taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

taler-kyc-manual.rst (53426B)


      1 ..
      2   This file is part of GNU TALER.
      3 
      4   Copyright (C) 2014-2025 Taler Systems SA
      5 
      6   TALER is free software; you can redistribute it and/or modify it under the
      7   terms of the GNU Affero General Public License as published by the Free Software
      8   Foundation; either version 2.1, or (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     11   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     12   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
     13 
     14   You should have received a copy of the GNU Affero General Public License along with
     15   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     16 
     17   @author Christian Grothoff
     18   @author Florian Dold
     19 
     20 .. _KycOperatorManual:
     21 
     22 Exchange KYC/AML Operator Manual
     23 ################################
     24 
     25 .. contents:: Table of Contents
     26   :depth: 1
     27   :local:
     28 
     29 
     30 Introduction
     31 ============
     32 
     33 About GNU Taler
     34 ---------------
     35 
     36 .. include:: frags/about-taler.rst
     37 
     38 
     39 About this manual
     40 -----------------
     41 
     42 This chapter describes how to setup certain compliance aspects of a GNU Taler
     43 exchange. Users that just want to set up an exchange as an experiment without
     44 legal or regulatory requirements can safely skip this chapter.
     45 
     46 This manual targets compliance experts working with system administrators and
     47 developers to configure legitimization (KYC/KYB) and anti-money laundering
     48 (AML) processes for a GNU Taler exchange.  Expertise in all three domains is
     49 required, as Taler's KYC and AML processes are highly configurable and
     50 programmable.
     51 
     52 
     53 
     54 Legal conditions for using the service
     55 --------------------------------------
     56 
     57 .. include:: frags/legal.rst
     58 
     59 
     60 Know-Your-Customer Setup
     61 ========================
     62 
     63 To legally operate, Taler exchange operators may have to comply with KYC
     64 regulation that requires financial institutions to identify parties involved
     65 in transactions at certain points.
     66 
     67 Taler permits an exchange to require know-your-customer (KYC) or
     68 know-your-business (KYB) data under the following circumstances:
     69 
     70   * Customer withdraws money over a threshold
     71   * Wallet receives (via refunds) money resulting in a balance over a threshold
     72   * Wallet receives money via P2P payments over a threshold
     73   * Merchant receives money over a threshold
     74   * Merchant deposits digital cash over a threshold (**planned feature, bug 9040**)
     75   * Reserve is "opened" for invoicing (**planned feature**)
     76 
     77 Any of the above requests can trigger the KYC process,
     78 which can be illustrated as follows:
     79 
     80 .. image:: images/kyc-process.png
     81 
     82 At the end of the KYC process, the wallet re-tries the
     83 original request, and assuming KYC was successful, the
     84 request should then succeed.
     85 
     86 
     87 KYC Terminology
     88 ---------------
     89 
     90 * **Attributes**: Attributes are used to represent KYC data obtained about
     91   an account holder. Attributes include passport images, address data,
     92   business registration documents, and indeed arbitrary forms filed by
     93   AML staff or the customer themselves.  Attribute data is considered
     94   sensitive private information and is thus stored encrypted within the
     95   exchange database.
     96 
     97 * **Check**: A check establishes a particular attribute of a user, such as
     98   their name based on an ID document and lifeness, mailing address, phone
     99   number, taxpayer identity, etc.  Checks may be given *context* (such as
    100   whether a customer is an individual or a business) to run correctly. Checks
    101   can also be AML staff inserting information for plausibilization.  Checks
    102   result in *attributes* about the account's owner which are given to an
    103   external AML *program* together with the *context* to determine an *outcome*.
    104   KYC checks are always specified with a fallback *measure* to be taken if
    105   the check fails.
    106 
    107 * **Condition**: A condition specifies when KYC is required. Conditions
    108   include the *type of operation*, a threshold amount (e.g. above EUR:1000)
    109   and possibly a time period (e.g. over the last month).
    110 
    111 * **Configuration**: The configuration determines the *legitimization rules*,
    112   and specifies which providers offer which *checks*.
    113 
    114 * **Context**: Context is information provided as input into a *check* and
    115   *program* to customize their execution. The context is initially set by the
    116   *measure* (possibly including data from the *trigger*).  Naturally, the
    117   *program* may use its `AmlProgramInput` which includes *context* and
    118   *attribute* data to compute an update *context* for the next set of
    119   *measures* that it specifies in the `LegitimizationRuleSet` as part
    120   of the `AmlOutcome`.  Thus, *context* is something that typically
    121   evolves as the *account* undergoes *measures*.  Context is lost if
    122   an account transitions to default *legitimization rules* due to
    123   *expiration*.
    124 
    125 * **Decision**: AML decisions are these as taken by AML officers (humans). AML
    126   outcomes are the results of AML programs (code). Legitimization outcomes (DB
    127   table) can arise from either.
    128 
    129 * **Display priority**: Every rule has a *display priority*. If a second
    130   *rule* is *triggered* before the *outcome* of a *rule* could be determined,
    131   the *rule* with the larger *display priority* becomes the requirement that
    132   the account owner has to satisfy (and that thus will be displayed by the
    133   KYC SPA).
    134 
    135 * **Expiration**: Except for the default rules, any set of KYC rules is
    136   subject to *expiration*. This can be because *attributes* become outdated or
    137   because sanctions have a time limit. The expiration time thus determines
    138   when a new *measure* is triggered in the absence of a transaction crossing
    139   thresholds in the current set of *legtimization rules*.
    140 
    141 * **Legitimization rules**: The *legitimization rules* determine under which
    142   *conditions* which *measures* will be taken. A `LegitimizationRuleSet`
    143   always also includes an *expiration* time period for (custom, non-default)
    144   *legitimization rules* after which a fallback measure* will automatically
    145   apply.  Legitimization rules may be *exposed* to the client (for example,
    146   to allow a wallet to stay below hard withdraw thresholds) or could be secret.
    147 
    148 * **Logic**: Logic refers to a specific bit of code (realized as an exchange
    149   plugin) that enables the interaction with a specific *provider*.  Logic
    150   typically requires *configuration* for access control (such as an
    151   authorization token) and possibly the endpoint of the specific *provider*
    152   implementing the respective API.
    153 
    154 * **Measure**: Describes the possible outgoing edges from one state in the
    155   state machine (including how to show the current state). Each edge is given
    156   some *context* and a *check* to be performed as well as an AML *program*
    157   which determines the *outcome*.  We generally distinguish between
    158   "original" measures (defined globally in the exchange configuration) and
    159   "custom" measures (defined specifically for an account by AML staff).
    160   Additionally, only *origional* measures that have a *check* of type
    161   "SKIP" and that require no inputs can be used as *FALLBACK* measures.
    162 
    163 * **Outcome**: An `AmlOutcome` describes the account state that an account
    164   ends up in due to either an AML staff action or an AML *program* doing some
    165   computation over the attributes resulting from a *check*.  Outcomes can be
    166   that certain types of transactions are "verboten", that the account is (or
    167   remains) under investigation by AML staff, that the account is given certain
    168   properties, and/or that certain events are to be logged. Outcomes also
    169   include a new set of *legitimization rules* to apply (and an *expiration*
    170   time at which point a successor *measure* will be automatically taken).
    171 
    172 * **Provider**: A provider performs a specific set of *checks* at a certain
    173   *cost*. Interaction with a provider is performed by provider-specific
    174   *logic*.
    175 
    176 * **Program**: An AML helper *program* is given *context* about the current
    177   state of an account and the attribute data from a *check* to compute the
    178   *outcome*.  For example, a *program* may look at the "PEP" field of a KYC
    179   check and decide if the outcome is to put the account into ``normal`` or
    180   ``held-for-manual-review`` state.  AML programs are always specified
    181   with a fallback *measure* to be taken if the program fails.
    182 
    183 * **Trigger**: A specific transaction that satisfies a **Condition**.
    184 
    185 * **Type of operation**: The operation type determines which Taler-specific
    186   operation has triggered the KYC requirement. We support four types of
    187   operation: withdraw (by customer), deposit (by merchant),
    188   aggregate transfer (to merchant), P2P receive (by wallet) and
    189   (high) wallet balance.
    190 
    191 
    192 Configuration of possible KYC/AML providers
    193 -------------------------------------------
    194 
    195 The KYC configuration determines the *legitimization rules*, and specifies
    196 which providers offer which *checks*.
    197 
    198 The configuration specifies a set of providers, one per configuration
    199 section. The names of the configuration sections must being with
    200 ``kyc-proider-`` followed by an arbitrary ``$PROVIDER_ID``:
    201 
    202 .. code-block:: ini
    203   :caption: /etc/taler-exchange/conf.d/exchange-kyc-providers.conf
    204 
    205   [kyc-provider-$PROVIDER_ID]
    206 
    207   # Which plugin is responsible for this provider?
    208   # Choices include "oauth2", "kycaid" and "persona".
    209   LOGIC = oauth2
    210 
    211   # Plus additional logic-specific options, e.g.:
    212   AUTHORIZATION_TOKEN = superdupersecret
    213 
    214   # Other logic-specific internal options (example):
    215   FORM_ID = business_legi_form
    216 
    217 
    218 OAuth 2.0 specifics
    219 ^^^^^^^^^^^^^^^^^^^
    220 
    221 In terms of configuration, the OAuth 2.0 logic requires the respective client
    222 credentials to be configured apriori to enable access to the legitimization
    223 service.  The OAuth 2.0 configuration options are:
    224 
    225 .. code-block:: ini
    226   :caption: /etc/taler-exchange/conf.d/exchange-oauth2.conf
    227 
    228   [kyc-provider-example-oauth2]
    229   LOGIC = oauth2
    230   # (generic options omitted)
    231   # How long is the KYC check valid?
    232   KYC_OAUTH2_VALIDITY = forever
    233 
    234   # URL to which we redirect the user for the login process
    235   KYC_OAUTH2_AUTHORIZE_URL = "http://kyc.example.com/authorize"
    236   # URL where we POST the user's authentication information
    237   KYC_OAUTH2_TOKEN_URL = "http://kyc.example.com/token"
    238   # URL of the user info access point.
    239   KYC_OAUTH2_INFO_URL = "http://kyc.example.com/info"
    240 
    241   # Where does the client get redirected upon completion?
    242   KYC_OAUTH2_POST_URL = "http://example.com/thank-you"
    243 
    244   # For authentication to the OAuth2.0 service
    245   KYC_OAUTH2_CLIENT_ID = testcase
    246   KYC_OAUTH2_CLIENT_SECRET = password
    247 
    248   # Mustach template that converts OAuth2.0 data about the user
    249   # into GNU Taler standardized attribute data.
    250   KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-challenger.sh
    251 
    252 The converter helper is expected to be customized to the selected OAuth2.0
    253 service: different services may return different details about the user or
    254 business, hence there cannot be a universal converter for all purposes. The
    255 default shell script uses the ``jq`` tool to convert the JSON returned by the
    256 service into the KYC attributes (also in JSON) expected by the exchange.  The
    257 script will need to be adjusted based on the attributes collected by the
    258 specific backend.
    259 
    260 The Challenger service for address validation supports OAuth2.0, but does not
    261 have a static AUTHORIZE_URL. Instead, the AUTHORIZE_URL must be enabled by the client
    262 using a special authenticated request to the Challenger's ``/setup`` endpoint.
    263 The exchange supports this by appending ``#setup`` to the AUTHORIZE_URL (note
    264 that fragments are illegal in OAuth2.0 URLs).  Be careful to quote the URL,
    265 as ``#`` is otherwise interpreted as the beginning of a comment by the
    266 configuration file syntax.
    267 
    268 .. code-block:: ini
    269   :caption: /etc/taler-exchange/conf.d/exchange-challenger-oauth2.conf
    270 
    271   [kyc-provider-challenger-oauth2]
    272   LOGIC = oauth2
    273   KYC_OAUTH2_AUTHORIZE_URL = "http://challenger.example.com/authorize/#setup"
    274   KYC_OAUTH2_TOKEN_URL = "http://challenger.example.com/token"
    275   KYC_OAUTH2_INFO_URL = "http://challenger.example.com/info"
    276 
    277 When using OAuth 2.0, the *CLIENT REDIRECT URI* must be set to the
    278 ``/kyc-proof/$PROVIDER_SECTION`` endpoint. For example, given the
    279 configuration above and an exchange running on the host
    280 ``exchange.example.com``, the redirect URI would be
    281 ``https://exchange.example.com/kyc-proof/kyc-provider-challenger-oauth2/``.
    282 
    283 Using the OAuth 2.0 logic with the ``/setup`` endpoint it is possible to
    284 pass Challenger the address to validate via the **context** of the KYC check.
    285 To do so, the *address type* specific address data must be provided in a
    286 field ``initial_address`` of the **context** object.
    287 
    288 
    289 Persona specifics
    290 ^^^^^^^^^^^^^^^^^
    291 
    292 We use the hosted flow. The Persona endpoints return a ``request-id``, which
    293 we log for diagnosis.
    294 
    295 Persona should be configured to use the ``/kyc-webhook/`` endpoint of the
    296 exchange to notify the exchange about the completion of KYC processes.  The
    297 webhook is authenticated using a shared secret, which should be in the
    298 configuration.  To use the Persona webhook, you must set the webhook URL in
    299 the Persona service to ``$EXCHANGE_BASE_URL/kyc-webhook/$SECTION_NAME/`` where
    300 ``$SECTION_NAME`` is the name of the configuration section.  You should also
    301 extract the authentication token for the webhook and put it into the
    302 configuration as shown above.
    303 
    304 
    305 .. code-block:: ini
    306   :caption: /etc/taler-exchange/conf.d/exchange-persona.conf
    307 
    308   [kyclogic-persona]
    309   # Webhook authorization token. Global for all uses
    310   # of the persona provider!
    311   WEBHOOK_AUTH_TOKEN = wbhsec_698b5a19-c790-47f6-b396-deb572ec82f9
    312 
    313   [kyc-provider-example-persona]
    314   LOGIC = persona
    315   # (generic options omitted)
    316 
    317   # How long is the KYC check valid?
    318   KYC_PERSONA_VALIDITY = 365d
    319 
    320   # Which subdomain is used for our API?
    321   KYC_PERSONA_SUBDOMAIN = taler
    322 
    323   # Authentication token to use.
    324   KYC_PERSONA_AUTH_TOKEN = persona_sandbox_42XXXX
    325 
    326   # Form to use.
    327   KYC_PERSONA_TEMPLATE_ID = itempl_Uj6Xxxxx
    328 
    329   # Where do we redirect to after KYC finished successfully.
    330   KYC_PERSONA_POST_URL = "https://taler.net/kyc-done"
    331 
    332   # Salt to give to requests for idempotency.
    333   # Optional.
    334   # KYC_PERSONA_SALT = salt
    335 
    336   # Helper to convert JSON with KYC data returned by Persona into GNU Taler
    337   # internal format. Should probably always be set to some variant of
    338   # "taler-exchange-kyc-persona-converter.sh".
    339   KYC_PERSONA_CONVERTER_HELPER = "taler-exchange-kyc-persona-converter.sh"
    340 
    341 The converter helper is expected to be customized to the
    342 selected template: different templates may return different details
    343 about the user or business, hence there cannot be a universal converter
    344 for all purposes. The default shell script uses the ``jq`` tool to
    345 convert the JSON returned by Persona into the KYC attributes (also
    346 in JSON) expected by the exchange.  The script will need to be adjusted
    347 based on the attributes collected by the specific template.
    348 
    349 
    350 KYC AID specifics
    351 ^^^^^^^^^^^^^^^^^
    352 
    353 We use the hosted flow.
    354 
    355 KYCAID must be configured to use the ``/kyc-webhook/$SECTION_NAME/`` endpoint
    356 of the exchange to notify the exchange about the completion of KYC processes.
    357 
    358 .. code-block:: ini
    359   :caption: /etc/taler-exchange/conf.d/exchange-kycaid.conf
    360 
    361   [kyc-provider-example-kycaid]
    362   LOGIC = kycaid
    363   # (generic options omitted)
    364 
    365   # How long is the KYC check valid?
    366   KYC_KYCAID_VALIDITY = 365d
    367 
    368   # Authentication token to use.
    369   KYC_KYCAID_AUTH_TOKEN = XXX
    370 
    371   # Form to use.
    372   KYC_KYCAID_FORM_ID = XXX
    373 
    374   # URL to go to after the process is complete.
    375   KYC_KYCAID_POST_URL = "https://taler.net/kyc-done"
    376 
    377   # Script to convert the KYCAID data into the Taler format.
    378   KYC_KYCAID_CONVERTER_HELPER = taler-exchange-kyc-kycaid-converter.sh
    379 
    380 
    381 The converter helper is expected to be customized to the selected template:
    382 different templates may return different details about the user or business,
    383 hence there cannot be a universal converter for all purposes. The default
    384 shell script uses the ``jq`` tool to convert the JSON returned by Persona into
    385 the KYC attributes (also in JSON) expected by the exchange.  The script will
    386 need to be adjusted based on the attributes collected by the specific
    387 template.
    388 
    389 
    390 Configuration of possible KYC/AML checks
    391 ----------------------------------------
    392 
    393 The configuration specifies a set of possible KYC checks offered by external
    394 providers, one per configuration section.  The names of the configuration
    395 sections must being with ``kyc-check-`` followed by an arbitrary
    396 ``$CHECK_NAME``.
    397 
    398 .. code-block:: ini
    399 
    400   [kyc-check-$CHECK_NAME]
    401 
    402   # Which type of check is this? Also determines
    403   # the SPA form to show to the user for this check.
    404   #
    405   # INFO: wait for staff or contact staff out-of band
    406   #          (only information shown, no SPA action)
    407   # FORM: SPA should show an inline (HTML) form
    408   # LINK: SPA may start external KYC process or upload
    409   #
    410   TYPE = INFO|LINK|FORM
    411 
    412   # Optional. Set to YES to allow this check be
    413   # done voluntarily by a client (they may then
    414   # still have to pay for it). Used to offer the
    415   # SPA to display checks even if they are
    416   # not required. Default is NO.
    417   # Since **vATTEST**.
    418   VOLUNTARY = YES/NO
    419 
    420   # Provider id, present only if type is LINK.
    421   # Refers to a ``kyc-provider-$PROVIDER_ID`` section.
    422   PROVIDER_ID = id
    423 
    424   # Name of the SPA form, if type is FORM
    425   # "INFO" and "LINK" are reserved and must not be used.
    426   # The exchange server and the SPA must agree on a list
    427   # of supported forms and the resulting attributes.
    428   #
    429   # The SPA should include a JSON resource file
    430   # "forms.json" mapping form names to arrays of
    431   # attribute names each form provides.
    432   FORM_NAME = name
    433 
    434   # Descriptions to use in the SPA to display the check.
    435   DESCRIPTION = "Upload your passport picture"
    436   DESCRIPTION_I18N = "{"en":"Upload scan of your passport"}"
    437 
    438   # ';'-separated list of fields that the CONTEXT must
    439   # provide as inputs to this check. For example,
    440   # for a FORM of type CHOICE, this might state
    441   # ``choices: string[];``. The type after the ":"
    442   # is for now purely for documentation and is
    443   # not checked. However, it may be shown to AML staff
    444   # when they configure measures.
    445   REQUIRES = requirement;
    446 
    447   # Description of the outputs provided by the check.
    448   # Basically, the check's output is expected to
    449   # provide the following fields as attribute inputs into
    450   # a subsequent AML program.
    451   # INFO never has any outputs.
    452   OUTPUTS = "business_name street city country registration"
    453 
    454   # **original** measure to take if the check fails
    455   # (for any reason, e.g. provider or form fail to
    456   # satisfy constraints or provider signals user error)
    457   # Usually should point to a measure that requests
    458   # AML staff to investigate.  The fallback measure
    459   # context always includes the reasons for the
    460   # failure.  Fallback measures MUST be *origional*
    461   # measures and MUST use a check of
    462   # type "SKIP" and MUST NOT require any inputs.
    463   FALLBACK = MEASURE_NAME
    464 
    465 The list of possible FORM names is fixed in the SPA
    466 for a particular exchange release.
    467 
    468 The "check_name" value "skip" is reserved and must not be defined. It can be
    469 used in measures where the AML program must be run immediately without any
    470 input.
    471 
    472 The outcome of *any* check is stored encrypted in the ``kyc_attributes``
    473 table.  It MUST include an ``expiration_time``.
    474 
    475 The INFO Type
    476 ^^^^^^^^^^^^^
    477 
    478 When using KYC checks of type "INFO", the KYC-SPA
    479 will simply show the given DESCRIPTION (or translations
    480 from DESCRIPTION_I18N) to the user.
    481 
    482 
    483 The FORM Type
    484 ^^^^^^^^^^^^^
    485 
    486 When using KYC checks of type "FORM", the KYC-SPA
    487 will show different forms based on "FORM_NAME" while
    488 also showing the user the text from DESCRIPTION
    489 as instructions.
    490 
    491 Some of the forms may be further parameterized via
    492 the context in which the form is executed.
    493 
    494 .. note::
    495 
    496   For build-in forms, it should in the future not be
    497   necessary to specify the context requirements via
    498   REQUIRES as the KYC SPA should inform the exchange
    499   about the requirements of each form automatically.
    500   However, this is not yet implemented, see #9187.
    501 
    502 When forms are submitted, the exchange converts the form data into key-value
    503 pairs where the key is the form field name and the value depends on
    504 the key.  The different keys are defined in the
    505 ``gnu-taler-form-attributes`` GANA registry.
    506 The respective AML program can then evaluate the data from the form
    507 submission from `attributes`.
    508 
    509 
    510 The LINK Type
    511 ^^^^^^^^^^^^^
    512 
    513 When using KYC checks of type "FORM", the KYC-SPA will show a link that allows
    514 the user to begin the KYC process at an external provider under the given
    515 DESCRIPTION.
    516 
    517 The external providers are expected to yield KYC attributes in the form of
    518 key-value pairs where the list of key is defined in the GANA
    519 ``gnu-taler-kyc-attributes`` registry, which also defines the format of each
    520 attribute.  External providers may not directly yield attributes using the
    521 correct encodings, thus converter helper programs are typically used to convert
    522 external attribute data into the standardized format.
    523 
    524 
    525 Configuration of legitimization rules
    526 -------------------------------------
    527 
    528 The configuration also must specify a set of legitimization rules, one per
    529 configuration section. Each rule specifies the condition and the measure the
    530 condition triggers:
    531 
    532 .. code-block:: ini
    533 
    534   [kyc-rule-$RULE_NAME]
    535 
    536   # Operation that triggers this rule.
    537   # Must be one of AGGREGATE, BALANCE, CLOSE, DEPOSIT, MERGE,
    538   # REFUND, TRANSACTION or WITHDRAW
    539   OPERATION_TYPE = WITHDRAW
    540 
    541   # Space-separated list of next measures to be performed.
    542   # The SPA should display *all* of these measures to the user.
    543   # (They have a choice of either which ones, or in
    544   # which order they are to be performed.)
    545   # A special measure name "verboten" is used if the
    546   # specified threshold may never be crossed
    547   # (under this set of rules).
    548   NEXT_MEASURES = SWISSNESS KYB
    549 
    550   # "YES" if all NEXT_MEASURES will eventually need
    551   # to be satisfied, "NO" if the user has a choice between
    552   # them. Not actually enforced by the exchange, but
    553   # primarily used to inform the user whether this is
    554   # an "and" or "or". YES for "and".
    555   IS_AND_COMBINATOR = YES
    556 
    557   # YES if the rule (specifically, operation type,
    558   # threshold, timeframe) and the general nature of
    559   # the next measure (verboten or approval required)
    560   # should be exposed to the client.
    561   # Defaults to NO if not set.
    562   EXPOSED = YES
    563 
    564   # Threshold amount above which the rule is
    565   # triggered.  The total must be exceeded in the given
    566   # timeframe.
    567   THRESHOLD = KUDOS:100
    568 
    569   # Timeframe over which the amount to be compared to
    570   # the THRESHOLD is calculated.
    571   # Ignored for WALLET-BALANCE.  Can be 'forever'.
    572   TIMEFRAME = 30 days
    573 
    574   # Set to YES to enable the rule (default is NO)
    575   ENABLED = NO
    576 
    577 The operation types of KYC rules refer to the following scenarios:
    578 
    579   * **AGGREGATION**: Triggered when an exchange is about to do an
    580     wire transfer to a merchant. Such wire transfers typically have
    581     aggregated multiple smaller deposits, and thus enforcing KYC rules
    582     at aggregation time is more efficient than checking individual
    583     deposits. Plus, checking at the aggregation level is likely to
    584     render structuring inherently ineffective.
    585     Enforced by the exchange.
    586 
    587   * **BALANCE**: Triggered whenever the balance of a wallet is increased.
    588     Can only be used with a timeframe of zero, as this is about the absolute
    589     amount that can be stored at any time in a compliant wallet.
    590     Enforced by the wallet.
    591 
    592   * **CLOSE**: Triggered when a reserve is closed (explicitly by a wallet
    593     or implicitly by timeout). Use with caution, as this may prevent
    594     an exchange from returning funds that were not withdrawn to users.
    595     Enforced by the exchange.
    596     (Note: This rule is so far not used in production
    597     anywhere, thus likely not tested well yet.)
    598 
    599   * **DEPOSIT**: Sets a limit on the amount that can be deposited by
    600     a merchant into their bank account.  Can be used with a timeframe
    601     of zero to effectively set another transaction limit that additionally
    602     only applies to deposits (and not P2P payments), or with a non-zero
    603     timeframe to limit the amount a merchant can deposit over time.
    604     Usually used with a limit of zero to enforce merchant onboarding
    605     prior to first payment processing.  Inefficient to enforce limits
    606     later, usually for merchants that have been onboarded **AGGREGATION**
    607     limits should be set instead.
    608     Enforced by the exchange.
    609 
    610   * **MERGE**: Triggered when a user received digital cash from another
    611     wallet.
    612     Enforced by the exchange.
    613 
    614   * **REFUND**: Limit on the amount that can be refunded per
    615     transaction by a compliant merchant to a compliant wallet.
    616     Can only be used with a timeframe of zero, as this is about
    617     the amount that can be funded on an individual purchase.
    618     Enforced both wallet-side and merchant-side (enforcement by
    619     the exchange could be implemented in the future, but is
    620     tricky as the exchange sees refunds per coin and not per
    621     purchase).
    622 
    623   * **TRANSACTION**: Refers to all transactions of a wallet where digital
    624     cash is spent. Can be used with a timeframe of zero to set a transaction
    625     limit, or with a non-zero timeframe to limit the spending rate over time.
    626     Applies to spending money both in P2P and merchant transactions.
    627     Enforced by wallets and merchants.
    628 
    629   * **WITHDRAW**: Triggered when a user withdraws digital cash from their
    630     bank account.  Enforced by the exchange.
    631 
    632 
    633 Configuration of AML programs
    634 -----------------------------
    635 
    636 AML decision processes are automatically executed under certain configurable
    637 conditions.  Basically, any AML program that is run can flag an account for
    638 investigation by setting the respective flag in the `AmlOutcome`. Once this
    639 happens, the respective account will be highlighted to AML staff. The AML
    640 program can also limit the operations of the account by setting arbitrary
    641 thresholds for the various operations (including freezing the account by
    642 setting the thresholds to zero). AML staff investigating the account can then
    643 request further documentation or set new rules, including new thresholds.
    644 
    645 AML programs can base their decisions on arbitrary attributes created by the
    646 KYC check (such as the user being a politically exposed person).
    647 
    648 AML programs will be given the KYC attributes in JSON format on standard
    649 input, and must output the `AmlOutcome`. If AML programs fail (return non-zero
    650 status codes), a FALLBACK measure is automatically triggered.  FALLBACK
    651 measures MUST be *original* measures and MUST have a check of type "SKIP"
    652 and MUST NOT require any inputs.
    653 
    654 AML programs are listed in the configuration file, one program per section:
    655 
    656 .. code-block:: ini
    657 
    658   [aml-program-$PROG_NAME]
    659 
    660   # Program to run.
    661   COMMAND = taler-helper-aml-pep
    662 
    663   # Human-readable description of what this
    664   # AML helper program will do. Used to show
    665   # to the AML staff.
    666   DESCRIPTION = "check if the customer is a PEP"
    667 
    668   # True if this AML program is enabled (and thus can be
    669   # used in measures and exposed to AML staff).
    670   # Optional, default is NO.
    671   ENABLED = YES
    672 
    673   # **original** measure to take if COMMAND fails
    674   # Usually points to a measure that asks AML staff
    675   # to contact the systems administrator. The fallback measure
    676   # context always includes the reasons for the
    677   # failure.  FALLBACK measures MUST be *original*
    678   # measures with a check type of "SKIP" without any required
    679   # inputs.
    680   FALLBACK = MEASURE_NAME
    681 
    682 Implementing your own AML programs
    683 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    684 
    685 When implementing an AML program, developers must
    686 ensure to provide four main execution paths:
    687 
    688 * Generate a list of *required* context field names
    689   for the helper (introspection!) when given the "-r"
    690   command-line switch. The output should use the same
    691   syntax as the REQUIRES clause of ``[kyc-check-]``
    692   configuration sections, except that new lines
    693   MUST be used to separate fields instead of ";".
    694 * Generate a list of *required* inputs fields
    695   for the helper (introspection!) when given the "-i"
    696   command-line switch.  The input fields are named
    697   after the respective fields of the `AmlProgramInput`,
    698   thus "attributes", "aml_history", "context", "kyc_history",
    699   "default_rules" and "current_rules" are valid strings
    700   to return. Additionally, for the histories, it is
    701   possible to specify "\*_history[$NUMBER]" where
    702   "$NUMBER" is the number of entries to return, with
    703   positive numbers counting from the start of the
    704   history and negative numbers from the end of the
    705   history. Thus, "aml_history[-1]" will cause only
    706   the last AML history entry to be included.
    707 * Generate a list of *required* attribute names
    708   for the helper (introspection!) when given the "-a"
    709   command-line switch. The output should use the same
    710   list of names as the ATTRIBUTES in the
    711   ``[kyc-provider-]`` configuration section
    712   (but may also include FORM field names).
    713 * Process an input JSON object of type
    714   `AmlProgramInput` into a JSON object of
    715   type `AmlOutcome`.
    716   This is the default behavior if no command-line switches
    717   are provided.
    718 
    719 AML programs will be given the exchange's configuration filename with the "-c
    720 FILENAME" command-line option.  They may or may not use the configuration file
    721 as they see fit. AML programs should support the canonical "-h" (help) and
    722 "-v" (version) command-line options to display a help text and their version
    723 number respectively.  AML programs may be given the "-V" option to put them
    724 into verbose mode, suggesting that they should log additional information to
    725 standard error.
    726 
    727 If the AML program fails (exits with a failure code or does not provide
    728 well-formed JSON output) the AML/KYC process continues with the FALLBACK
    729 measure. This should usually be one that asks AML staff to contact the systems
    730 administrator.
    731 
    732 .. ts:def:: AmlProgramInput
    733 
    734   interface AmlProgramInput {
    735 
    736     // JSON object that was provided as
    737     // part of the *measure*.  This JSON object is
    738     // provided under "context" in the main JSON object
    739     // input to the AML program.  This "context" should
    740     // satify both the REQUIRES clause of the respective
    741     // check and the output of "-r" from the
    742     // AML program's command-line option.
    743     context?: Object;
    744 
    745     // JSON object that captures the
    746     // output of a ``[kyc-provider-]`` or (HTML) FORM.
    747     // In the case of KYC data provided by providers,
    748     // the keys in the JSON object will be the attribute
    749     // names and the values must be strings representing
    750     // the data. In the case of file uploads, the data
    751     // MUST be base64-encoded.
    752     // Attributes are only provided if the AML program
    753     // specifies "attributes" for its input requirements.
    754     attributes?: Object;
    755 
    756     // JSON array with the results of historic
    757     // AML desisions about the account.
    758     //
    759     // AML history is only provided if the AML program
    760     // specifies "aml_history" for its input requirements.
    761     aml_history?: AmlHistoryEntry[];
    762 
    763     // JSON array with the results of historic
    764     // KYC data about the account.
    765     //
    766     // KYC history is only provided if the AML program
    767     // specifies "kyc_history" for its input requirements.
    768     kyc_history?: KycHistoryEntry[];
    769 
    770     // Default KYC rules of the exchange (exposed and not exposed).
    771     //
    772     // Default KYC rules are only provided if the AML program
    773     // specifies "default_rules" for its input requirements.
    774     default_rules?: LegitimizationRuleSet;
    775 
    776     // Current KYC rules the exchange applies for this user.
    777     // (exposed and not exposed).
    778     //
    779     // Current KYC rules are only provided if the AML program
    780     // specifies "current_rules" for its input requirements.
    781     current_rules?: LegitimizationRuleSet;
    782 
    783   }
    784 
    785 .. ts:def:: AmlHistoryEntry
    786 
    787   interface AmlHistoryEntry {
    788     // When was the AML decision taken.
    789     decision_time : Timestamp;
    790 
    791     // What was the justification given for the decision.
    792     justification : string;
    793 
    794     // Public key of the AML officer taking the decision.
    795     decider_pub : AmlOfficerPublicKeyP;
    796 
    797     // Properties associated with the account by the decision.
    798     properties : Object;
    799 
    800     // New set of legitimization rules that was put in place.
    801     new_rules : LegitimizationRuleSet;
    802 
    803     // True if the account was flagged for (further)
    804     // investigation.
    805     to_investigate : boolean;
    806 
    807     // True if this is the currently active decision.
    808     is_active : boolean;
    809   }
    810 
    811 .. ts:def:: KycHistoryEntry
    812 
    813   interface KycHistoryEntry {
    814     // Name of the provider
    815     // which was used to collect the attributes. NULL if they were
    816     // just uploaded via a form by the account owner.
    817     provider_name?: string;
    818 
    819     // True if the KYC process completed.
    820     finished: boolean;
    821 
    822     // Numeric `error code <error-codes>`, if the
    823     // KYC process did not succeed; 0 on success.
    824     code: number;
    825 
    826     // Human-readable description of ``code``. Optional.
    827     hint?: string;
    828 
    829     // Optional detail given when the KYC process failed.
    830     error_message?: string;
    831 
    832     // Identifier of the user at the KYC provider. Optional.
    833     provider_user_id?: string;
    834 
    835     // Identifier of the KYC process at the KYC provider. Optional.
    836     provider_legitimization_id? :string;
    837 
    838     // The collected KYC data.
    839     // NULL if the attribute data could not
    840     // be decrypted or was not yet collected.
    841     attributes?: Object;
    842 
    843     // Time when the KYC data was collected
    844     collection_time: Timestamp;
    845 
    846     // Time when the KYC data will expire.
    847     expiration_time: Timestamp;
    848   }
    849 
    850 .. ts:def:: AmlOutcome
    851 
    852   interface AmlOutcome {
    853 
    854     // Should the client's account be investigated
    855     // by AML staff?
    856     // Defaults to false.
    857     to_investigate?: boolean;
    858 
    859     // Free-form properties about the account.
    860     // Can be used to store properties such as PEP,
    861     // risk category, type of business, hits on
    862     // sanctions lists, etc.
    863     properties?: AccountProperties;
    864 
    865     // Types of events to add to the KYC events table.
    866     // (for statistics).
    867     events?: string[];
    868 
    869     // Space-separated list of measures to trigger
    870     // immediately on the account.
    871     // Prefixed with a "+" to indicate that the
    872     // measures should be ANDed.
    873     // Should typically be used to give the user some
    874     // information or request additional information.
    875     //
    876     // MUST NOT contain an instant measure.
    877     // AML programs may be chained directly via
    878     // exec / fork+exec, but the exchange does not
    879     // support chaining.
    880     new_measures?: string;
    881 
    882     // KYC rules to apply.  Note that this
    883     // overrides *all* of the default rules
    884     // until the ``expiration_time`` and specifies
    885     // the successor measure to apply after the
    886     // expiration time.
    887     new_rules: LegitimizationRuleSet;
    888 
    889   }
    890 
    891 If the AML program fails (exits with a failure code or
    892 does not provide well-formed JSON output) the AML/KYC
    893 process continues with the FALLBACK measure. This should
    894 usually be one that asks AML staff to contact the
    895 systems administrator.
    896 
    897 
    898 
    899 Configuration of measures
    900 -------------------------
    901 
    902 Finally, the configuration specifies a set of
    903 **original** *measures* one per configuration section:
    904 
    905 .. code-block:: ini
    906 
    907   [kyc-measure-$MEASURE_NAME]
    908 
    909   # Possible check for this measure.  Optional.
    910   # If not given (or set to "SKIP"), PROGRAM should
    911   # be run immediately (on an empty set of attributes).
    912   CHECK_NAME = IB_FORM
    913 
    914   # Context for the check. The context can be
    915   # just an empty JSON object if there is none.
    916   CONTEXT = {"choices":["individual","business"]}
    917 
    918   # Program name to run on the context and check data to
    919   # determine the outcome and next measure.
    920   # Refers to a ``[aml-program-$PROG_NAME]`` section name.
    921   PROGRAM = taler-aml-program
    922 
    923 If ``CHECK_NAME`` is set to "SKIP" (or is not provided at all), the AML
    924 ``PROGRAM`` is to be run immediately.  This is useful if no client-interaction
    925 is required to arrive at a decision.
    926 
    927 .. note::
    928 
    929   The list of *measures* in the configuration is not complete: AML staff may
    930   freely define new measures dynamically, usually by selecting checks, an AML
    931   program, and providing context.  The measures specified in the configuration
    932   are called the *original measures* and only those can be used as FALLBACK
    933   measures.
    934 
    935 
    936 
    937 AML Configuration
    938 =================
    939 
    940 The AML configuration steps are used to add or remove keys of exchange
    941 operator staff that are responsible for anti-money laundering (AML)
    942 compliance.  These AML officers are shown suspicious transactions and are
    943 granted access to the KYC data of an exchange. They can then investigate the
    944 transaction and decide on new rules for the respective user. They may request
    945 additional KYC data from the consumer, can change the thresholds up to which
    946 amounts transactions are allowed, and associate properties with the account
    947 that AML programs (and AML officers) may interpret for arbitrary future
    948 actions.
    949 
    950 
    951 AML Officer Setup
    952 -----------------
    953 
    954 To begin the AML setup, AML staff should launch the GNU Taler exchange AML SPA
    955 Web interface by going to the ``/aml-spa/`` endpoint of the exchange. This is
    956 generally a public endpoint, but of course an operator may restrict access via
    957 the reverse proxy. The SPA will generate a public-private key pair and store
    958 it in the local storage of the browser.  The public key will be displayed and
    959 **must** be securely transmitted to the offline system for approval.  Using the
    960 offline system, one can then configure which staff has access to the AML
    961 operations:
    962 
    963 .. code-block:: shell-session
    964 
    965   [root@exchange-offline]# taler-exchange-offline \
    966      aml-enable "$PUBLIC_KEY" "Legal Name" rw > aml.json
    967   [root@exchange-online]# taler-exchange-offline \
    968      upload < aml.json
    969 
    970 The above commands would add an AML officer with the given "Legal Name" with
    971 read-write (rw) access to the AML officer database.  Using "ro" instead of
    972 "rw" would grant read-only access to the data, leaving out the ability to
    973 actually make AML decisions.  Once AML access has been granted, the AML
    974 officer can use the SPA to review cases and (with "rw" access) take AML
    975 decisions.
    976 
    977 Access rights can be revoked at any time using:
    978 
    979 .. code-block:: shell-session
    980 
    981   [root@exchange-offline]# taler-exchange-offline \
    982      aml-disable $PUBLIC_KEY "Legal Name" > aml-off.json
    983   [root@exchange-online]# taler-exchange-offline \
    984      upload < aml-off.json
    985 
    986 
    987 AML Forms
    988 ---------
    989 
    990 AML forms are defined by the :ref:`dynamic forms design document <dd54dynamicforms>`.
    991 The shipped implementation with of the exchange is installed in
    992 
    993 .. code-block:: shell-session
    994 
    995   ${INSTALL_PREFIX}/share/taler-exchange/spa/forms.js
    996 
    997 
    998 The variable ``form`` contains the list of all form available. For
    999 every entry in the list the next properties are expected to be present:
   1000 
   1001 ``label``: used in the UI as the name of the form
   1002 
   1003 ``id``: identification name, this will be saved in the exchange database
   1004 along with the values to correctly render the form again.
   1005 It should simple, short and without any character outside numbers,
   1006 letters and underscore.
   1007 
   1008 ``version``: when editing a form, instead of just replacing fields
   1009 it will be better to create a new form with the same id and new version.
   1010 That way old forms in the database will used old definition of the form.
   1011 It should be a number.
   1012 
   1013 ``impl`` : a function that returns the design and behavior of form.
   1014 See DD 54 dynamic forms.
   1015 
   1016 .. attention::
   1017 
   1018   do not remove a form the list if it has been used. Otherwise you
   1019   won't be able to see the information save in the exchange database.
   1020 
   1021 To add a new one you can simply copy and paste one element, and edit it.
   1022 
   1023 It is much easier to download ``@gnu-taler/aml-backoffice-ui`` source
   1024 from ``https://git.taler.net/wallet-core.git/``, compile and copy the file
   1025 from the ``dist/prod``.
   1026 
   1027 
   1028 .. _sanctions:
   1029 
   1030 Sanction list checking
   1031 ======================
   1032 
   1033 The **taler-exchange-sanctionlist** service can be used to automatically check
   1034 KYC records against sanction lists.  The service is not run by default but
   1035 must be explicitly enabled. It can run in incremental mode, processing
   1036 incoming KYC records immediately when new data is submitted. When a new
   1037 sanction list is released, use the "--reset" option to re-process all existing
   1038 records, checking them again against the latest list.  To only reset the
   1039 position but keep checking in the background, add "--norun". Finally, to run
   1040 the tool manually and exit immediately once all existing KYC records have been
   1041 processed (and not wait for new records to eventually be submitted from new
   1042 customers), use "--test".
   1043 
   1044 The tool operates by decrypting all of the KYC attributes from the exchange
   1045 database and passes them to a helper program which must then determine
   1046 
   1047   * which sanction list record matches best,
   1048   * how well that sanction list record matches, and
   1049   * how certain the tool is that the match is accurate.
   1050 
   1051 Based on this assessment by the helper program, **taler-exchange-sanctionlist**
   1052 will then either
   1053 
   1054   * freeze the account and flag it for investigation (likely match),
   1055   * only flag the account for investigation (possible match), or
   1056   * allow the account to continue as normal (no match)
   1057 
   1058 To avoid the same account being flagged repeatedly for investigation
   1059 due to a false-positive match with the sanction list, AML staff can
   1060 mark an account with the "SANCTION_LIST_SUPPRESS: true"
   1061 property, in which case hits on the sanction list are ignored.
   1062 
   1063 Robocop
   1064 -------
   1065 
   1066 Robocop is an implementation of a sanction list helper that can be used to
   1067 match KYC records against sanction lists. It consists of a generic matching
   1068 tool that computes the editing distance between a provided KYC record and each
   1069 sanction list entry. The sanction list entries must be provided in a file that
   1070 contains a JSON array with all sanction list entries where each entry is a
   1071 JSON object with fields matching the KYC attributes from the GANA registry,
   1072 plus a special field "ssid" that identifies the sanction list entry. Each
   1073 regular attribute field must be mapped to an array of strings where each
   1074 string is a possible spelling for values of this field, for example to allow
   1075 aliases to be given for names.
   1076 
   1077 Given such a sanction list, Robocop finds the best match for
   1078 each KYC record read from standard input (one record per line)
   1079 and outputs the match quality, confidence and the "ssid" of the
   1080 best match in the format expected by **taler-exchange-sanctionlist**.
   1081 
   1082 Robocop additionally includes Python script to convert the Swiss
   1083 sanction list (provided in XML) to its internal JSON format, and
   1084 a shell script to optimize the resulting JSON data by removing
   1085 empty fields.
   1086 
   1087 
   1088 .. _ExchangeTemplateCustomization:
   1089 
   1090 KYC Process Template Customization
   1091 ==================================
   1092 
   1093 The Exchange comes with various HTML templates that are shown to guide users
   1094 through the KYC process. The Exchange uses `C implementation of mustache
   1095 <https://gitlab.com/jobol/mustach>`__ as the templating engine.  This section
   1096 describes the various templates.  In general, the templates must be installed
   1097 to the ``share/taler-exchange/templates/`` directory. The file names must be
   1098 of the form ``$NAME.$LANG.must`` where ``$NAME`` is the name of the template
   1099 and ``$LANG`` is the 2-letter language code of the template. English templates
   1100 must exist and will be used as a fallback.  If the browser (user-agent) has
   1101 provided language preferences in the HTTP header and the respective language
   1102 exists, the correct language will be automatically served.
   1103 
   1104 The following subsections give details about each of the templates. Most
   1105 subsection titles are the ``$NAME`` of the respective template.
   1106 
   1107 
   1108 Generic Errors Templates
   1109 ------------------------
   1110 
   1111 A number of templates are used for generic errors. These are:
   1112 
   1113   * kyc-proof-already-done (KYC process already completed)
   1114   * kyc-bad-request (400 Bad Request)
   1115   * kyc-proof-endpoint-unknown (404 Not Found for KYC logic)
   1116   * kyc-proof-internal-error (500 Internal Server Error)
   1117   * kyc-proof-target-unknown (404 Not Found for KYC operation)
   1118 
   1119 All of these templates are instantiated using the following information:
   1120 
   1121   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1122     error compactly for reporting to developers
   1123 
   1124   * hint: String; human-readable Taler error code, should be shown for the
   1125     user to understand the error
   1126 
   1127   * message: String; optional, extended human-readable text provided to elaborate
   1128     on the error, should be shown to provide additional context
   1129 
   1130 
   1131 kycaid-invalid-request
   1132 ----------------------
   1133 
   1134 The KYCaid plugin does not support requests to the
   1135 ``/kyc-proof/`` endpoint (HTTP 400 bad request).
   1136 
   1137 This template is instantiated using the following information:
   1138 
   1139   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1140     error compactly for reporting to developers
   1141 
   1142   * hint: String; human-readable Taler error code, should be shown for the
   1143     user to understand the error
   1144 
   1145   * error: String; error code from the server
   1146 
   1147   * error_details: String; optional error description from the server
   1148 
   1149   * error_uri: optional URI with further details about the error from the server
   1150 
   1151 
   1152 
   1153 oauth2-authentication-failure
   1154 -----------------------------
   1155 
   1156 The OAuth2 server said that the request was not
   1157 properly authenticated (HTTP 403 Forbidden).
   1158 
   1159 
   1160 This template is instantiated using the following information:
   1161 
   1162   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1163     error compactly for reporting to developers
   1164 
   1165   * hint: String; human-readable Taler error code, should be shown for the
   1166     user to understand the error
   1167 
   1168 
   1169 oauth2-authorization-failure
   1170 ----------------------------
   1171 
   1172 The OAuth2 server refused to return the KYC data because the authorization
   1173 code provided was invalid (HTTP 403 Forbidden).
   1174 
   1175 This template is instantiated using the following information:
   1176 
   1177   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1178     error compactly for reporting to developers
   1179 
   1180   * hint: String; human-readable Taler error code, should be shown for the
   1181     user to understand the error
   1182 
   1183   * error: String; error code from the server
   1184 
   1185   * error_message: String; error message from the server
   1186 
   1187 
   1188 oauth2-authorization-failure-malformed
   1189 --------------------------------------
   1190 
   1191 The server refused the authorization, but then provided
   1192 a malformed response (HTTP 502 Bad Gateway).
   1193 
   1194 This template is instantiated using the following information:
   1195 
   1196   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1197     error compactly for reporting to developers
   1198 
   1199   * hint: string; human-readable Taler error code, should be shown for the
   1200     user to understand the error
   1201 
   1202   * debug: boolean; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
   1203 
   1204   * server_response: Object; could be NULL; this includes the (malformed) OAuth2 server response, it should be shown to the use if "debug" is true
   1205 
   1206 
   1207 oauth2-bad-request
   1208 ------------------
   1209 
   1210 The client made an invalid request (HTTP 400 Bad Request).
   1211 
   1212 This template is instantiated using the following information:
   1213 
   1214   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1215     error compactly for reporting to developers
   1216 
   1217   * hint: String; human-readable Taler error code, should be shown for the
   1218     user to understand the error
   1219 
   1220   * message: String; additional error message elaborating on what was bad about the request
   1221 
   1222 
   1223 oauth2-conversion-failure
   1224 -------------------------
   1225 
   1226 Converting the KYC data into the exchange's internal
   1227 format failed (HTTP 502 Bad Gateway).
   1228 
   1229 This template is instantiated using the following information:
   1230 
   1231   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1232     error compactly for reporting to developers
   1233 
   1234   * hint: string; human-readable Taler error code, should be shown for the
   1235     user to understand the error
   1236 
   1237   * debug: boolean; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
   1238 
   1239   * converter: String; name of the conversion command that failed which was used by the Exchange
   1240 
   1241   * attributes: Object; attributes returned by the conversion command, often NULL (after all, conversion failed)
   1242 
   1243   * message: error message elaborating on the conversion failure
   1244 
   1245 
   1246 oauth2-provider-failure
   1247 -----------------------
   1248 
   1249 We did not get an acceptable response from the OAuth2
   1250 provider (HTTP 502 Bad Gateway).
   1251 
   1252 This template is instantiated using the following information:
   1253 
   1254   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1255     error compactly for reporting to developers
   1256 
   1257   * hint: String; human-readable Taler error code, should be shown for the
   1258     user to understand the error
   1259 
   1260   * message: String; could be NULL; text elaborating on the details of the failure
   1261 
   1262 
   1263 persona-exchange-unauthorized
   1264 -----------------------------
   1265 
   1266 The Persona server refused our request (HTTP 403 Forbidden from Persona, returned as a HTTP 502 Bad Gateway).
   1267 
   1268 This template is instantiated using the following information:
   1269 
   1270   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1271     error compactly for reporting to developers
   1272 
   1273   * hint: String; human-readable Taler error code, should be shown for the
   1274     user to understand the error
   1275 
   1276   * data: Object; data returned from Persona service, optional
   1277 
   1278   * persona_http_status: Integer; HTTP status code returned by Persona
   1279 
   1280 
   1281 persona-load-failure
   1282 --------------------
   1283 
   1284 The Persona server refused our request (HTTP 429 Too Many Requests from Persona, returned as a HTTP 503 Service Unavailable).
   1285 
   1286 This template is instantiated using the following information:
   1287 
   1288   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1289     error compactly for reporting to developers
   1290 
   1291   * hint: String; human-readable Taler error code, should be shown for the
   1292     user to understand the error
   1293 
   1294   * data: Object; data returned from Persona service, optional
   1295 
   1296   * persona_http_status: Integer; HTTP status code returned by Persona
   1297 
   1298 
   1299 persona-exchange-unpaid
   1300 -----------------------
   1301 
   1302 The Persona server refused our request (HTTP 402 Payment REquired from Persona, returned as a HTTP 503 Service Unavailable).
   1303 
   1304 This template is instantiated using the following information:
   1305 
   1306   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1307     error compactly for reporting to developers
   1308 
   1309   * hint: String; human-readable Taler error code, should be shown for the
   1310     user to understand the error
   1311 
   1312   * data: Object; data returned from Persona service, optional
   1313 
   1314   * persona_http_status: Integer; HTTP status code returned by Persona
   1315 
   1316 
   1317 
   1318 persona-logic-failure
   1319 ---------------------
   1320 
   1321 The Persona server refused our request (HTTP 400, 403, 409, 422 from Persona, returned as a HTTP 502 Bad Gateway).
   1322 
   1323 This template is instantiated using the following information:
   1324 
   1325   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1326     error compactly for reporting to developers
   1327 
   1328   * hint: String; human-readable Taler error code, should be shown for the
   1329     user to understand the error
   1330 
   1331   * data: Object; data returned from Persona service, optional
   1332 
   1333   * persona_http_status: Integer; HTTP status code returned by Persona
   1334 
   1335 
   1336 persona-invalid-response
   1337 ------------------------
   1338 
   1339 The Persona server refused our request in an
   1340 unexpected way; returned as a HTTP 502 Bad Gateway.
   1341 
   1342 This template is instantiated using the following information:
   1343 
   1344   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1345     error compactly for reporting to developers
   1346 
   1347   * hint: string; human-readable Taler error code, should be shown for the
   1348     user to understand the error
   1349 
   1350   * debug: boolean; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
   1351 
   1352   * server_response: Object; could be NULL; this includes the (malformed) OAuth2 server response, it should be shown to the use if "debug" is true
   1353 
   1354 
   1355 persona-network-timeout
   1356 -----------------------
   1357 
   1358 The Persona server refused our request (HTTP 408 from Persona, returned as a HTTP 504 Gateway Timeout).
   1359 
   1360 This template is instantiated using the following information:
   1361 
   1362   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1363     error compactly for reporting to developers
   1364 
   1365   * hint: String; human-readable Taler error code, should be shown for the
   1366     user to understand the error
   1367 
   1368   * data: Object; data returned from Persona service, optional
   1369 
   1370   * persona_http_status: Integer; HTTP status code returned by Persona
   1371 
   1372 
   1373 persona-kyc-failed
   1374 ------------------
   1375 
   1376 The Persona server indicated a problem with the KYC process, saying it was not completed.
   1377 
   1378 This template is instantiated using the following information:
   1379 
   1380   * persona_inquiry_id: String; internal ID of the inquiry within Persona, useful for further diagnostics by staff
   1381 
   1382   * data: Object; could be NULL; this includes the server response, it contains extensive diagnostics, see Persona documentation on their ``/api/v1/inquiries/$ID``.
   1383 
   1384   * persona_http_status: Integer; HTTP status code returned by Persona
   1385 
   1386 persona-provider-failure
   1387 ------------------------
   1388 
   1389 The Persona server refused our request (HTTP 500 from Persona, returned as a HTTP 502 Bad Gateway).
   1390 
   1391 This template is instantiated using the following information:
   1392 
   1393   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1394     error compactly for reporting to developers
   1395 
   1396   * hint: String; human-readable Taler error code, should be shown for the
   1397     user to understand the error
   1398 
   1399   * data: Object; data returned from Persona service, optional
   1400 
   1401   * persona_http_status: Integer; HTTP status code returned by Persona