summaryrefslogtreecommitdiff
path: root/taler-exchange-manual.rst
diff options
context:
space:
mode:
Diffstat (limited to 'taler-exchange-manual.rst')
-rw-r--r--taler-exchange-manual.rst751
1 files changed, 371 insertions, 380 deletions
diff --git a/taler-exchange-manual.rst b/taler-exchange-manual.rst
index 742b0c8e..f0c345c7 100644
--- a/taler-exchange-manual.rst
+++ b/taler-exchange-manual.rst
@@ -1,7 +1,7 @@
..
This file is part of GNU TALER.
- Copyright (C) 2014-2023 Taler Systems SA
+ Copyright (C) 2014-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -17,8 +17,13 @@
@author Christian Grothoff
@author Florian Dold
-GNU Taler Exchange Operator Manual
-##################################
+Exchange Operator Manual
+########################
+
+.. contents:: Table of Contents
+ :depth: 1
+ :local:
+
Introduction
============
@@ -35,6 +40,7 @@ About this manual
This manual targets system administrators who want to install and
operate a GNU Taler exchange.
+
Organizational prerequisites
----------------------------
@@ -822,369 +828,32 @@ configuration of the online machine:
Wire Gateway Setup
==================
-The Taler Wire Gateway is an API that connects the Taler exchange to
-the underlying core banking system.
-
-LibEuFin is an implementation of the Wire Gateway API for the EBICS protocol.
-This section will walk through (1) installing and configuring LibEuFin and
-(2) connecting the Taler Exchange to LibEuFin.
-
-
-Installation and Basic Configuration
-------------------------------------
-
-First, install the ``libeufin`` package. This can be done on the ``exchange-online``
-machine or a different one.
-
-.. code-block:: shell-session
-
- [root@exchange-online]# apt-get install -y libeufin
-
-The main component of LibEuFin is called the Nexus. It implements a Web
-service that provides a JSON abstraction layer to access bank accounts.
-
-The HTTP port and database connection string can be edited in the configuration:
-
-.. code-block:: ini
- :caption: /etc/libeufin/nexus.env
-
- LIBEUFIN_NEXUS_PORT=5017
- LIBEUFIN_NEXUS_DB_CONNECTION=jdbc:sqlite:/var/lib/libeufin/nexus/nexus-db.sqlite3
-
-After configuring the database, you can start the service.
-The database is initialized automatically.
-
-
-.. code-block:: shell-session
-
- [root@exchange-online]# systemctl enable libeufin-nexus
- [root@exchange-online]# systemctl start libeufin-nexus
-
-You can now create a superuser account. The command to
-create the superuser needs direct database access, thus
-the configuration file is sourced first, and the relevant
-environment variable is exported.
-
-.. code-block:: console
-
- [root@exchange-online]# source /etc/libeufin/nexus.env
- [root@exchange-online]# export LIBEUFIN_NEXUS_DB_CONNECTION
- [root@exchange-online]# NEXUS_ADMIN_PW=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)
- [root@exchange-online]# libeufin-nexus superuser admin --password $NEXUS_ADMIN_PW
-
-If you omit ``--password $NEXUS_ADMIN_PW``, you will interactively be asked for a password.
-For simplicity, a superuser can as well act as a normal user, but an API
-to create less privileged users is offered.
-
-.. note::
+The :ref:`Taler Wire Gateway <taler-wire-gateway-http-api>` is an API that
+connects the Taler exchange to the underlying core banking system. There are
+several implementations of wire gateways:
- User and permissions management in LibEuFin is still under development.
- In particular, permissions for non-superusers are very limited at the moment.
+ * `Project deploymerization <https://git.taler.net/depolymerization.git>`_ implements a wire gateway on top of Bitcoin or Ethereum
+ * The :ref:`libeufin-bank <libeufin-bank>` provides a wire gateway interface on top of a regional currency bank
+ * The **taler-fakebank-run** command is an in-memory bank simulator with a wire gateway interface for testing
+.. FIXME :ref:`libeufin-nexus <libeufin-nexus>` is an implementation of the Wire Gateway API for the EBICS protocol. Add to list above once nexus implements the TWG directly!
-Connecting Nexus with an EBICS account
---------------------------------------
-
-The command line interface of the LibEuFin Nexus needs the following three
-values to be defined in the environment: ``LIBEUFIN_NEXUS_URL``,
-``LIBEUFIN_NEXUS_USERNAME``, and ``LIBEUFIN_NEXUS_PASSWORD``. In this example,
-``LIBEUFIN_NEXUS_USERNAME`` should be set to ``admin``, and
-``LIBEUFIN_NEXUS_PASSWORD`` to the value hold in ``NEXUS_ADMIN_PW`` from the
-previous step (the ``libeufin-nexus superuser`` command). The
-``LIBEUFIN_NEXUS_URL`` could be given as ``http://localhost:5017/``.
-
-Next, we create a EBICS *bank connection* that Nexus can use to communicate with the bank.
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli \
- connections \
- new-ebics-connection \
- --ebics-url $EBICS_BASE_URL \
- --host-id $EBICS_HOST_ID \
- --partner-id $EBICS_PARTNER_ID \
- --ebics-user-id $EBICS_USER_ID \
- $CONNECTION_NAME
-
-If this step executes correctly, Nexus will have created all the cryptographic
-material that is needed on the client side; in this EBICS example, it created
-the signature and identification keys. It is therefore advisable to *make
-a backup copy* of such keys.
-
-.. code-block:: console
+Before continuing, you need to decide which wire gateway you want to use,
+and install and configure it on your system. Afterwards, you need to
+have two key pieces of information from that setup:
- [root@exchange-online]# libeufin-cli \
- connections \
- export-backup \
- --passphrase $SECRET \
- --output-file $BACKUP_FILE \
- $CONNECTION_NAME
+ * The username and password to access the exchange's account in the system.
+ * The ``payto://`` URI of that account (see `RFC 8905 <https://www.rfc-editor.org/rfc/rfc8905>`_).
-At this point, Nexus needs to both communicate its keys to the bank, and
-download the bank's keys. This synchronization happens through the INI, HIA, and
-finally, HPB message types.
-
-After the electronic synchronization, the subscriber must confirm their keys
-by sending a physical mail to the bank. The following command helps generating
-such letter:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli connections get-key-letter $CONNECTION_NAME out.pdf
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli \
- connections \
- connect \
- $CONNECTION_NAME
-
-..
- FIXME: Maybe is not 100% clear that 'connecting' means exchanging keys
- with the bank?
-
-Once the connection is synchronized, Nexus needs to import locally the data
-corresponding to the bank accounts offered by the bank connection just made.
-The command below downloads the list of the bank accounts offered by ``$CONNECTION_NAME``.
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli \
- connections \
- download-bank-accounts \
- $CONNECTION_NAME
-
-It is now possible to list the accounts offered by the connection.
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli \
- connections \
- list-offered-bank-accounts \
- $CONNECTION_NAME
-
-.. note::
-
- The ``nexusBankAccountId`` field should at this step be ``null``,
- as we have not yet imported the bank account and thus the account
- does not yet have a local name.
-
-Nexus now needs an explicit import of the accounts it should manage. This
-step is needed to let the user pick a custom name for such accounts.
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli \
- connections \
- import-bank-account \
- --offered-account-id testacct01 \
- --nexus-bank-account-id $LOCAL_ACCOUNT_NAME \
- $CONNECTION_NAME
-
-Once a Nexus user imported a bank account (``$LOCAL_ACCOUNT_NAME``)
-under a certain connection (``$CONNECTION_NAME``), it is possible
-to accomplish the usual operations for any bank account: asking for the
-list of transactions, and making a payment.
-
-Testing: Requesting the transaction history
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The LibEuFin Nexus keeps a local copy of the bank account's transaction
-history. Before querying transactions locally, it is necessary
-to request transactions for the bank account via the bank connection.
-
-This command asks Nexus to download the latest transaction reports/statements
-through the bank connection:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli accounts fetch-transactions $LOCAL_ACCOUNT_NAME
-
-.. note::
-
- By default, the latest available transactions are fetched. It is also
- possible to specify a custom date range (or even all available transactions)
- and the type of transactions to fetch (inter-day statements or intra-day
- reports).
-
-..
- FIXME: Possibly the date range filter is still missing, see #6243.
-
-Once Nexus has stored all the information in the database, the
-client can ask to actually see the transactions:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli accounts transactions $LOCAL_ACCOUNT_NAME
-
-Testing: Making payments
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-Payments pass through two phases: preparation and submission. The preparation
-phase assigns the payment initiation a unique ID, which prevents accidental
-double submissions of payments in case of network failures or other
-disruptions.
-
-
-The following command prepares a payment:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli accounts prepare-payment \
- --creditor-iban=$IBAN_TO_SEND_MONEY_TO \
- --creditor-bic=$BIC_TO_SEND_MONEY_TO \
- --creditor-name=$CREDITOR_NAME \
- --payment-amount=$AMOUNT \
- --payment-subject=$SUBJECT \
- $LOCAL_ACCOUNT_NAME
-
-Note: the ``$AMOUNT`` value needs the format ``X.Y:CURRENCY``; for example
-``EUR:10``, or ``EUR:1.01``.
-
-The previous command should return a value (``$UUID``) that uniquely
-identifies the prepared payment in the Nexus system. That is needed
-in the next step, to **send the payment instructions to the bank**:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli accounts submit-payments \
- --payment-uuid $UUID \
- $LOCAL_ACCOUNT_NAME
-
-Automatic scheduling
-^^^^^^^^^^^^^^^^^^^^
-
-With an EBICS bank connection, the LibEuFin Nexus needs to regularly query for
-new transactions and (re-)submit prepared payments.
-
-It is possible to schedule these tasks via an external task scheduler such as
-cron(8). However, the nexus also has an internal task scheduling mechanism for
-accounts.
-
-
-The following three commands create a schedule for submitting payments hourly,
-fetching transactions (intra-day reports) every 5 minutes, and (inter-day statements)
-once at 11pm every day:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \
- --task-type="submit" \
- --task-name='submit-payments-hourly' \
- --task-cronspec='0 0 *'
-
- [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \
- --task-type="fetch" \
- --task-name='fetch-5min' \
- --task-cronspec='0 */5 *' \
- --task-param-level=report \
- --task-param-range-type=latest
-
- [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \
- --task-type="fetch" \
- --task-name='fetch-daily' \
- --task-cronspec='0 0 23' \
- --task-param-level=statement \
- --task-param-range-type=latest
-
-The cronspec has the following format, which is slightly non-standard due to
-the ``SECONDS`` field
-
-.. code-block:: none
-
- SECONDS MINUTES HOURS DAY-OF-MONTH[optional] MONTH[optional] DAY-OF-WEEK[optional]
-
-
-Creating a Taler facade
-^^^^^^^^^^^^^^^^^^^^^^^
-
-Facades are additional abstraction layers that can serve
-specific purposes. For example, one application might need
-a filtered version of the transaction history, or it might
-want to refuse payments that do not conform to certain rules.
-
-At this moment, only the *Taler facade type* is implemented
-in the Nexus, and the command below instantiates one under a
-existing bank account / connection pair. You can freely
-assign an identifier for the ``$FACADE_NAME`` below:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli facades new-taler-wire-gateway-facade \
- --currency EUR \
- --facade-name $FACADE_NAME \
- $CONNECTION_NAME \
- $LOCAL_ACCOUNT_NAME
-
-At this point, the additional :doc:`taler-wire-gateway API <core/api-bank-wire>`
-becomes offered by the Nexus. The purpose is to let a Taler exchange rely on
-Nexus to manage its bank account.
-
-The base URL of the facade that can be used by the Taler exchange
-as the Taler Wire Gateway base URL can be seen by listing the facades:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli facades list
-
-Managing Permissions and Users
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This guide has so far assumed that a superuser is accessing the LibEuFin Nexus.
-However, it is advisable that the Nexus is accessed with users that only have a
-minimal set of permissions.
-
-The Nexus currently only has support for giving non-superusers access to Taler
-wire gateway facades.
-
-To create a new user, use the ``users`` subcommand of the CLI:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli users list
- # [ ... shows available users ... ]
-
- [root@exchange-online]# libeufin-cli users create $USERNAME
- # [ ... will prompt for password ... ]
-
-Permissions are managed with the ``permissions`` subcommand.
-The following commands grant permissions to view the transaction history
-and create payment initiations with a Taler wire gateway facade:
-
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli permissions grant \
- user $USERNAME \
- facade $FACADENAME \
- facade.talerwiregateway.history
-
- [root@exchange-online]# libeufin-cli permissions grant \
- user $USERNAME \
- facade $FACADENAME \
- facade.talerwiregateway.transfer
-
-..
- FIXME: The two commands above output an empty JSON object
- when successful. Possibly, we should suppress that (just like
- the other commands do).
-
-The list of all granted permissions can be reviewed:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli permissions list
-
-
-.. _Bank-account:
+.. _exchange-bank-account-configuration:
Exchange Bank Account Configuration
-----------------------------------
An exchange must be configured with the right settings to access its bank
-account via a Taler Wire Gateway. An exchange can be configured to use
-multiple bank accounts by using multiple Wire Gateways. Typically only one
-Wire Gateway is used.
+account via a :ref:`Taler wire gateway <taler-wire-gateway-http-api>`. An
+exchange can be configured to use multiple bank accounts by using multiple
+wire gateways. Typically only one wire gateway is used.
To configure a bank account in Taler, we need to furnish two pieces of
information:
@@ -1195,8 +864,8 @@ information:
an IBAN or
``payto://x-taler-bank/localhost:8080/2`` for the 2nd bank account a
the Taler bank demonstrator running at ``localhost`` on port 8080.
- The first part of the URI following ``payto://`` (“iban” or
- “x-taler-bank”) is called the wire method.
+ The first part of the URI following ``payto://`` (``iban`` or
+ ``x-taler-bank``) is called the wire method.
- The ``taler-exchange-wirewatch`` and ``taler-exchange-transfer``
tools needs to be provided resources for authentication
@@ -1205,20 +874,22 @@ information:
for HTTP basic authentication.
-A Taler Wire Gateway is configured in a configuration section that follows the
-pattern ``exchange-account-$id``, where ``$id`` is an internal identifier for
-the bank account accessed by the exchange. The basic information for an
+Each Taler wire gateway is configured in a configuration section that follows
+the pattern ``exchange-account-$id``, where ``$id`` is an internal identifier
+for the bank account accessed by the exchange. The basic information for an
account should be put in ``/etc/taler/conf.d/exchange-business.conf``. The
secret credentials to access the Taler Wire Gateway API should be put into a
corresponding ``exchange-accountcredentials-$id`` section in
``/etc/taler/secrets/exchange-accountcredentials.conf``. The latter file
-should already be only readable for the ``taler-exchange-wire`` user. Other
-exchange processes should not have access to this information.
+should be only readable for the ``taler-exchange-wire`` user. Only the
+``taler-exchange-wirewatch`` and ``taler-exchange-transfer`` services should
+run as the ``taler-exchange-wire`` user. Other exchange processes do not need
+to have access to the account credentials.
You can configure multiple accounts for an exchange by creating sections
-starting with “exchange-account-” for the section name. You can ENABLE for
-each account whether it should be used, and for what (incoming or outgoing
-wire transfers):
+starting with ``exchange-account-`` for the section name. You must specify
+``ENABLE_``-settings for each account whether it should be used, and for what
+(incoming or outgoing wire transfers):
.. code-block:: ini
:caption: /etc/taler/conf.d/exchange-business.conf
@@ -1253,15 +924,15 @@ wire transfers):
# LibEuFin expects basic auth.
WIRE_GATEWAY_AUTH_METHOD = basic
- # Username and password set in LibEuFin.
+ # Username and password to access the Taler wire gateway.
USERNAME = ...
PASSWORD = ...
- # Base URL of the wire gateway set up with LibEuFin.
+ # Base URL of the Taler wire gateway.
WIRE_GATEWAY_URL = ...
-Such a Wire Gateway configuration can be tested with the following commands:
+Such a wire gateway configuration can be tested with the following commands:
.. code-block:: shell-session
@@ -1270,7 +941,8 @@ Such a Wire Gateway configuration can be tested with the following commands:
[root@exchange-online]# taler-exchange-wire-gateway-client \
--section exchange-accountcredentials-1 --credit-history
-
+On success, you will see some of your account's transaction history (or an
+empty history), while on failure you should see an error message.
.. _LegalSetup:
@@ -1301,12 +973,12 @@ Taler permits an exchange to require KYC data under the following circumstances:
* Wallet receives (via refunds) money resulting in a balance over a threshold
* Wallet receives money via P2P payments over a threshold
* Merchant receives money over a threshold
- * Reserve is "opened" for invoicing or rewards (**planned feature**)
+ * Reserve is "opened" for invoicing (**planned feature**)
Any of the above requests can trigger the KYC process,
which can be illustrated as follows:
-.. image:: kyc-process.png
+.. image:: images/kyc-process.png
At the end of the KYC process, the wallet re-tries the
original request, and assuming KYC was successful, the
@@ -1716,7 +1388,7 @@ started using a simple command:
At this point, the exchange service is not yet fully operational.
-To check whether the exchange is running correctly under the advertized
+To check whether the exchange is running correctly under the advertised
base URL, run:
.. code-block:: shell-session
@@ -1811,6 +1483,8 @@ periodically, as it signs the various online signing keys of the exchange
which periodically expire.
+.. _exchange-account-signing:
+
Account signing
---------------
@@ -1819,7 +1493,7 @@ The ``enable-account`` step is important to must be used to sign the
correct address to wire funds to. Note that for each bank account, additional
options **must** be set in the configuration file to tell the exchange how to
access the bank account. The offline tool *only* configures the externally
-visible portions of the setup. The chapter on `Bank account <_Bank-account>`_ configuration has further details.
+visible portions of the setup. The chapter on `bank account configuration <_exchange-bank-account-configuration>`_ has further details.
taler-exchange-offline accepts additional options to configure the use of the
account. For example, additional options can be used to add currency
@@ -2005,7 +1679,7 @@ makes the decision given the KYC attributes:
The given program will be given the KYC attributes in JSON format on standard
input, and must return 0 to continue without AML and non-zero to flag the
-account for manual review. To disable this triger, simply leave the option to
+account for manual review. To disable this trigger, simply leave the option to
its default value of '[/usr/bin/]true'. To flag all new users for manual
review, simply set the program to '[/usr/bin/]false'.
@@ -2013,7 +1687,7 @@ AML Forms
---------
AML forms are defined by the DD 54 dynamic forms.
-The shipped implementation with of the exchange is installed in
+The shipped implementation with of the exchange is installed in
.. code-block:: shell-session
@@ -2026,11 +1700,11 @@ every entry in the list the next properties are expected to be present:
``label``: used in the UI as the name of the form
``id``: identification name, this will be saved in the exchange database
-along with the values to correctly render the form again.
+along with the values to correctly render the form again.
It should simple, short and without any character outside numbers,
letters and underscore.
-``version``: when editing a form, instead of just replacing fields
+``version``: when editing a form, instead of just replacing fields
it will be better to create a new form with the same id and new version.
That way old forms in the database will used old definition of the form.
It should be a number.
@@ -2040,12 +1714,12 @@ See DD 54 dynamic forms.
.. attention::
- do not remove a form the list if it has been used. Otherwise you
+ do not remove a form the list if it has been used. Otherwise you
won't be able to see the information save in the exchange database.
To add a new one you can simply copy and paste one element, and edit it.
-It is much easier to download ``@gnu-taler/aml-backoffice-ui`` source
+It is much easier to download ``@gnu-taler/aml-backoffice-ui`` source
from ``https://git.taler.net/wallet-core.git/``, compile and copy the file
from the ``dist/prod``.
@@ -2268,6 +1942,323 @@ grant the permissions to the other exchange processes again.
+.. _ExchangeTemplateCustomization:
+
+Template Customization
+======================
+
+The Exchange comes with various HTML templates that are shown to
+guide users through the KYC process. The Exchange uses `Mustach
+<https://gitlab.com/jbol/mustach>`__ as the templating engine. This section
+describes the various templates. In general, the templates must be installed
+to the ``share/taler/exchange/templates/`` directory. The file names must be of
+the form ``$NAME.$LANG.must`` where ``$NAME`` is the name of the template and
+``$LANG`` is the 2-letter language code of the template. English templates
+must exist and will be used as a fallback. If the browser (user-agent) has
+provided language preferences in the HTTP header and the respective language
+exists, the correct language will be automatically served.
+
+The following subsections give details about each of the templates. Most
+subsection titles are the ``$NAME`` of the respective template.
+
+
+Generic Errors Templates
+------------------------
+
+A number of templates are used for generic errors. These are:
+
+ * kyc-proof-already-done (KYC process already completed)
+ * kyc-bad-request (400 Bad Request)
+ * kyc-proof-endpoint-unknown (404 Not Found for KYC logic)
+ * kyc-proof-internal-error (500 Internal Server Error)
+ * kyc-proof-target-unknown (404 Not Found for KYC operation)
+
+All of these templates are instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * message: String; optional, extended human-readable text provided to elaborate
+ on the error, should be shown to provide additional context
+
+
+kycaid-invalid-request
+----------------------
+
+The KYCaid plugin does not support requests to the
+``/kyc-proof/`` endpoint (HTTP 400 bad request).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * error: String; error code from the server
+
+ * error_details: String; optional error description from the server
+
+ * error_uri: optional URI with further details about the error from the server
+
+
+
+oauth2-authentication-failure
+-----------------------------
+
+The OAuth2 server said that the request was not
+properly authenticated (HTTP 403 Forbidden).
+
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+
+oauth2-authorization-failure
+----------------------------
+
+The OAuth2 server refused to return the KYC data
+because the authorization code provided was
+invalid (HTTP 403 Forbidden).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * error: String; error code from the server
+
+ * error_message: String; error message from the server
+
+
+oauth2-authorization-failure-malformed
+--------------------------------------
+
+The server refused the authorization, but then provided
+a malformed response (HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * debug: Bool; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
+
+ * server_response: Object; could be NULL; this includes the (malformed) OAuth2 server response, it should be shown to the use if "debug" is true
+
+
+oauth2-bad-request
+------------------
+
+The client made an invalid request (HTTP 400 Bad Request).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * message: String; additional error message elaborating on what was bad about the request
+
+
+oauth2-conversion-failure
+-------------------------
+
+Converting the KYC data into the exchange's internal
+format failed (HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * debug: Bool; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
+
+ * converter: String; name of the conversion command that failed which was used by the Exchange
+
+ * attributes: Object; attributes returned by the conversion command, often NULL (after all, conversion failed)
+
+ * message: error message elaborating on the conversion failure
+
+
+oauth2-provider-failure
+-----------------------
+
+We did not get an acceptable response from the OAuth2
+provider (HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * message: String; could be NULL; text elaborating on the details of the failure
+
+
+persona-exchange-unauthorized
+-----------------------------
+
+The Persona server refused our request (HTTP 403 Forbidden from Persona, returned as a HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
+persona-load-failure
+--------------------
+
+The Persona server refused our request (HTTP 429 Too Many Requests from Persona, returned as a HTTP 503 Service Unavailable).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
+persona-exchange-unpaid
+-----------------------
+
+The Persona server refused our request (HTTP 402 Payment REquired from Persona, returned as a HTTP 503 Service Unavailable).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
+
+persona-logic-failure
+---------------------
+
+The Persona server refused our request (HTTP 400, 403, 409, 422 from Persona, returned as a HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
+persona-invalid-response
+------------------------
+
+The Persona server refused our request in an
+unexpected way; returned as a HTTP 502 Bad Gateway.
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * debug: Bool; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
+
+ * server_response: Object; could be NULL; this includes the (malformed) OAuth2 server response, it should be shown to the use if "debug" is true
+
+
+persona-network-timeout
+-----------------------
+
+The Persona server refused our request (HTTP 408 from Persona, returned as a HTTP 504 Gateway Timeout).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
+persona-kyc-failed
+------------------
+
+The Persona server indicated a problem with the KYC process, saying it was not completed.
+
+This template is instantiated using the following information:
+
+ * persona_inquiry_id: String; internal ID of the inquiry within Persona, useful for further diagnostics by staff
+
+ * data: Object; could be NULL; this includes the server response, it contains extensive diagnostics, see Persona documentation on their ``/api/v1/inquiries/$ID``.
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+persona-provider-failure
+------------------------
+
+The Persona server refused our request (HTTP 500 from Persona, returned as a HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
.. _ExchangeBenchmarking:
Benchmarking