taler-docs

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

api-merchant.rst (215461B)


      1 ..
      2   This file is part of GNU TALER.
      3   Copyright (C) 2014-2025 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Affero General Public License as published by the Free Software
      7   Foundation; either version 2.1, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
     12 
     13   You should have received a copy of the GNU Affero General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 
     16   @author Marcello Stanisci
     17   @author Florian Dold
     18   @author Christian Grothoff
     19   @author Priscilla Huang
     20   @author Martin Schanzenbach
     21 
     22 .. _merchant-api:
     23 
     24 ============================
     25 Merchant Backend RESTful API
     26 ============================
     27 
     28 ---------------
     29 Version History
     30 ---------------
     31 
     32 The current protocol version is ``v20``.
     33 
     34 Android PoS app is currently targeting ``v20``.
     35 
     36 **Version history:**
     37 
     38 * ``v21`` (in development): Adds self-provisioning and two factor authentication.
     39 
     40 -----------------------
     41 Base URLs and Instances
     42 -----------------------
     43 
     44 A single merchant backend installation can host multiple merchant instances.
     45 This is useful when multiple businesses want to share the same payment
     46 infrastructure.
     47 
     48 Merchant backends have one special ``admin`` instance.  This ``admin``
     49 instance is used when no explicit instance is specified.  Note that using
     50 ``/instances/admin/$ANYTHING`` is deprecated and will result in a permanent
     51 redirect (HTTP status 308) to ``$ANYTHING``. a Despite its name, this instance
     52 must be created after the installation.
     53 
     54 Each instance (admin and others) has a base URL.  The resources under
     55 this base URL are divided into to categories:
     56 
     57 * Public endpoints that are exposed to the Internet
     58 * Private endpoints (under ``/private/*``) that are only supposed to be exposed
     59   to the merchant internally, and must not be exposed on the
     60   Internet.
     61 * Management endpoints (under ``/management/*``) are also private and dedicated
     62   to CRUD operation over instances and reset authentication settings over all
     63   instances. Only accessible with the admin instance authentication token.
     64 
     65 Examples:
     66 
     67 .. code-block:: none
     68 
     69    Base URL of the merchant (admin instance) at merchant-backend.example.com:
     70    https://merchant-backend.example.com/
     71 
     72    A private endpoint (admin instance):
     73    https://merchant-backend.example.com/private/orders
     74 
     75    A public endpoint (admin instance and order id "ABCD"):
     76    https://merchant-backend.example.com/orders/ABCD
     77 
     78    A private endpoint ("myinst" instance):
     79    https://merchant-backend.example.com/instances/myinst/private/orders
     80 
     81    A public endpoint ("myinst" instance and order id "ABCD"):
     82    https://merchant-backend.example.com/instances/myinst/orders/ABCD
     83 
     84    A private endpoint (explicit "admin" instance):
     85    https://merchant-backend.example.com/private/orders
     86 
     87    A public endpoint (explicit "admin" instance):
     88    https://merchant-backend.example.com/orders
     89 
     90    Endpoints to manage other instances (ONLY for implicit "admin" instance):
     91    https://merchant-backend.example.com/management/instances
     92    https://merchant-backend.example.com/management/instances/$ID
     93 
     94    Endpoints to manage own instance:
     95    https://merchant-backend.example.com/private
     96    https://merchant-backend.example.com/private/auth
     97    https://merchant-backend.example.com/instances/$ID/private
     98    https://merchant-backend.example.com/instances/$ID/forgot-password
     99    https://merchant-backend.example.com/instances/$ID/private/auth
    100 
    101    Unavailabe endpoints (will return 404):
    102    https://merchant-backend.example.com/instances/myinst/private/instances
    103 
    104 -----------------
    105 Generic Responses
    106 -----------------
    107 
    108 The following (error) responses are applicable to all endpoints
    109 unless specified otherwise.
    110 
    111 .. http:any:: *
    112 
    113   :http:statuscode:`403 Forbidden`:
    114     * ``TALER_EC_GENERIC_FORBIDDEN``: Missing permissions.
    115     * ``TALER_EC_MERCHANT_ACCOUNT_TWOFA_UNCONFIRMED``: The account
    116       needs to confirm authentication factors before it can proceed
    117       with the request.
    118 
    119 --------------
    120 Authentication
    121 --------------
    122 
    123 Each merchant instance has separate authentication settings for the private API resources
    124 of that instance.
    125 
    126 Currently, the ``/private/auth/`` API supports two main authentication methods in the ``InstanceAuthConfigurationMessage``:
    127 
    128 * ``external``: (@deprecated since **v20**) With this method, no checks are done by the merchant backend.
    129   Instead, a reverse proxy / API gateway must do all authentication/authorization checks.
    130 * ``token`` (**@since v19**): With this method, the client must provide an authorization header
    131   that contains a bearer token  when accessing a protected endpoint in the form
    132   ``Authorization: Bearer secret-token:$TOKEN``.
    133   ``$TOKEN`` is an authentication token retrieved from the ``/private/token`` endpoint using basic authorization.
    134   The respective username is the instance ``$ID``, and the password the instance password (``$INSTANCE_PASSWORD``).
    135   A login token is commonly only valid for a limited period of time and scoped to specific permissions.
    136   If the ``$INSTANCE_PASSWORD`` is lost, the administrator can set a password
    137   using the ``taler-merchant-passwd`` command-line tool.
    138 * ``token`` (@deprecated since **v19**): With this method, the client must provide an authentication token in
    139   the format ``secret-token: $INSTANCE_PASSWORD``.
    140   The behaviour is then equivalent to the ``token`` method above.
    141   Any API may be accessed using the bearer authentication ``secret-token: $INSTANCE_PASSWORD``.
    142   Notice that this behaviour is deprecated and will be phased out in favor of login tokens.
    143 
    144 For testing, the service may be started with the configuration option ``DISABLED_AUTHENTICATION = YES``
    145 in section ``[merchant]`` (@since **v20**).
    146 
    147 Scopes
    148 ^^^^^^
    149 
    150 Access tokens can be requested with a (limiting) scope. Available scopes and their associated permissions are:
    151 
    152 * ``readonly``: ``*-read`` -- Access to APIs using ``GET`` requests is always allowed.
    153 * ``write`` (*deprecated*): See ``all``.
    154 * ``all``: ``*`` -- General access to all APIs and endpoints and always refreshable. (@since **v19**)
    155 * ``spa``: ``*`` -- General access to all APIs and endpoints. (@since **v20**)
    156 * ``order-simple``: ``orders-read``, ``orders-write`` -- Allows the creation of orders and checking of payment status. (@since **v19**)
    157 * ``order-pos``: ``orders-read``, ``orders-write``, ``inventory-lock`` -- Same as ``order-simple`` and allows inventory locking. (@since **v19**)
    158 * ``order-mgmt``: ``orders-read``, ``orders-write``, ``orders-refund`` -- Same as ``order-simple`` and also allows refunding. (@since **v19**)
    159 * ``order-full``: ``orders-read``, ``orders-write``, ``inventory-lock``, ``orders-refund`` -- Same ``order-pos`` and ``order-mgmt`` combined. (@since **v19**)
    160 
    161 Since **v19** the scope may be suffixed with ``:refreshable``, e.g. ``order-pos:refreshable``.
    162 This allows the token to be refreshed at the token endpoint.
    163 This behaviour replaces the deprecated ``refreshable`` field in the `LoginTokenRequest`.
    164 
    165 -----------------
    166 Configuration API
    167 -----------------
    168 
    169 The configuration API exposes basic information about a merchant backend,
    170 such as the implemented version of the protocol and the currency used.
    171 
    172 .. http:get:: /config
    173 
    174   Return the protocol version and currency supported by this merchant backend.
    175   This specification corresponds to ``current`` protocol being version **v24**.
    176 
    177   **Response:**
    178 
    179   :http:statuscode:`200 OK`:
    180     The body is a `MerchantVersionResponse`.
    181 
    182   **Details:**
    183 
    184   .. ts:def:: MerchantVersionResponse
    185 
    186     interface MerchantVersionResponse {
    187       // libtool-style representation of the Merchant protocol version, see
    188       // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
    189       // The format is "current:revision:age".
    190       version: string;
    191 
    192       // Name of the protocol.
    193       name: "taler-merchant";
    194 
    195       // URN of the implementation (needed to interpret 'revision' in version).
    196       // @since **v8**, may become mandatory in the future.
    197       implementation?: string;
    198 
    199       // Default (!) currency supported by this backend.
    200       // This is the currency that the backend should
    201       // suggest by default to the user when entering
    202       // amounts. See ``currencies`` for a list of
    203       // supported currencies and how to render them.
    204       currency: string;
    205 
    206       // Which Persona should be used by default by new clients in the SPA.
    207       // Can be changed locally per browers under "Personalization".
    208       // Possible values include "expert", "offline-vending-machine",
    209       // "point-of-sale", "digital-publishing", "e-commerce" and "developer".
    210       // @since **v23**.
    211       default_persona: string;
    212 
    213       // How services should render currencies supported
    214       // by this backend.  Maps
    215       // currency codes (e.g. "EUR" or "KUDOS") to
    216       // the respective currency specification.
    217       // All currencies in this map are supported by
    218       // the backend.  Note that the actual currency
    219       // specifications are a *hint* for applications
    220       // that would like *advice* on how to render amounts.
    221       // Applications *may* ignore the currency specification
    222       // if they know how to render currencies that they are
    223       // used with.
    224       currencies: { currency : CurrencySpecification};
    225 
    226       // Array of exchanges trusted by the merchant.
    227       // @since **v6**.
    228       exchanges: ExchangeConfigInfo[];
    229 
    230       // Set when the merchant supports
    231       // self-provisioning instances.
    232       // Since protocol **v21**
    233       have_self_provisioning: boolean;
    234 
    235       // True if this merchant backend supports the Donau
    236       // extension and can thus issue donation receipts.
    237       // Should primarily be used to control the SPA's CRUD
    238       // functionality for Donau.
    239       // @since **v21**
    240       have_donau: boolean;
    241 
    242       // Tan channels that are required
    243       // to be confirmed for an instance to
    244       // be useable.
    245       // @since **v21**
    246       mandatory_tan_channels?: TanChannel[];
    247 
    248       // Space-separated list of enabled payment target types.
    249       // Useful if the SPA should not show allow adding other
    250       // types of bank accounts. "*" is used to represent no
    251       // restriction.
    252       // @since **v22**
    253       payment_target_types: string;
    254 
    255       // Regular expression representing further restrictions
    256       // on allowed payment targets.  Any "payto://"-URI supplied
    257       // for a bank account must match the given regular expression.
    258       // For example, "payto://iban/CH.*" would restrict the system
    259       // to only Swiss bank accounts.
    260       // Optional, no restrictions are imposed if the field is
    261       // absent.
    262       // @since **v22**
    263       // CAUTION: Likely to be removed/deprecated,
    264       // as we'll want an array of restrictions with the
    265       // same format as the exchange uses, as this allows
    266       // proper i18n and spec/code reuse.
    267       payment_target_regex? string;
    268 
    269       // Default payment delay for new instances.
    270       // This is the default to use for new instances, see the instance value for
    271       // the instance-specific default.
    272       // A value of "forever" is not allowed.
    273       // @since **v22**
    274       default_pay_delay: RelativeTime;
    275 
    276       // If the frontend does NOT specify a refund deadline, how long should
    277       // refunds be allowed by default?
    278       // This is the default to use for new instances, see the instance value for
    279       // the instance-specific default.
    280       // A value of "forever" is not allowed.
    281       // @since **v22**
    282       default_refund_delay: RelativeTime;
    283 
    284       // Default wire transfer delay for new instances.
    285       // This is the default to use for new instances, see the instance value for
    286       // the instance-specific default.
    287       // A value of "forever" is not allowed.
    288       // @since **v22**
    289       default_wire_transfer_delay: RelativeTime;
    290 
    291       // Default interval to which wire deadlines computed by
    292       // adding the wire_transfer_delay on top of the refund
    293       // deadline should be rounded up to.
    294       // @since **v23**
    295       default_wire_transfer_rounding_interval: RoundingInterval;
    296     }
    297 
    298   .. ts:def:: TanChannel
    299 
    300     enum TanChannel {
    301       SMS = "sms",
    302       EMAIL = "email"
    303     }
    304 
    305   .. ts:def:: RoundingInterval
    306 
    307    enum RoundingInterval {
    308       NONE = "NONE",
    309       SECOND = "SECOND",
    310       MINUTE = "MINUTE",
    311       HOUR = "HOUR",
    312       DAY = "DAY",
    313       WEEK = "WEEK",
    314       MONTH = "MONTH",
    315       QUARTER = "QUARTER",
    316       YEAR = "YEAR"
    317     }
    318 
    319   .. ts:def:: ExchangeConfigInfo
    320 
    321     interface ExchangeConfigInfo {
    322 
    323       // Base URL of the exchange REST API.
    324       base_url: string;
    325 
    326       // Currency for which the merchant is configured
    327       // to trust the exchange.
    328       // May not be the one the exchange actually uses,
    329       // but is the only one we would trust this exchange for.
    330       currency: string;
    331 
    332       // Offline master public key of the exchange. The
    333       // ``/keys`` data must be signed with this public
    334       // key for us to trust it.
    335       master_pub: EddsaPublicKey;
    336     }
    337 
    338 .. include:: tos.rst
    339 
    340 ---------------
    341 Two Factor Auth
    342 ---------------
    343 
    344 202 Challenge Responses
    345 ^^^^^^^^^^^^^^^^^^^^^^^
    346 
    347 Various APIs generate ``202 Accepted`` HTTP status codes when multi-factor
    348 authentication (MFA) is required.  In this case, the response will be a
    349 `ChallengeResponse`.  In these cases, the client must first request and solve
    350 one or more challenges before repeating the request. When repeating the
    351 request, they must include a list of comma-separated challenge IDs of the
    352 solved challenges in an ``Taler-Challenge-Ids`` HTTP header. The body must
    353 remain absolutely unchanged.
    354 
    355   .. note::
    356 
    357     If all allowed attempts to solve the MFA challenge(s) fail, the endpoint
    358     may start to return ``403 Forbidden`` until the issued challenges expire,
    359     preventing the request from being completed for a while.  In this case,
    360     repeating the request with a different body may still be allowed!
    361 
    362   .. ts:def:: ChallengeResponse
    363 
    364     // @since v21
    365     interface ChallengeResponse {
    366       // List of challenge IDs that must be solved before the
    367       // client may proceed.
    368       challenges: Challenge[];
    369 
    370       // True if **all** challenges must be solved (AND), false if
    371       // it is sufficient to solve one of them (OR).
    372       combi_and: boolean;
    373 
    374     }
    375 
    376   .. ts:def:: Challenge
    377 
    378     interface Challenge {
    379       // Unique identifier of the challenge to solve to run this protected
    380       // operation.
    381       challenge_id: string;
    382 
    383       // Channel of the last successful transmission of the TAN challenge.
    384       tan_channel: TanChannel;
    385 
    386       // Info of the last successful transmission of the TAN challenge.
    387       // Hint to show to the user as to where the challenge was
    388       // sent or what to use to solve the challenge. May not
    389       // contain the full address for privacy.
    390       tan_info: string;
    391 
    392     }
    393 
    394 Requesting challenges
    395 ^^^^^^^^^^^^^^^^^^^^^
    396 
    397 .. http:post:: [/instances/$INSTANCE]/challenge/$CHALLENGE_ID
    398 
    399   Send TAN code for the ``CHALLENGE_ID`` challenge.
    400 
    401   This request can be posted several times to trigger TAN retransmission when
    402   the current code has expired or too many confirmation attempts have been
    403   made.
    404 
    405   This endpoint is not authenticated, it may be used even when mandatory TAN
    406   channels were not validated yet.
    407 
    408   @since **v21**
    409 
    410   **Request:**
    411 
    412   The request body must be a JSON object, but can otherwise be empty
    413   (so just send '{}').
    414 
    415   **Response:**
    416 
    417   :http:statuscode:`200 Ok`:
    418     The TAN code has been sent. The body will be a `ChallengeRequestResponse`.
    419   :http:statuscode:`404 Not Found`:
    420     The challenge was not found.
    421     Returned with ``TALER_EC_MERCHANT_TAN_CHALLENGE_UNKNOWN``.
    422   :http:statuscode:`410 Gone`:
    423     The challenge was already solved.
    424     Returned with ``TALER_EC_MERCHANT_TAN_CHALLENGE_SOLVED``.
    425   :http:statuscode:`429 Too many requests`:
    426     Too many challenges are active right now,
    427     you must wait or confirm current challenges.
    428     Returned with ``TALER_EC_MERCHANT_TAN_TOO_EARLY``.
    429   :http:statuscode:`502 Bad Gateway`:
    430     TAN transmition via ``tan_channel`` failed.
    431     Returned with ``TALER_EC_MERCHANT_MFA_HELPER_EXEC_FAILED``.
    432 
    433   **Details:**
    434 
    435   .. ts:def:: ChallengeRequestResponse
    436 
    437     interface ChallengeRequestResponse {
    438       // How long does the client have to solve the
    439       // challenge.
    440       solve_expiration: Timestamp;
    441 
    442       // What is the earlist time at which the client
    443       // may request a new challenge to be transmitted?
    444       earliest_retransmission: Timestamp;
    445     }
    446 
    447 Solving challenges
    448 ^^^^^^^^^^^^^^^^^^
    449 
    450 .. http:post:: [/instances/$INSTANCE]/challenge/$CHALLENGE_ID/confirm
    451 
    452   Solves the ``CHALLENGE_ID`` challenge and allows performing the protected operation.
    453 
    454   @since **v21**
    455 
    456   When the challenge is confirmed, you can call the protected endpoint again
    457   with ``CHALLENGE_ID`` in the ``Taler-Challenge-Ids`` HTTP header and the
    458   original request body.
    459 
    460   This endpoints is not authenticated for token creation challenges. Too many
    461   unsuccessful attempts to confirm token creation challenges block the
    462   account.
    463 
    464   This endpoint may be used even when mandatory TAN channels
    465   were not validated yet.
    466 
    467   **Request:**
    468 
    469   .. ts:def:: MerchantChallengeSolveRequest
    470 
    471     interface MerchantChallengeSolveRequest {
    472 
    473       // The TAN code that solves $CHALLENGE_ID.
    474       tan: string;
    475     }
    476 
    477   **Response:**
    478 
    479   :http:statuscode:`204 No Content`:
    480     The challenge was solved.
    481   :http:statuscode:`404 Not Found`:
    482     The challenge was not found.
    483     Returned with ``TALER_EC_MERCHANT_TAN_CHALLENGE_UNKNOWN``.
    484   :http:statuscode:`409 Conflict`:
    485     Wrong TAN, returned with an
    486     error code of ``TALER_EC_MERCHANT_TAN_CHALLENGE_FAILED``.
    487   :http:statuscode:`429 Too many requests`:
    488     Too many failed confirmation attempts, a new TAN must be requested.
    489     Returned with ``TALER_EC_MERCHANT_TAN_TOO_MANY_ATTEMPTS``.
    490 
    491 ----------
    492 Wallet API
    493 ----------
    494 
    495 This section describes (public) endpoints that wallets must be able
    496 to interact with directly (without HTTP-based authentication). These
    497 endpoints are used to process payments (claiming an order, paying
    498 for the order, checking payment/refund status and aborting payments),
    499 and to process refunds (checking refund status, obtaining the refund).
    500 
    501 
    502 Claiming an order
    503 ^^^^^^^^^^^^^^^^^
    504 
    505 The first step of processing any Taler payment consists of the
    506 (authorized) wallet claiming the order for itself. In this process,
    507 the wallet provides a wallet-generated nonce that is added
    508 into the contract terms.  This step prevents two different
    509 wallets from paying for the same contract, which would be bad
    510 especially if the merchant only has finite stocks.
    511 
    512 A claim token can be used to ensure that the wallet claiming an
    513 order is actually authorized to do so. This is useful in cases
    514 where order IDs are predictable and malicious actors may try to
    515 claim orders (say in a case where stocks are limited).
    516 
    517 
    518 .. http:post:: [/instances/$INSTANCE]/orders/$ORDER_ID/claim
    519 
    520   Wallet claims ownership (via nonce) over an order.  By claiming
    521   an order, the wallet obtains the full contract terms, and thereby
    522   implicitly also the hash of the contract terms it needs for the
    523   other ``public`` APIs to authenticate itself as the wallet that
    524   is indeed eligible to inspect this particular order's status.
    525 
    526   **Request:**
    527 
    528   The request must be a `ClaimRequest`.
    529 
    530   **Response:**
    531 
    532   :http:statuscode:`200 OK`:
    533     The client has successfully claimed the order.
    534     The response contains the :ref:`contract terms <contract-terms>`.
    535   :http:statuscode:`404 Not found`:
    536     The backend is unaware of the instance or order.
    537   :http:statuscode:`409 Conflict`:
    538     Someone else has already claimed the same order ID with a different nonce.
    539 
    540   **Details:**
    541 
    542   .. ts:def:: ClaimRequest
    543 
    544     interface ClaimRequest {
    545       // Nonce to identify the wallet that claimed the order.
    546       nonce: string;
    547 
    548       // Token that authorizes the wallet to claim the order.
    549       // *Optional* as the merchant may not have required it
    550       // (``create_token`` set to ``false`` in `PostOrderRequest`).
    551       token?: ClaimToken;
    552     }
    553 
    554   .. ts:def:: ClaimResponse
    555 
    556     interface ClaimResponse {
    557       // Contract terms of the claimed order
    558       contract_terms: ContractTerms;
    559 
    560       // Signature by the merchant over the contract terms.
    561       sig: EddsaSignature;
    562     }
    563 
    564 Making the payment
    565 ^^^^^^^^^^^^^^^^^^
    566 
    567 .. http:post:: [/instances/$INSTANCE]/orders/$ORDER_ID/pay
    568 
    569   Pay for an order by giving a deposit permission for coins.  Typically used by
    570   the customer's wallet.  Note that this request does not include the
    571   usual ``h_contract`` argument to authenticate the wallet, as the hash of
    572   the contract is implied by the signatures of the coins.  Furthermore, this
    573   API doesn't really return useful information about the order.
    574 
    575   **Request:**
    576 
    577   The request must be a `pay request <PayRequest>`.
    578 
    579   **Response:**
    580 
    581   :http:statuscode:`200 OK`:
    582     The exchange accepted all of the coins.
    583     The body is a `payment response <PaymentResponse>`.
    584     The ``frontend`` should now fulfill the contract.
    585     Note that it is possible that refunds have been granted.
    586   :http:statuscode:`400 Bad request`:
    587     Either the client request is malformed or some specific processing error
    588     happened that may be the fault of the client as detailed in the JSON body
    589     of the response.
    590     This includes the case where the payment is insufficient (sum is below
    591     the required total amount, for example because the wallet calculated the
    592     fees wrong).
    593 
    594     Applicable error codes:
    595 
    596     * ``MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND``: Wallet tried
    597       to pay with a non-existent denomination.
    598 
    599   :http:statuscode:`402 Payment required`:
    600     There used to be a sufficient payment, but due to refunds the amount effectively
    601     paid is no longer sufficient. (If the amount is generally insufficient, we
    602     return "400 Bad Request", only if this is because of refunds we return 402.)
    603   :http:statuscode:`403 Forbidden`:
    604     One of the coin signatures was not valid.
    605   :http:statuscode:`404 Not found`:
    606     The merchant backend could not find the order or the instance and thus cannot process the payment.
    607   :http:statuscode:`408 Request timeout`:
    608     The backend took too long to process the request. Likely the merchant's connection
    609     to the exchange timed out. Try again.
    610   :http:statuscode:`409 Conflict`:
    611     The exchange rejected the payment because a coin was already spent (or
    612     used in a different way for the same purchase previously), or
    613     the merchant rejected the payment because the order was already fully paid
    614     (and then return signatures with refunds). If a coin was already spent
    615     (this includes re-using the same coin after a refund),
    616     the response will include the ``exchange_url`` for which the payment failed,
    617     in addition to the response from the exchange to the ``/batch-deposit`` request.
    618 
    619     Applicable error codes:
    620 
    621     * ``MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS``:  Exchange reported insufficient
    622       funds for one of the coins.
    623 
    624   :http:statuscode:`410 Gone`:
    625     The offer has expired and is no longer available.
    626   :http:statuscode:`412 Precondition failed`:
    627     The given exchange is not acceptable for this merchant, as it is not in the
    628     list of accepted exchanges and not audited by an approved auditor.
    629     TODO: Status code may be changed to 409 in the future as 412 is technically wrong.
    630   :http:statuscode:`451 Unavailable for Legal Reasons`:
    631     The exchange has rejected the deposit by the merchant
    632     for legal reasons. This is **not** exactly a client
    633     failure (and possibly nobody's fault except for the
    634     regulator). In any case, the wallet should refresh
    635     the deposited coins of the affected exchange and
    636     may try to pay with coins from another exchange if
    637     possible (it has such coins and the merchant accepts
    638     coins from another exchange).
    639     The body is a `PaymentDeniedLegallyResponse` with
    640     details about the failure.
    641     Since protocol **v17**.
    642   :http:statuscode:`502 Bad gateway`:
    643     The merchant's interaction with the exchange failed in some way.
    644     The client might want to try again later.
    645     This includes failures such as the denomination key of a coin not being
    646     known to the exchange as far as the merchant can tell.
    647   :http:statuscode:`504 Gateway timeout`:
    648     The merchant's interaction with the exchange took too long.
    649     The client might want to try again later.
    650 
    651   The backend will return verbatim the error codes received from the exchange's
    652   :ref:`deposit <deposit>` API.  If the wallet made a mistake, like by
    653   double-spending for example, the frontend should pass the reply verbatim to
    654   the browser/wallet.  If the payment was successful, the frontend MAY use
    655   this to trigger some business logic.
    656 
    657   **Details:**
    658 
    659   .. ts:def:: PaymentResponse
    660 
    661     interface PaymentResponse {
    662       // Signature on ``TALER_PaymentResponsePS`` with the public
    663       // key of the merchant instance.
    664       sig: EddsaSignature;
    665 
    666       // Text to be shown to the point-of-sale staff as a proof of
    667       // payment.
    668       pos_confirmation?: string;
    669 
    670       // Signed tokens. Returned in the same order as the
    671       // token envelopes were provided in the request. Specifically,
    672       // the order will follow the order of the outputs from the
    673       // contract terms, and then within each output follow the
    674       // order in which the ``wallet_data`` contained the respective
    675       // blinded envelopes.  The donation tokens will be present
    676       // at the offset matching the place where a donation receipt
    677       // was indicated in the outputs array, and of course be skipped
    678       // if the ``PayWalletData`` did not have a ``donau`` field.
    679       // @since protocol **v21**
    680       token_sigs?: SignedTokenEnvelope[];
    681 
    682     }
    683 
    684   .. ts:def:: PayRequest
    685 
    686     interface PayRequest {
    687       // The coins used to make the payment.
    688       coins: CoinPaySig[];
    689 
    690       // Input tokens required by choice indicated by ``choice_index``.
    691       // @since protocol **v21**
    692       tokens?: TokenUseSig[];
    693 
    694       // Custom inputs from the wallet for the contract.
    695       wallet_data?: PayWalletData;
    696 
    697       // The session for which the payment is made (or replayed).
    698       // Only set for session-based payments.
    699       session_id?: string;
    700 
    701     }
    702 
    703   .. ts:def:: SignedTokenEnvelope
    704 
    705     interface SignedTokenEnvelope {
    706 
    707       // Blind signature made by the merchant.
    708       blind_sig: TokenIssueBlindSig;
    709 
    710     }
    711 
    712   .. ts:def:: TokenIssueBlindSig
    713 
    714     type TokenIssueBlindSig = RSATokenIssueBlindSig | CSTokenIssueBlindSig;
    715 
    716   .. ts:def:: RSATokenIssueBlindSig
    717 
    718     interface RSATokenIssueBlindSig {
    719       cipher: "RSA";
    720 
    721       // (blinded) RSA signature
    722       blinded_rsa_signature: BlindedRsaSignature;
    723     }
    724 
    725   .. ts:def:: CSTokenIssueBlindSig
    726 
    727     interface CSTokenIssueBlindSig {
    728       cipher: "CS";
    729 
    730       // Signer chosen bit value, 0 or 1, used
    731       // in Clause Blind Schnorr to make the
    732       // ROS problem harder.
    733       b: Integer;
    734 
    735       // Blinded scalar calculated from c_b.
    736       s: Cs25519Scalar;
    737 
    738     }
    739 
    740   .. ts:def:: PayWalletData
    741 
    742     interface PayWalletData {
    743       // Index of the selected choice within the ``choices`` array of
    744       // the contract terms.
    745       // @since protocol **v21**
    746       choice_index?: Integer;
    747 
    748       // Array of output tokens to be (blindly) signed by the merchant.
    749       // Output tokens specified in choice indicated by ``choice_index``.
    750       // @since protocol **v21**
    751       tokens_evs?: TokenEnvelope[];
    752 
    753       // Request for donation receipts to be issued.
    754       // @since protocol **v21**
    755       donau?: DonationRequestData;
    756     }
    757 
    758   .. ts:def:: DonationRequestData
    759 
    760     interface DonationRequestData {
    761       // Base URL of the selected Donau
    762       url: string;
    763 
    764       // Year for which the donation receipts are expected.
    765       // Also determines which keys are used to sign the
    766       // blinded donation receipts.
    767       year: Integer;
    768 
    769       // Array of blinded donation receipts to sign.
    770       // Must NOT be empty (if no donation receipts
    771       // are desired, just leave the entire ``donau``
    772       // argument blank).
    773       budikeypairs: BlindedDonationReceiptKeyPair[];
    774     }
    775 
    776   .. ts:def:: CoinPaySig
    777 
    778     interface CoinPaySig {
    779       // Signature by the coin.
    780       coin_sig: EddsaSignature;
    781 
    782       // Public key of the coin being spent.
    783       coin_pub: EddsaPublicKey;
    784 
    785       // Signature made by the denomination public key.
    786       ub_sig: UnblindedSignature;
    787 
    788       // The hash of the denomination public key associated with this coin.
    789       h_denom: HashCode;
    790 
    791       // The amount that is subtracted from this coin with this payment.
    792       contribution: Amount;
    793 
    794       // URL of the exchange this coin was withdrawn from.
    795       exchange_url: string;
    796 
    797       // Signature affirming the posession of the
    798       // respective private key proving that the payer
    799       // is old enough. Only provided if the paid contract
    800       // has an age restriction and the coin is
    801       // age-restricted.
    802       minimum_age_sig?: EddsaSignature;
    803 
    804       // Age commitment vector of the coin.
    805       // Only provided if the paid contract
    806       // has an age restriction and the coin is
    807       // age-restricted.
    808       age_commitment?: Edx25519PublicKey[];
    809 
    810       // Hash over the agge commitment vector of the coin.
    811       // Only provided if the paid contract
    812       // does NOT have an age restriction and the coin is
    813       // age-restricted.
    814       h_age_commitment?: AgeCommitmentHash;
    815     }
    816 
    817   .. ts:def:: TokenUseSig
    818 
    819     interface TokenUseSig {
    820 
    821       // Signature on ``TALER_TokenUseRequestPS`` with the token use key of
    822       // the token being used in this request.
    823       token_sig: EddsaSignature;
    824 
    825       // Token use public key.
    826       token_pub: EddsaPublicKey;
    827 
    828       // Unblinded signature on ``TALER_TokenIssueRequestPS`` with the token
    829       // issue public key of the merchant.
    830       ub_sig: UnblindedSignature;
    831 
    832       // Hash of the token issue public key associated with this token.
    833       h_issue: HashCode;
    834     }
    835 
    836   .. ts:def:: TokenEnvelope
    837 
    838     // This type depends on the cipher used to sign token families. This is
    839     // configured by the merchant and defined for each token family in the
    840     // contract terms.
    841     type TokenEnvelope = RSATokenEnvelope | CSTokenEnvelope;
    842 
    843   .. ts:def:: RSATokenEnvelope
    844 
    845     interface RSATokenEnvelope {
    846 
    847       // RSA is used for the blind signature.
    848       cipher: "RSA";
    849 
    850       // Blinded signature of the token's `public EdDSA key <eddsa-token-pub>`.
    851       rsa_blinded_pub: BlindedRsaSignature;
    852 
    853     }
    854 
    855   .. ts:def:: CSTokenEnvelope
    856 
    857     interface CSTokenEnvelope {
    858       // Blind Clause-Schnorr signature scheme is used for the blind signature.
    859       // See https://taler.net/papers/cs-thesis.pdf for details.
    860       cipher: "CS";
    861 
    862       // Public nonce
    863       cs_nonce: string;      // Crockford `Base32` encoded
    864 
    865       // Two Curve25519 scalars, each representing a blinded challenge
    866       cs_blinded_c0: string; // Crockford `Base32` encoded
    867       cs_blinded_c1: string; // Crockford `Base32` encoded
    868     }
    869 
    870   .. ts:def:: PaymentDeniedLegallyResponse
    871 
    872     interface PaymentDeniedLegallyResponse {
    873 
    874        // Base URL of the exchanges that denied the payment.
    875        // The wallet should refresh the coins from these
    876        // exchanges, but may try to pay with coins from
    877        // other exchanges.
    878        exchange_base_urls: string[];
    879 
    880     }
    881 
    882 
    883 Querying payment status
    884 ^^^^^^^^^^^^^^^^^^^^^^^
    885 
    886 .. http:get:: [/instances/$INSTANCE]/orders/$ORDER_ID
    887 
    888   Query the payment status of an order. This endpoint is for the wallet
    889   and possibly for Web shops and other integrations that need an
    890   unauthenticated way to query the order status (like when checking
    891   it from JavaScript from inside the customer's browser). It is also
    892   possible to just redirect a browser to this URL to initiate the
    893   payment process.
    894 
    895   When a client (usually a wallet) goes to this URL and it is unpaid,
    896   it will be prompted for payment.
    897   This endpoint typically also supports requests with the "Accept" header
    898   requesting "text/html".  In this case, an HTML response suitable for
    899   triggering the interaction with the wallet is returned, with ``timeout_ms``
    900   ignored (treated as zero). If the backend installation does not include the
    901   required HTML templates, a 406 status code is returned.
    902 
    903   In the case that the request was made with a claim token (even the wrong one)
    904   and the order was claimed and paid, the server will redirect the client to
    905   the fulfillment URL.  This redirection will happen with a 302 status code
    906   if the "Accept" header specified "text/html", and with a 202 status code
    907   otherwise.
    908 
    909   **Request:**
    910 
    911   :query h_contract=HASH: *Optional*. Hash of the order's contract terms (this is used to authenticate the wallet/customer in case $ORDER_ID is guessable). Required once an order was claimed.
    912   :query token=TOKEN: *Optional*. Authorizes the request via the claim token that was returned in the `PostOrderResponse`.  Used with unclaimed orders only. Whether token authorization is required is determined by the merchant when the frontend creates the order.
    913   :query session_id=STRING: *Optional*. Session ID that the payment must be bound to.  If not specified, the payment is not session-bound.
    914   :query timeout_ms=NUMBER: *Optional.*  If specified, the merchant backend will
    915     wait up to ``timeout_ms`` milliseconds for completion of the payment before
    916     sending the HTTP response.  A client must never rely on this behavior, as the
    917     merchant backend may return a response immediately.
    918   :query await_refund_obtained=BOOLEAN: *Optional*. If set to "yes", poll for the order's pending refunds to be picked up.  ``timeout_ms`` specifies how long we will wait for the refund.
    919   :query refund=AMOUNT: *Optional*. Indicates that we are polling for a refund above the given AMOUNT. ``timeout_ms`` will specify how long we will wait for the refund.
    920   :query allow_refunded_for_repurchase: *Optional*. Since protocol **v9** refunded orders are only returned under "already_paid_order_id" if this flag is set explicitly to "YES".
    921 
    922   **Response:**
    923 
    924   :http:statuscode:`200 OK`:
    925     The response is a `StatusPaidResponse`.
    926   :http:statuscode:`202 Accepted`:
    927     The response is a `StatusGotoResponse`. Only returned if the content type requested was not HTML.
    928     The target site may allow the client to setup a fresh order (as this one has been taken) or may
    929     trigger repurchase detection.
    930   :http:statuscode:`302 Found`:
    931     The client should go to the indicated location (via HTTP "Location:" header).
    932     Only returned if the content type requested was HTML.
    933     The target site may allow the client to setup a fresh order (as this one has been taken) or may
    934     trigger repurchase detection.
    935   :http:statuscode:`402 Payment required`:
    936     The response is a `StatusUnpaidResponse`.
    937   :http:statuscode:`403 Forbidden`:
    938     The ``h_contract`` (or the ``token`` for unclaimed orders) does not match the order
    939     and we have no fulfillment URL in the contract.
    940   :http:statuscode:`404 Not found`:
    941     The merchant backend is unaware of the order.
    942   :http:statuscode:`406 Not acceptable`:
    943     The merchant backend could not load the template required to generate a reply in the desired format. (Likely HTML templates were not properly installed.)
    944 
    945   **Details:**
    946 
    947   .. ts:def:: StatusPaidResponse
    948 
    949     interface StatusPaidResponse {
    950       // Was the payment refunded (even partially, via refund or abort)?
    951       refunded: boolean;
    952 
    953       // Is any amount of the refund still waiting to be picked up (even partially)?
    954       refund_pending: boolean;
    955 
    956       // Amount that was refunded in total.
    957       refund_amount: Amount;
    958 
    959       // Amount that already taken by the wallet.
    960       refund_taken: Amount;
    961     }
    962 
    963   .. ts:def:: StatusGotoResponse
    964 
    965     interface StatusGotoResponse {
    966       // The client should go to the reorder URL, there a fresh
    967       // order might be created as this one is taken by another
    968       // customer or wallet (or repurchase detection logic may
    969       // apply).
    970       public_reorder_url: string;
    971     }
    972 
    973   .. ts:def:: StatusUnpaidResponse
    974 
    975     interface StatusUnpaidResponse {
    976       // URI that the wallet must process to complete the payment.
    977       taler_pay_uri: string;
    978 
    979       // Fulfillment URL of the contract.
    980       // If present, it should be possible to create an
    981       // equivalent order by redirecting a browser to this
    982       // URL. Once the customer has paid, they should see the
    983       // order's fulfillment (digital goods, tracking data for
    984       // shipping, etc.) under this URL (assuming they use the
    985       // same session that the wallet used when making the payment).
    986       fulfillment_url?: string;
    987 
    988       // Alternative order ID which was paid for already in the same session.
    989       // Only given if the same product was purchased before in the same session.
    990       already_paid_order_id?: string;
    991     }
    992 
    993 
    994 
    995 Demonstrating payment
    996 ^^^^^^^^^^^^^^^^^^^^^
    997 
    998 In case a wallet has already paid for an order, this is a fast way of proving
    999 to the merchant that the order was already paid. The alternative would be to
   1000 replay the original payment, but simply providing the merchant's signature
   1001 saves bandwidth and computation time.
   1002 
   1003 Demonstrating payment is useful in case a digital good was made available
   1004 only to clients with a particular session ID: if that session ID expired or
   1005 if the user is using a different client, demonstrating payment will allow
   1006 the user to regain access to the digital good without having to pay for it
   1007 again.
   1008 
   1009 .. http:post:: [/instances/$INSTANCE]/orders/$ORDER_ID/paid
   1010 
   1011   Prove that the client previously paid for an order by providing
   1012   the merchant's signature from the `payment response <PaymentResponse>`.
   1013   Typically used by the customer's wallet if it receives a request for
   1014   payment for an order that it already paid. This is more compact than
   1015   re-transmitting the full payment details.
   1016   Note that this request does include the
   1017   usual ``h_contract`` argument to authenticate the wallet and
   1018   to allow the merchant to verify the signature before checking
   1019   with its own database.
   1020 
   1021   **Request:**
   1022 
   1023   The request must be a `paid request <PaidRequest>`.
   1024 
   1025   **Response:**
   1026 
   1027   :http:statuscode:`200 Ok`:
   1028     The merchant accepted the signature.
   1029     The ``frontend`` should now fulfill the contract.
   1030     Note that it is possible that refunds have been granted.  Response is of type `PaidRefundStatusResponse`.
   1031   :http:statuscode:`400 Bad request`:
   1032     Either the client request is malformed or some specific processing error
   1033     happened that may be the fault of the client as detailed in the JSON body
   1034     of the response.
   1035   :http:statuscode:`403 Forbidden`:
   1036     The signature was not valid.
   1037   :http:statuscode:`404 Not found`:
   1038     The merchant backend could not find the order or the instance
   1039     and thus cannot process the request.
   1040 
   1041   **Details**:
   1042 
   1043   .. ts:def:: PaidRefundStatusResponse
   1044 
   1045     interface PaidRefundStatusResponse {
   1046 
   1047       // Text to be shown to the point-of-sale staff as a proof of
   1048       // payment (present only if re-usable OTP algorithm is used).
   1049       pos_confirmation?: string;
   1050 
   1051       // True if the order has been subjected to
   1052       // refunds. False if it was simply paid.
   1053       refunded: boolean;
   1054     }
   1055 
   1056   .. ts:def:: PaidRequest
   1057 
   1058     interface PaidRequest {
   1059       // Signature on ``TALER_PaymentResponsePS`` with the public
   1060       // key of the merchant instance.
   1061       sig: EddsaSignature;
   1062 
   1063       // Hash of the order's contract terms (this is used to authenticate the
   1064       // wallet/customer and to enable signature verification without
   1065       // database access).
   1066       h_contract: HashCode;
   1067 
   1068       // Session id for which the payment is proven.
   1069       session_id: string;
   1070     }
   1071 
   1072 
   1073 Aborting incomplete payments
   1074 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   1075 
   1076 In rare cases (such as a wallet restoring from an outdated backup) it is possible
   1077 that a wallet fails to complete a payment because it runs out of e-cash in the
   1078 middle of the process. The abort API allows the wallet to abort the payment for
   1079 such an incomplete payment and to regain control over the coins that were spent
   1080 so far. Aborts are not permitted for payments that have completed.  In contrast to
   1081 refunds, aborts do not require approval by the merchant because aborts always
   1082 are for incomplete payments for an order and never for established contracts.
   1083 
   1084 
   1085 .. _order-abort:
   1086 .. http:post:: [/instances/$INSTANCE]/orders/$ORDER_ID/abort
   1087 
   1088   Abort paying for an order and obtain a refund for coins that
   1089   were already deposited as part of a failed payment.
   1090 
   1091   **Request:**
   1092 
   1093   The request must be an `abort request <AbortRequest>`.  We force the wallet
   1094   to specify the affected coins as it may only request for a subset of the coins
   1095   (i.e. because the wallet knows that some were double-spent causing the failure).
   1096   Also we need to know the coins because there may be two wallets "competing" over
   1097   the same order and one wants to abort while the other still proceeds with the
   1098   payment. Here we need to again know which subset of the deposits to abort.
   1099 
   1100   **Response:**
   1101 
   1102   :http:statuscode:`200 OK`:
   1103     The merchant accepted the request, and passed it on to the exchange. The body is a
   1104     a `abort response <AbortResponse>`. Note that the exchange
   1105     MAY still have encountered errors in processing. Those will then be part of
   1106     the body. Wallets MUST carefully consider errors for each of the coins as
   1107     returned by the exchange.
   1108   :http:statuscode:`400 Bad request`:
   1109     Either the client request is malformed or some specific processing error
   1110     happened that may be the fault of the client as detailed in the JSON body
   1111     of the response.
   1112   :http:statuscode:`403 Forbidden`:
   1113     The ``h_contract`` does not match the $ORDER_ID.
   1114   :http:statuscode:`404 Not found`:
   1115     The merchant backend could not find the order or the instance
   1116     and thus cannot process the abort request.
   1117   :http:statuscode:`408 Request timeout`:
   1118     The merchant backend took too long getting a response from the exchange.
   1119     The wallet SHOULD retry soon.
   1120   :http:statuscode:`412 Precondition failed`:
   1121     Aborting the payment is not allowed, as the original payment did succeed.
   1122     It is possible that a different wallet succeeded with the payment. This
   1123     wallet should thus try to refresh all of the coins involved in the payment.
   1124   :http:statuscode:`502 Bad gateway`:
   1125     The merchant's interaction with the exchange failed in some way.
   1126     The error from the exchange is included.
   1127   :http:statuscode:`504 Gateway timeout`:
   1128     The merchant's interaction with the exchange took too long.
   1129     The client might want to try again later.
   1130 
   1131   The backend will return an `abort response <AbortResponse>`, which includes
   1132   verbatim the error codes received from the exchange's
   1133   :ref:`refund <exchange_refund>` API.  The frontend should pass the replies verbatim to
   1134   the browser/wallet.
   1135 
   1136   **Details:**
   1137 
   1138   .. ts:def:: AbortRequest
   1139 
   1140     interface AbortRequest {
   1141 
   1142       // Hash of the order's contract terms (this is used to authenticate the
   1143       // wallet/customer in case $ORDER_ID is guessable).
   1144       h_contract: HashCode;
   1145 
   1146       // List of coins the wallet would like to see refunds for.
   1147       // (Should be limited to the coins for which the original
   1148       // payment succeeded, as far as the wallet knows.)
   1149       coins: AbortingCoin[];
   1150     }
   1151 
   1152   .. ts:def:: AbortingCoin
   1153 
   1154     interface AbortingCoin {
   1155       // Public key of a coin for which the wallet is requesting an abort-related refund.
   1156       coin_pub: EddsaPublicKey;
   1157 
   1158       // The amount to be refunded (matches the original contribution)
   1159       // @Deprecated since **v18**.
   1160       contribution: Amount;
   1161 
   1162       // URL of the exchange this coin was withdrawn from.
   1163       exchange_url: string;
   1164     }
   1165 
   1166 
   1167   .. ts:def:: AbortResponse
   1168 
   1169     interface AbortResponse {
   1170 
   1171       // List of refund responses about the coins that the wallet
   1172       // requested an abort for.  In the same order as the ``coins``
   1173       // from the original request.
   1174       // The ``rtransaction_id`` is implied to be 0.
   1175       refunds: MerchantAbortPayRefundStatus[];
   1176     }
   1177 
   1178   .. ts:def:: MerchantAbortPayRefundStatus
   1179 
   1180     type MerchantAbortPayRefundStatus =
   1181       | MerchantAbortPayRefundSuccessStatus
   1182       | MerchantAbortPayRefundUndepositedStatus
   1183       | MerchantAbortPayRefundFailureStatus;
   1184 
   1185   .. ts:def:: MerchantAbortPayRefundFailureStatus
   1186 
   1187     // Details about why a refund failed.
   1188     interface MerchantAbortPayRefundFailureStatus {
   1189       // Used as tag for the sum type RefundStatus sum type.
   1190       type: "failure";
   1191 
   1192       // HTTP status of the exchange request, must NOT be 200.
   1193       exchange_status: Integer;
   1194 
   1195       // Taler error code from the exchange reply, if available.
   1196       exchange_code?: Integer;
   1197 
   1198       // If available, HTTP reply from the exchange.
   1199       exchange_reply?: Object;
   1200     }
   1201 
   1202   .. ts:def:: MerchantAbortPayRefundSuccessStatus
   1203 
   1204     // Additional details needed to verify the refund confirmation signature
   1205     // (``h_contract_terms`` and ``merchant_pub``) are already known
   1206     // to the wallet and thus not included.
   1207     interface MerchantAbortPayRefundSuccessStatus {
   1208       // Used as tag for the sum type MerchantCoinRefundStatus sum type.
   1209       type: "success";
   1210 
   1211       // HTTP status of the exchange request, 200 (integer) required for refund confirmations.
   1212       exchange_status: 200;
   1213 
   1214       // The EdDSA :ref:`signature` (binary-only) with purpose
   1215       // `TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND` using a current signing key of the
   1216       // exchange affirming the successful refund.
   1217       exchange_sig: EddsaSignature;
   1218 
   1219       // Public EdDSA key of the exchange that was used to generate the signature.
   1220       // Should match one of the exchange's signing keys from ``/keys``.  It is given
   1221       // explicitly as the client might otherwise be confused by clock skew as to
   1222       // which signing key was used.
   1223       exchange_pub: EddsaPublicKey;
   1224     }
   1225 
   1226   .. ts:def:: MerchantAbortPayRefundUndepositedStatus
   1227 
   1228     // The merchant didn't deposit the coin in the first place,
   1229     // no refund possible.
   1230     interface MerchantAbortPayRefundSuccessStatus {
   1231       // Used as tag for the sum type MerchantCoinRefundStatus sum type.
   1232       type: "undeposited";
   1233     }
   1234 
   1235 
   1236 Obtaining refunds
   1237 ^^^^^^^^^^^^^^^^^
   1238 
   1239 Refunds allow merchants to fully or partially restitute e-cash to a wallet,
   1240 for example because the merchant determined that it could not actually fulfill
   1241 the contract. Refunds must be approved by the merchant's business logic.
   1242 
   1243 
   1244 .. http:post:: [/instances/$INSTANCE]/orders/$ORDER_ID/refund
   1245 
   1246   Obtain refunds for an order. After talking to the exchange, the refunds will
   1247   no longer be pending if processed successfully.
   1248 
   1249   **Request:**
   1250 
   1251   The request body is a `WalletRefundRequest` object.
   1252 
   1253   **Response:**
   1254 
   1255   :http:statuscode:`200 OK`:
   1256     The response is a `WalletRefundResponse`.
   1257   :http:statuscode:`204 No content`:
   1258     There are no refunds for the order.
   1259   :http:statuscode:`403 Forbidden`:
   1260     The ``h_contract`` does not match the order.
   1261   :http:statuscode:`404 Not found`:
   1262     The merchant backend is unaware of the order.
   1263   :http:statuscode:`410 Gone`:
   1264     The wire deadline has past and it is too late to grant a refund.
   1265     Since protocol **v24**.
   1266   :http:statuscode:`451 Unavailable for Legal Reasons`:
   1267     The refund could not be awarded because of legal
   1268     reasons (an exchange refused). The wallet should
   1269     show an error message and suggest to the user to
   1270     get in touch with the merchant to try to get the
   1271     refund in a different way.
   1272     The body is a `PaymentDeniedLegallyResponse` with
   1273     details about the exchange causing the failure.
   1274     Since protocol **v17**.
   1275 
   1276   **Details:**
   1277 
   1278   .. ts:def:: WalletRefundRequest
   1279 
   1280     interface WalletRefundRequest {
   1281       // Hash of the order's contract terms (this is used to authenticate the
   1282       // wallet/customer).
   1283       h_contract: HashCode;
   1284     }
   1285 
   1286   .. ts:def:: WalletRefundResponse
   1287 
   1288     interface WalletRefundResponse {
   1289       // Amount that was refunded in total.
   1290       refund_amount: Amount;
   1291 
   1292       // Successful refunds for this payment, empty array for none.
   1293       refunds: MerchantCoinRefundStatus[];
   1294 
   1295       // Public key of the merchant.
   1296       merchant_pub: EddsaPublicKey;
   1297 
   1298     }
   1299 
   1300   .. ts:def:: MerchantCoinRefundStatus
   1301 
   1302     type MerchantCoinRefundStatus =
   1303       | MerchantCoinRefundSuccessStatus
   1304       | MerchantCoinRefundFailureStatus;
   1305 
   1306   .. ts:def:: MerchantCoinRefundFailureStatus
   1307 
   1308     // Details about why a refund failed.
   1309     interface MerchantCoinRefundFailureStatus {
   1310       // Used as tag for the sum type RefundStatus sum type.
   1311       type: "failure";
   1312 
   1313       // HTTP status of the exchange request, must NOT be 200.
   1314       exchange_status: Integer;
   1315 
   1316       // Taler error code from the exchange reply, if available.
   1317       exchange_code?: Integer;
   1318 
   1319       // If available, HTTP reply from the exchange.
   1320       exchange_reply?: Object;
   1321 
   1322       // Refund transaction ID.
   1323       rtransaction_id: Integer;
   1324 
   1325       // Public key of a coin that was refunded.
   1326       coin_pub: EddsaPublicKey;
   1327 
   1328       // Amount that was refunded, including refund fee charged by the exchange
   1329       // to the customer.
   1330       refund_amount: Amount;
   1331 
   1332       // Timestamp when the merchant approved the refund.
   1333       // Useful for grouping refunds.
   1334       execution_time: Timestamp;
   1335     }
   1336 
   1337   .. ts:def:: MerchantCoinRefundSuccessStatus
   1338 
   1339     // Additional details needed to verify the refund confirmation signature
   1340     // (``h_contract_terms`` and ``merchant_pub``) are already known
   1341     // to the wallet and thus not included.
   1342     interface MerchantCoinRefundSuccessStatus {
   1343       // Used as tag for the sum type MerchantCoinRefundStatus sum type.
   1344       type: "success";
   1345 
   1346       // HTTP status of the exchange request, 200 (integer) required for refund confirmations.
   1347       exchange_status: 200;
   1348 
   1349       // The EdDSA :ref:`signature` (binary-only) with purpose
   1350       // `TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND` using a current signing key of the
   1351       // exchange affirming the successful refund.
   1352       exchange_sig: EddsaSignature;
   1353 
   1354       // Public EdDSA key of the exchange that was used to generate the signature.
   1355       // Should match one of the exchange's signing keys from /keys.  It is given
   1356       // explicitly as the client might otherwise be confused by clock skew as to
   1357       // which signing key was used.
   1358       exchange_pub: EddsaPublicKey;
   1359 
   1360       // Refund transaction ID.
   1361       rtransaction_id: Integer;
   1362 
   1363       // Public key of a coin that was refunded.
   1364       coin_pub: EddsaPublicKey;
   1365 
   1366       // Amount that was refunded, including refund fee charged by the exchange
   1367       // to the customer.
   1368       refund_amount: Amount;
   1369 
   1370       // Timestamp when the merchant approved the refund.
   1371       // Useful for grouping refunds.
   1372       execution_time: Timestamp;
   1373     }
   1374 
   1375 
   1376 -------------------
   1377 Instance management
   1378 -------------------
   1379 
   1380 Instances allow one merchant backend to be shared by multiple merchants.
   1381 Every backend must have at least one instance, typically the "admin"
   1382 instance setup before it can be used to manage inventory or process payments.
   1383 
   1384 
   1385 Setting up instances
   1386 ^^^^^^^^^^^^^^^^^^^^
   1387 
   1388 .. http:post:: /instances
   1389 
   1390   This request will be used to create a new merchant instance in the backend.
   1391   Since protocol **v21**.
   1392 
   1393   Only available if self-provisioning is enabled.
   1394 
   1395   **Required permission:** none
   1396 
   1397   **Request:**
   1398 
   1399   The request must be a `InstanceConfigurationMessage`.
   1400 
   1401   :query token_validity_ms=DURATION: *Optional*.
   1402     Pass a non-zero DURATION in milliseconds to get a
   1403     refreshable login token for the SPA with the
   1404     given validity duration in the response.  @since **v21**.
   1405 
   1406   **Response:**
   1407 
   1408   :http:statuscode:`200 Ok`:
   1409     The backend has successfully created the instance. Body will
   1410     be an `LoginTokenSuccessResponse` with a refreshable
   1411     login token for the SPA as requested. @since **v21**.
   1412   :http:statuscode:`202 Accepted`:
   1413     2FA is required for this operation, usually to validate the
   1414     email and/or phone numbers provided for the instance.
   1415     This returns the `ChallengeResponse`. @since **v21**
   1416   :http:statuscode:`204 No Content`:
   1417     The backend has successfully created the instance. No login
   1418     token was requested, so nothing is returned.
   1419   :http:statuscode:`409 Conflict`:
   1420     This instance already exists, but with other configuration options.
   1421     Use "PATCH" to update an instance configuration. Alternatively,
   1422     the currency provided in the configuration does not match the
   1423     currency supported by this backend. Another possible conflict
   1424     would be if a deleted but not purged instance is known under this
   1425     ID to the backend.
   1426 
   1427 
   1428 .. http:post:: /instances/$INSTANCE/forgot-password
   1429 
   1430   Same as ``/management/instances/$INSTANCE/private/auth`` it will update the password of the instance but
   1431   without requiring the current password. On the first call it will validate the request
   1432   and return the multi-factor authentication challenge IDs with
   1433   a ``202 Accepted`` response. Once the challenges are solved the
   1434   request needs to be repeated with the ``Taler-Challenge-Ids`` header.
   1435 
   1436   This endpoint is **not** available for the ``admin`` instance.
   1437   The administrator must use the command-line tool if they forgot
   1438   their password.
   1439 
   1440   Since protocol **v21**
   1441 
   1442   **Request** the request must be an `InstanceAuthConfigurationMessage`.
   1443 
   1444   **Response:**
   1445 
   1446   :http:statuscode:`202 Accepted`:
   1447     2FA is required for this operation. This returns
   1448     the `ChallengeResponse`. @since **v21**
   1449   :http:statuscode:`204 No content`:
   1450     The backend has successfully changed the credentials for the instance.
   1451   :http:statuscode:`404 Not found`:
   1452     This instance is unknown and thus cannot be reconfigured.
   1453 
   1454 
   1455 .. http:post:: /management/instances
   1456 
   1457   This request will be used to create a new merchant instance in the backend.
   1458   It is only available for the implicit ``admin`` instance.
   1459 
   1460   **Required permission:** ``instances-write``
   1461 
   1462   **Request:**
   1463 
   1464   The request must be a `InstanceConfigurationMessage`.
   1465 
   1466   **Response:**
   1467 
   1468   :http:statuscode:`202 Accepted`:
   1469     2FA is required for this operation, usually to validate the
   1470     email and/or phone numbers registered for the instance.
   1471     This returns the `ChallengeResponse`. @since **v21**
   1472   :http:statuscode:`204 No content`:
   1473     The backend has successfully created the instance.
   1474   :http:statuscode:`409 Conflict`:
   1475     This instance already exists, but with other configuration options.
   1476     Use "PATCH" to update an instance configuration. Alternatively,
   1477     the currency provided in the configuration does not match the
   1478     currency supported by this backend. Another possible conflict
   1479     would be if a deleted but not purged instance is known under this
   1480     ID to the backend.
   1481 
   1482   **Details:**
   1483 
   1484   .. ts:def:: InstanceConfigurationMessage
   1485 
   1486     interface InstanceConfigurationMessage {
   1487 
   1488       // Name of the merchant instance to create (will become $INSTANCE).
   1489       // Must match the regex ``^[A-Za-z0-9][A-Za-z0-9_.@-]+$``.
   1490       id: string;
   1491 
   1492       // Merchant name corresponding to this instance.
   1493       name: string;
   1494 
   1495       // Merchant email for customer contact and password reset.
   1496       email?: string;
   1497 
   1498       // Merchant phone number for password reset (2-FA)
   1499       // @since **v21**.
   1500       phone_number?: string;
   1501 
   1502       // Merchant public website.
   1503       website?: string;
   1504 
   1505       // Merchant logo.
   1506       logo?: ImageDataUrl;
   1507 
   1508       // Authentication settings for this instance
   1509       auth: InstanceAuthConfigurationMessage;
   1510 
   1511       // The merchant's physical address (to be put into contracts).
   1512       address: Location;
   1513 
   1514       // The jurisdiction under which the merchant conducts its business
   1515       // (to be put into contracts).
   1516       jurisdiction: Location;
   1517 
   1518       // Use STEFAN curves to determine default fees?
   1519       // If false, no fees are allowed by default.
   1520       // Can always be overridden by the frontend on a per-order basis.
   1521       use_stefan: boolean;
   1522 
   1523       // If the frontend does NOT specify a payment deadline, how long should
   1524       // offers we make be valid by default?
   1525       // Optional @since **v22** (before the setting was mandatory).
   1526       // If not provided, the global merchant default will be used.
   1527       default_pay_delay?: RelativeTime;
   1528 
   1529       // If the frontend does NOT specify a refund deadline, how long should
   1530       // refunds be allowed by default? Added on top of the
   1531       // payment deadline.
   1532       // @since **v22**
   1533       default_refund_delay?: RelativeTime;
   1534 
   1535       // If the frontend does NOT specify an execution date, how long should
   1536       // we tell the exchange to wait to aggregate transactions before
   1537       // executing the wire transfer?  This delay is added on top of
   1538       // the refund deadline and afterwards subject to rounding
   1539       // via the ``default_wire_transfer_rounding_interval``.
   1540       // Optional @since **v22** (before the setting was mandatory).
   1541       // If not provided, the global merchant default will be used.
   1542       default_wire_transfer_delay?: RelativeTime;
   1543 
   1544       // How far should the wire deadline (if computed with the help of
   1545       // the ``default_wire_transfer_delay``) be rounded up to compute
   1546       // the ultimate wire deadline?
   1547       // @since **v22**, defaults to no rounding if not given.
   1548       default_wire_transfer_rounding_interval?: RoundingInterval;
   1549     }
   1550 
   1551 .. http:post:: /management/instances/$INSTANCE/auth
   1552 .. http:post:: [/instances/$INSTANCE]/private/auth
   1553 
   1554   Update the authentication settings for an instance.  POST operations against
   1555   an instance are authenticated by checking that an authorization is provided
   1556   that matches either the credential required by the instance being modified
   1557   OR the ``admin`` instance, depending on the access path used.
   1558 
   1559   **Required permission:** ``instances-auth-write``
   1560 
   1561   **Request** the request must be an `InstanceAuthConfigurationMessage`.
   1562 
   1563   **Response:**
   1564 
   1565   :http:statuscode:`202 Accepted`:
   1566     2FA is required for this operation. This returns the `ChallengeResponse` response. @since **v21**
   1567   :http:statuscode:`204 No content`:
   1568     The backend has successfully changed the credentials for the instance.
   1569   :http:statuscode:`404 Not found`:
   1570     This instance is unknown and thus cannot be reconfigured.
   1571 
   1572   **Details:**
   1573 
   1574   .. ts:def:: InstanceAuthConfigurationMessage
   1575 
   1576     type InstanceAuthConfigurationMessage = InstanceAuthConfigToken | InstanceAuthConfigTokenOLD | InstanceAuthConfigExternal
   1577 
   1578   .. ts:def:: InstanceAuthConfigToken
   1579 
   1580     // @since **v19**
   1581     interface InstanceAuthConfigToken {
   1582       // The API is accessible through API tokens.
   1583       // Tokens are retrieved from the /private/token
   1584       // endpoint.
   1585       method: "token";
   1586 
   1587       // Authentication against the /private/token endpoint
   1588       // is done using basic authentication with the configured password
   1589       // in the "password" field. Tokens are passed to other endpoints for
   1590       // authorization using RFC 8959 bearer tokens.
   1591       password: string;
   1592 
   1593     }
   1594 
   1595   .. ts:def:: InstanceAuthConfigTokenOLD
   1596 
   1597     // @deprecated since **v19**
   1598     interface InstanceAuthConfigTokenOLD {
   1599       // The API is accessible through API tokens.
   1600       // Tokens are retrieved from the /private/token
   1601       // endpoint.
   1602       method: "token";
   1603 
   1604       // The value of this field MUST begin with the string "secret-token:".
   1605       token: string;
   1606 
   1607     }
   1608 
   1609   .. ts:def:: InstanceAuthConfigExternal
   1610 
   1611     // @deprecated since **v20**
   1612     interface InstanceAuthConfigExternal {
   1613       // The mechant backend does not do
   1614       // any authentication checks.  Instead an API
   1615       // gateway must do the authentication.
   1616       method: "external";
   1617     }
   1618 
   1619 
   1620 .. http:post:: [/instances/$INSTANCE]/private/token
   1621 
   1622   Retrieve an access token for the merchant API for instance
   1623   ``$INSTANCE``.
   1624   When accessed with a Bearer token for authentication, the token
   1625   must have scope ``token-refresh`` and the requested scope must be a subset
   1626   of the scope of the token.
   1627   When accessed with Basic authentication the instance password must be provided
   1628   along with ``$INSTANCE`` as username.
   1629 
   1630 
   1631   **Required permission:** ``token-refresh`` if accessed using a Bearer token.
   1632 
   1633   **Request:**
   1634 
   1635   The request must be a `LoginTokenRequest`.
   1636 
   1637   **Response:**
   1638 
   1639   :http:statuscode:`200 Ok`:
   1640     The backend is returning the access token in a
   1641     `LoginTokenSuccessResponse`.
   1642   :http:statuscode:`202 Accepted`:
   1643     2FA is required for this operation.
   1644     This returns the `ChallengeResponse`. @since **v21**
   1645 
   1646   **Details:**
   1647 
   1648   .. ts:def:: LoginTokenRequest
   1649 
   1650     interface LoginTokenRequest {
   1651       // Scope of the token (which kinds of operations it will allow)
   1652       scope: "readonly" | "write" | "all" | "order-simple" | "order-pos" | "order-mgmt" | "order-full";
   1653 
   1654       // Server may impose its own upper bound
   1655       // on the token validity duration
   1656       duration?: RelativeTime;
   1657 
   1658       // Optional token description
   1659       description?: string;
   1660 
   1661       // Can this token be refreshed?
   1662       // Defaults to false. Deprecated since **v19**.
   1663       // Use ":refreshable" scope prefix instead.
   1664       refreshable?: boolean;
   1665     }
   1666 
   1667   .. ts:def:: LoginTokenSuccessResponse
   1668 
   1669     interface LoginTokenSuccessResponse {
   1670       // deprecated since v19. See access_token
   1671       token: string;
   1672 
   1673       // The login token that can be used to access resources
   1674       // that are in scope for some time. Must be prefixed
   1675       // with "Bearer " when used in the "Authorization" HTTP header.
   1676       // Will already begin with the RFC 8959 prefix.
   1677       // **Since v19**
   1678       access_token: string;
   1679 
   1680       // Scope of the token (which kinds of operations it will allow)
   1681       scope: "readonly" | "write" | "all" | "order-simple" | "order-pos" | "order-mgmt" | "order-full";
   1682 
   1683       // Server may impose its own upper bound
   1684       // on the token validity duration
   1685       expiration: Timestamp;
   1686 
   1687       // Can this token be refreshed?
   1688       refreshable: boolean;
   1689     }
   1690 
   1691 .. http:get:: [/instances/$INSTANCE]/private/tokens
   1692 
   1693   Retrieve a list of issued access tokens for ``$INSTANCE``.
   1694 
   1695   @since **v19**
   1696 
   1697   **Required permission**: ``tokens-read``
   1698 
   1699   **Request:**
   1700 
   1701   :query limit: *Optional.*
   1702     At most return the given number of results. Negative for descending by ``serial``, positive for ascending by ``serial``. Defaults to ``-20``.
   1703   :query offset: *Optional.*
   1704     Starting ``serial`` for :ref:`pagination <row-id-pagination>`.
   1705 
   1706   **Response:**
   1707 
   1708   :http:statuscode:`200 OK`:
   1709     Response is a `TokenInfos`.
   1710   :http:statuscode:`204 No content`:
   1711     No tokens.
   1712   :http:statuscode:`401 Unauthorized`:
   1713     Invalid or missing credentials.
   1714   :http:statuscode:`403 Forbidden`:
   1715     Missing rights.
   1716 
   1717   **Details:**
   1718 
   1719   .. ts:def:: TokenInfos
   1720 
   1721     interface TokenInfos {
   1722       tokens: TokenInfo[];
   1723     }
   1724 
   1725   .. ts:def:: TokenInfo
   1726 
   1727     interface TokenInfo {
   1728       // Time when the token was created.
   1729       creation_time: Timestamp;
   1730 
   1731       // Time when the token expires.
   1732       expiration: Timestamp;
   1733 
   1734       // Scope for the token.
   1735       scope: "readonly" | "readwrite" | ...;
   1736 
   1737       // Is the token refreshable into a new token during its
   1738       // validity?
   1739       // Refreshable tokens effectively provide indefinite
   1740       // access if they are refreshed in time.
   1741       refreshable: boolean;
   1742 
   1743       // Optional token description
   1744       description?: string;
   1745 
   1746       // Opaque unique ID used for pagination.
   1747       serial: Integer;
   1748     }
   1749 
   1750 .. http:delete:: [/instances/$INSTANCE]/private/tokens/$SERIAL
   1751 
   1752   Delete a token for ``$INSTANCE`` API access by its ``$SERIAL``.
   1753 
   1754 
   1755   @since **v19**
   1756 
   1757   **Required permission**: ``tokens-write``
   1758 
   1759   **Response:**
   1760 
   1761   :http:statuscode:`204 No content`:
   1762     Token deleted.
   1763   :http:statuscode:`401 Unauthorized`:
   1764     Invalid or missing credentials.
   1765   :http:statuscode:`403 Forbidden`:
   1766     Missing permission.
   1767   :http:statuscode:`404 Not found`:
   1768     The token was not found.
   1769 
   1770 .. http:delete:: [/instances/$INSTANCE]/private/token
   1771 
   1772    Delete the token presented in the authorization header.
   1773 
   1774   **Response:**
   1775 
   1776   :http:statuscode:`204 No content`:
   1777     The access token used to authorize this request was revoked.
   1778 
   1779 .. http:patch:: /management/instances/$INSTANCE
   1780 .. http:patch:: [/instances/$INSTANCE]/private
   1781 
   1782   Update the configuration of a merchant instance.  PATCH operations against
   1783   an instance are authenticated by checking that an authorization is provided
   1784   that matches either the credential required by the instance being modified
   1785   OR the ``admin`` instance, depending on the access path used.
   1786 
   1787   **Required permission:** ``instances-token-write``
   1788 
   1789   **Request**
   1790 
   1791   The request must be a `InstanceReconfigurationMessage`.
   1792   Removing an existing ``payto_uri`` deactivates
   1793   the account (it will no longer be used for future contracts).
   1794 
   1795   **Response:**
   1796 
   1797   :http:statuscode:`204 No content`:
   1798     The backend has successfully created the instance.
   1799   :http:statuscode:`404 Not found`:
   1800     This instance is unknown and thus cannot be reconfigured.
   1801 
   1802   **Details:**
   1803 
   1804   .. ts:def:: InstanceReconfigurationMessage
   1805 
   1806     interface InstanceReconfigurationMessage {
   1807 
   1808       // Merchant name corresponding to this instance.
   1809       name: string;
   1810 
   1811       // Merchant email for customer contact and password reset.
   1812       email?: string;
   1813 
   1814       // Merchant phone number for password reset (2-FA)
   1815       // @since **v21**.
   1816       phone_number?: string;
   1817 
   1818       // Merchant public website.
   1819       website?: string;
   1820 
   1821       // Merchant logo.
   1822       logo?: ImageDataUrl;
   1823 
   1824       // The merchant's physical address (to be put into contracts).
   1825       address: Location;
   1826 
   1827       // The jurisdiction under which the merchant conducts its business
   1828       // (to be put into contracts).
   1829       jurisdiction: Location;
   1830 
   1831       // Use STEFAN curves to determine default fees?
   1832       // If false, no fees are allowed by default.
   1833       // Can always be overridden by the frontend on a per-order basis.
   1834       use_stefan: boolean;
   1835 
   1836       // If the frontend does NOT specify a payment deadline, how long should
   1837       // offers we make be valid by default?
   1838       // A value of "forever" is not allowed.
   1839       // Optional @since **v22** (before the setting was mandatory).
   1840       // If not provided, the previous setting will now simply be preserved.
   1841       default_pay_delay?: RelativeTime;
   1842 
   1843       // If the frontend does NOT specify a refund deadline, how long should
   1844       // refunds be allowed by default? Added on top of the payment deadline.
   1845       // A value of "forever" is not allowed.
   1846       // @since **v22**
   1847       default_refund_delay?: RelativeTime;
   1848 
   1849       // If the frontend does NOT specify an execution date, how long should
   1850       // we tell the exchange to wait to aggregate transactions before
   1851       // executing the wire transfer?  This delay is added on top of
   1852       // the refund deadline and afterwards subject to rounding
   1853       // via the ``default_wire_transfer_rounding_interval``.
   1854       // A value of "forever" is not allowed.
   1855       // Optional @since **v22** (before the setting was mandatory).
   1856       // If not provided, the previous setting will now simply be preserved.
   1857       default_wire_transfer_delay?: RelativeTime;
   1858 
   1859       // How far should the wire deadline (if computed with the help of
   1860       // the ``default_wire_transfer_delay``) be rounded up to compute
   1861       // the ultimate wire deadline?
   1862       // @since **v22**, defaults to no rounding if not given.
   1863       default_wire_transfer_rounding_interval?: RoundingInterval;
   1864     }
   1865 
   1866 
   1867 Inspecting instances
   1868 ^^^^^^^^^^^^^^^^^^^^
   1869 
   1870 .. _instances:
   1871 .. http:get:: /management/instances
   1872 
   1873   This is used to return the list of all the merchant instances.
   1874   It is only available for the implicit ``admin`` instance.
   1875 
   1876   **Required permission:** ``instances-read``
   1877 
   1878   **Response:**
   1879 
   1880   :http:statuscode:`200 OK`:
   1881     The backend has successfully returned the list of instances stored. Returns
   1882     a `InstancesResponse`.
   1883 
   1884   **Details:**
   1885 
   1886   .. ts:def:: InstancesResponse
   1887 
   1888     interface InstancesResponse {
   1889       // List of instances that are present in the backend (see `Instance`).
   1890       instances: Instance[];
   1891     }
   1892 
   1893   The `Instance` object describes the instance registered with the backend.
   1894   It does not include the full details, only those that usually concern the frontend.
   1895   It has the following structure:
   1896 
   1897   .. ts:def:: Instance
   1898 
   1899     interface Instance {
   1900       // Merchant name corresponding to this instance.
   1901       name: string;
   1902 
   1903       // Merchant public website.
   1904       website?: string;
   1905 
   1906       // Merchant logo.
   1907       logo?: ImageDataUrl;
   1908 
   1909       // Merchant instance this response is about ($INSTANCE).
   1910       id: string;
   1911 
   1912       // Public key of the merchant/instance, in Crockford Base32 encoding.
   1913       merchant_pub: EddsaPublicKey;
   1914 
   1915       // List of the payment targets supported by this instance. Clients can
   1916       // specify the desired payment target in /order requests.  Note that
   1917       // front-ends do not have to support wallets selecting payment targets.
   1918       payment_targets: string[];
   1919 
   1920       // Has this instance been deleted (but not purged)?
   1921       deleted: boolean;
   1922    }
   1923 
   1924 
   1925 .. http:get:: /management/instances/$INSTANCE
   1926 .. http:get:: [/instances/$INSTANCE]/private
   1927 
   1928   This is used to query a specific merchant instance.  GET operations against
   1929   an instance are authenticated by checking that an authorization is provided
   1930   that matches either the credential required by the instance being modified
   1931   OR the ``admin`` instance, depending on the access path used.
   1932 
   1933   This endpoint may be used even when mandatory TAN channels
   1934   were not validated yet.
   1935 
   1936   **Required permission:** ``instances-read``
   1937 
   1938   **Response:**
   1939 
   1940   :http:statuscode:`200 OK`:
   1941     The backend has successfully returned the list of instances stored. Returns
   1942     a `QueryInstancesResponse`.
   1943 
   1944   **Details:**
   1945 
   1946   .. ts:def:: QueryInstancesResponse
   1947 
   1948     interface QueryInstancesResponse {
   1949 
   1950       // Merchant name corresponding to this instance.
   1951       name: string;
   1952 
   1953       // Merchant email for customer contact and password reset.
   1954       email?: string;
   1955 
   1956       // True if the ``email`` address was validated.
   1957       // @since **v21**.
   1958       email_validated?: boolean;
   1959 
   1960       // Merchant phone number for password reset (2-FA)
   1961       // @since **v21**.
   1962       phone_number?: string;
   1963 
   1964       // True if the ``email`` address was validated.
   1965       // @since **v21**.
   1966       phone_validated?: boolean;
   1967 
   1968       // Merchant public website.
   1969       website?: string;
   1970 
   1971       // Merchant logo.
   1972       logo?: ImageDataUrl;
   1973 
   1974       // Public key of the merchant/instance, in Crockford Base32 encoding.
   1975       merchant_pub: EddsaPublicKey;
   1976 
   1977       // The merchant's physical address (to be put into contracts).
   1978       address: Location;
   1979 
   1980       // The jurisdiction under which the merchant conducts its business
   1981       // (to be put into contracts).
   1982       jurisdiction: Location;
   1983 
   1984       // Use STEFAN curves to determine default fees?
   1985       // If false, no fees are allowed by default.
   1986       // Can always be overridden by the frontend on a per-order basis.
   1987       use_stefan: boolean;
   1988 
   1989       // If the frontend does NOT specify a payment deadline, how long should
   1990       // offers we make be valid by default? Added to the order creation
   1991       // time.
   1992       default_pay_delay: RelativeTime;
   1993 
   1994       // If the frontend does NOT specify a refund deadline, how long should
   1995       // refunds be allowed by default? Added to the payment deadline.
   1996       // @since **v22**
   1997       default_refund_delay: RelativeTime;
   1998 
   1999       // If the frontend does NOT specify an execution date, how long should
   2000       // we tell the exchange to wait to aggregate transactions before
   2001       // executing the wire transfer?  This delay is added to the
   2002       // refund deadline and subject to rounding to the
   2003       // ``default_wire_transfer_rounding_interval``.
   2004       default_wire_transfer_delay: RelativeTime;
   2005 
   2006       // Default interval to which wire deadlines computed by
   2007       // adding the wire_transfer_delay on top of the refund
   2008       // deadline should be rounded up to.
   2009       // @since **v23**
   2010       default_wire_transfer_rounding_interval: RoundingInterval;
   2011 
   2012       // Authentication configuration.
   2013       // Does not contain the token when token auth is configured.
   2014       auth: {
   2015         method: "external" | "token";
   2016       };
   2017 
   2018     }
   2019 
   2020 
   2021 Getting statistics
   2022 ^^^^^^^^^^^^^^^^^^
   2023 
   2024 .. http:get:: /management/instances/$INSTANCE/statistics-amount/$SLUG
   2025 .. http:get:: [/instances/$INSTANCE]/private/statistics-amount/$SLUG
   2026 
   2027   This request will return be used to statistics where the
   2028   values are amounts.  All available values for the given
   2029   SLUG will be returned.
   2030   Since protocol **vSTATISTICS**.
   2031 
   2032   **Required permission:** ``statistics-read``
   2033 
   2034   **Request:**
   2035 
   2036   :query by: *Optional*. If set to "BUCKET", only statistics by bucket will be returned. If set to "INTERVAL", only statistics kept by interval will be returned. If not set or set to "ANY", both will be returned.
   2037 
   2038   **Response:**
   2039 
   2040   :http:statuscode:`200 Ok`:
   2041     The body will be a `MerchantStatisticsAmountResponse`
   2042   :http:statuscode:`401 Unauthorized`:
   2043     The request is unauthorized.
   2044   :http:statuscode:`404 Not found`:
   2045     The instance is unknown to the backend.
   2046 
   2047   **Details:**
   2048 
   2049   .. ts:def:: MerchantStatisticsAmountResponse
   2050 
   2051     interface MerchantStatisticsAmountResponse {
   2052 
   2053       // Statistics kept for a particular fixed time window.
   2054       buckets: MerchantStatisticAmountByBucket[];
   2055 
   2056       // Human-readable bucket statistic description.
   2057       // Unset if no buckets returned
   2058       buckets_description?: string;
   2059 
   2060       // Statistics kept for a particular sliding interval.
   2061       intervals: MerchantStatisticAmountByInterval[];
   2062 
   2063       // Human-readable interval statistic description.
   2064       // Unset if no buckets returned
   2065       intervals_description?: string;
   2066     }
   2067 
   2068   .. ts:def:: MerchantStatisticAmountByBucket
   2069 
   2070     interface MerchantStatisticAmountByBucket {
   2071 
   2072        // Start time of the bucket (inclusive)
   2073        start_time: Timestamp;
   2074 
   2075        // End time of the bucket (exclusive)
   2076        end_time: Timestamp;
   2077 
   2078        // Range of the bucket
   2079        range: StatisticBucketRange;
   2080 
   2081        // Sum of all amounts falling under the given
   2082        // SLUG within this timeframe.
   2083        cumulative_amounts: Amount[];
   2084 
   2085     }
   2086 
   2087   .. ts:def:: MerchantStatisticAmountByInterval
   2088 
   2089     interface MerchantStatisticAmountByInterval {
   2090 
   2091        // Start time of the interval.
   2092        // The interval always ends at the response
   2093        // generation time.
   2094        start_time: Timestamp;
   2095 
   2096        // Sum of all amounts falling under the given
   2097        // SLUG within this timeframe.
   2098        cumulative_amounts: Amount[];
   2099 
   2100     }
   2101 
   2102 .. http:get:: /management/instances/$INSTANCE/statistics-counter/$SLUG
   2103 .. http:get:: [/instances/$INSTANCE]/private/statistics-counter/$SLUG
   2104 
   2105   This request will return be used to statistics where the
   2106   values are counters.  All available values for the given
   2107   SLUG will be returned.
   2108   Since protocol **vSTATISTICS**.
   2109 
   2110   **Required permission:** ``statistics-read``
   2111 
   2112   **Request:**
   2113 
   2114     :query by: *Optional*. If set to "BUCKET", only statistics by bucket will be returned. If set to "INTERVAL", only statistics kept by interval will be returned. If not set or set to "ANY", both will be returned.
   2115 
   2116   **Response:**
   2117 
   2118   :http:statuscode:`200 Ok`:
   2119     The body will be a `MerchantStatisticsCounterResponse`
   2120   :http:statuscode:`401 Unauthorized`:
   2121     The request is unauthorized.
   2122   :http:statuscode:`404 Not found`:
   2123     The instance is unknown to the backend.
   2124 
   2125   **Details:**
   2126 
   2127   .. ts:def:: MerchantStatisticsCounterResponse
   2128 
   2129     interface MerchantStatisticsCounterResponse {
   2130 
   2131       // Statistics kept for a particular fixed time window.
   2132       buckets: MerchantStatisticCounterByBucket[];
   2133 
   2134       // Human-readable bucket statistic description.
   2135       // Unset if no buckets returned
   2136       buckets_description?: string;
   2137 
   2138       // Statistics kept for a particular sliding interval.
   2139       intervals: MerchantStatisticCounterByInterval[];
   2140 
   2141       // Human-readable interval statistic description.
   2142       // Unset if no intervals returned
   2143       intervals_description?: string;
   2144 
   2145     }
   2146 
   2147   .. ts:def:: MerchantStatisticCounterByBucket
   2148 
   2149     interface MerchantStatisticCounterByBucket {
   2150 
   2151       // Start time of the bucket (inclusive)
   2152       start_time: Timestamp;
   2153 
   2154       // End time of the bucket (exclusive)
   2155       end_time: Timestamp;
   2156 
   2157       // Range of the bucket
   2158       range: StatisticBucketRange;
   2159 
   2160       // Sum of all counters falling under the given
   2161       // SLUG within this timeframe.
   2162       cumulative_counter: Integer;
   2163 
   2164     }
   2165 
   2166   .. ts:def:: MerchantStatisticCounterByInterval
   2167 
   2168     interface MerchantStatisticCounterByInterval {
   2169 
   2170       // Start time of the interval.
   2171       // The interval always ends at the response
   2172       // generation time.
   2173       start_time: Timestamp;
   2174 
   2175       // Sum of all counters falling under the given
   2176       // SLUG within this timeframe.
   2177       cumulative_counter: Integer;
   2178 
   2179     }
   2180 
   2181 Deleting instances
   2182 ^^^^^^^^^^^^^^^^^^
   2183 
   2184 .. http:delete:: /management/instances/$INSTANCE
   2185 .. http:delete:: [/instances/$INSTANCE]/private
   2186 
   2187   This request will be used to delete (permanently disable)
   2188   or purge merchant instance in the backend. Purging will
   2189   delete all offers and payments associated with the instance,
   2190   while disabling (the default behavior) only deletes the private key
   2191   and makes the instance unusable for new orders or payments.
   2192 
   2193   For deletion, the authentication credentials must match
   2194   the instance that is being deleted or the ``admin``
   2195   instance, depending on the access path used.
   2196 
   2197   **Required permission:** ``instances-write``
   2198 
   2199   **Request:**
   2200 
   2201   :query purge: *Optional*. If set to YES, the instance will be fully
   2202       deleted. Otherwise only the private key would be deleted.
   2203 
   2204   **Response:**
   2205 
   2206   :http:statuscode:`202 Accepted`:
   2207     2FA is required for this operation, usually to validate the
   2208     email and/or phone numbers registered for the instance.
   2209     This returns the `ChallengeResponse`. @since **v21**
   2210   :http:statuscode:`204 No content`:
   2211     The backend has successfully removed the instance.  The body is empty.
   2212   :http:statuscode:`401 Unauthorized`:
   2213     The request is unauthorized. Note that for already deleted instances,
   2214     the request must be authorized using the ``admin`` instance.
   2215   :http:statuscode:`404 Not found`:
   2216     The instance is unknown to the backend.
   2217   :http:statuscode:`409 Conflict`:
   2218     The instance cannot be deleted because it has pending offers, or
   2219     the instance cannot be purged because it has successfully processed
   2220     payments that have not passed the ``TAX_RECORD_EXPIRATION`` time.
   2221     The latter case only applies if ``purge`` was set.
   2222 
   2223 
   2224 KYC status checks
   2225 ^^^^^^^^^^^^^^^^^
   2226 
   2227 .. _merchantkycstatus:
   2228 
   2229 .. http:GET:: /management/instances/$INSTANCE/kyc
   2230 .. http:GET:: /instances/$INSTANCE/private/kyc
   2231 
   2232   Check KYC status of a particular payment target.
   2233   Prompts the exchange to inquire with the bank
   2234   as to the KYC status of the respective account
   2235   and returns the result.
   2236 
   2237   **Required permission:** ``instances-kyc-read``
   2238 
   2239   **Request:**
   2240 
   2241   :query h_wire=H_WIRE: *Optional*. If specified, the KYC check should return the KYC status only for this wire account. Otherwise, for all wire accounts.
   2242   :query exchange_url=URL: *Optional*. If specified, the KYC check should return the KYC status only for the given exchange. Otherwise, for all exchanges we interacted with.
   2243   :query lpt=TARGET: *Optional*.
   2244     Specifies what status change we are long-polling for.
   2245     Use 1 to wait for the KYC auth transfer (access token available),
   2246     2 to wait for an AML investigation to be done,
   2247     and 3 to wait for the KYC status to be OK.
   2248     If multiple accounts or exchanges match the query,
   2249     any account reaching the TARGET state will cause
   2250     the response to be returned.
   2251     Since protocol **v17**.
   2252   :query timeout_ms=NUMBER: *Optional.*  If specified, the merchant will
   2253     wait up to ``timeout_ms`` milliseconds for the exchanges to confirm completion of the KYC process(es).
   2254 
   2255   **Response:**
   2256 
   2257   If different exchanges cause different errors when processing
   2258   the request, the largest HTTP status code that is applicable
   2259   is returned.
   2260 
   2261   :http:statuscode:`200 Ok`:
   2262     The user may be redirected to the provided locations to perform
   2263     KYC checks.
   2264     The response will be a `MerchantAccountKycRedirectsResponse` object.
   2265     Uses this status code and format only since protocol **v17**.
   2266   :http:statuscode:`204 No content`:
   2267     No possibilities for KYC operations exist.
   2268     This may change in the future, but there is
   2269     no need to check again soon. This will most likely
   2270     change if accounts are added to the instance.
   2271 
   2272   **Details:**
   2273 
   2274   .. ts:def:: MerchantAccountKycRedirectsResponse
   2275 
   2276      interface MerchantAccountKycRedirectsResponse {
   2277 
   2278        // Array of KYC status information for
   2279        // the exchanges and bank accounts selected
   2280        // by the query.
   2281        kyc_data: MerchantAccountKycRedirect[];
   2282 
   2283     }
   2284 
   2285   .. ts:def:: MerchantAccountKycRedirect
   2286 
   2287     interface MerchantAccountKycRedirect {
   2288 
   2289       // Summary of the status of the KYC process. Possible values are:
   2290       //
   2291       // o "no-exchange-keys": we do not (yet) have the /keys of the exchange
   2292       // - "kyc-wire-impossible": KYC auth transfer needed but not possible
   2293       // @ "kyc-wire-required": KYC auth transfer still needed and possible
   2294       // @ "kyc-required": merchant must supply KYC data to proceed (incl.
   2295       //      in case of exposed zero-limits on deposit/aggregation)
   2296       // + "awaiting-aml-review": account under review by payment provider
   2297       // + "ready": everything is fine, account can be fully used
   2298       // - "logic-bug": merchant backend logic bug
   2299       // o "merchant-internal-error": merchant had an internal error
   2300       // o "exchange-internal-error": exchange had an internal error
   2301       // o "exchange-gateway-timeout": network timeout at gateway
   2302       // o "exchange-unreachable": exchange did not respond at all
   2303       // - "exchange-status-invalid": exchange violated protocol in reply
   2304       //
   2305       // "+" are perfectly normal states, "@" are states where the user
   2306       // must performn an action (show link!); "o" are reasonable transient
   2307       // states that could happen and are we are expected to likely recover
   2308       // from automatically but that we should inform the user about
   2309       // (show in yellow?), "-" are hard error states from which
   2310       // there is likely no good automatic recovery from (show in red?).
   2311       status: string;
   2312 
   2313       // Full payto URI of the bank wire account this is about.
   2314       payto_uri: string;
   2315 
   2316       // Hash of the salted payto://-URI of our
   2317       // bank wire account this is about.
   2318       // Since protocol **v17**.
   2319       h_wire: string;
   2320 
   2321       // Base URL of the exchange this is about.
   2322       exchange_url: string;
   2323 
   2324       // HTTP status code returned by the exchange when we asked for
   2325       // information about the KYC status.
   2326       // Since protocol **v17**.
   2327       exchange_http_status: Integer;
   2328 
   2329       // True if we did not get a ``/keys`` response from
   2330       // the exchange and thus cannot do certain checks, such as
   2331       // determining default account limits or account eligibility.
   2332       no_keys: boolean;
   2333 
   2334       // True if the given account cannot to KYC at the
   2335       // given exchange because no wire method exists that could
   2336       // be used to do the KYC auth wire transfer.
   2337       auth_conflict: boolean;
   2338 
   2339       // Numeric `error code <error-codes>` indicating errors the exchange
   2340       // returned, or TALER_EC_INVALID for none.
   2341       // Optional (as there may not always have
   2342       // been an error code). Since protocol **v17**.
   2343       exchange_code?: Integer;
   2344 
   2345       // Access token needed to open the KYC SPA and/or
   2346       // access the ``/kyc-info/`` endpoint.
   2347       access_token?: AccountAccessToken;
   2348 
   2349       // Array with limitations that currently apply to this
   2350       // account and that may be increased or lifted if the
   2351       // KYC check is passed.
   2352       // Note that additional limits *may* exist and not be
   2353       // communicated to the client. If such limits are
   2354       // reached, this *may* be indicated by the account
   2355       // going into ``aml_review`` state. However, it is
   2356       // also possible that the exchange may legally have
   2357       // to deny operations without being allowed to provide
   2358       // any justification.
   2359       // The limits should be used by the client to
   2360       // possibly structure their operations (e.g. withdraw
   2361       // what is possible below the limit, ask the user to
   2362       // pass KYC checks or withdraw the rest after the time
   2363       // limit is passed, warn the user to not withdraw too
   2364       // much or even prevent the user from generating a
   2365       // request that would cause it to exceed hard limits).
   2366       limits?: AccountLimit[];
   2367 
   2368       // Array of full payto://-URIs with
   2369       // wire transfer instructions (including
   2370       // optional amount and subject) for a KYC auth wire
   2371       // transfer. Set only if this is required
   2372       // to get the given exchange working.
   2373       // Array because the exchange may have multiple
   2374       // bank accounts, in which case any of these
   2375       // accounts will do.
   2376       // Optional. Since protocol **v17**.
   2377       payto_kycauths?: string[];
   2378 
   2379     }
   2380 
   2381 
   2382 -------------
   2383 Bank Accounts
   2384 -------------
   2385 
   2386 One or more bank accounts must be associated with an instance
   2387 so that the instance can receive payments.  Payments may be made
   2388 into any of the active bank accounts of an instance.
   2389 
   2390 
   2391 .. http:post:: [/instances/$INSTANCE]/private/accounts
   2392 
   2393   This is used to add an account to an instance.
   2394 
   2395   **Required permission:** ``accounts-write``
   2396 
   2397   **Request:**
   2398 
   2399   The request must have an `AccountAddDetails` body.
   2400 
   2401   **Response:**
   2402 
   2403   :http:statuscode:`200 Ok`:
   2404     Adding the account was successful, we return the salt selected by the backend and the resulting wire hash in an `AccountAddResponse`.
   2405   :http:statuscode:`202 Accepted`:
   2406     2FA is required for this operation, usually to validate the
   2407     email and/or phone numbers registered for the instance.
   2408     This returns the `ChallengeResponse`. @since **v21**
   2409   :http:statuscode:`404 Not found`:
   2410     The merchant instance is unknown or it is not in our data.
   2411   :http:statuscode:`409 Conflict`:
   2412     The provided information is inconsistent with the current state of the instance.
   2413     Usually this means we already have this account, but with conflicting credit facade information.
   2414     Inactive accounts can be reactivated using this method even if the
   2415     credit facade information differs from the previous state.
   2416 
   2417   **Details:**
   2418 
   2419   .. ts:def:: AccountAddDetails
   2420 
   2421     interface AccountAddDetails {
   2422 
   2423       // Full payto:// URI of the account.
   2424       payto_uri: string;
   2425 
   2426       // URL from where the merchant can download information
   2427       // about incoming wire transfers to this account.
   2428       credit_facade_url?: string;
   2429 
   2430       // Credentials to use when accessing the credit facade.
   2431       // Never returned on a GET (as this may be somewhat
   2432       // sensitive data). Can be set in POST
   2433       // or PATCH requests to update (or delete) credentials.
   2434       // To really delete credentials, set them to the type: "none".
   2435       credit_facade_credentials?: FacadeCredentials;
   2436 
   2437     }
   2438 
   2439   .. ts:def:: FacadeCredentials
   2440 
   2441     type FacadeCredentials =
   2442       | NoFacadeCredentials
   2443       | BasicAuthFacadeCredentials;
   2444 
   2445   .. ts:def:: NoFacadeCredentials
   2446 
   2447     interface NoFacadeCredentials {
   2448        type: "none";
   2449     };
   2450 
   2451   .. ts:def:: BasicAuthFacadeCredentials
   2452 
   2453     interface BasicAuthFacadeCredentials {
   2454        type: "basic";
   2455 
   2456        // Username to use to authenticate
   2457        username: string;
   2458 
   2459        // Password to use to authenticate
   2460        password: string;
   2461     };
   2462 
   2463   .. ts:def:: AccountAddResponse
   2464 
   2465     interface AccountAddResponse {
   2466 
   2467       // Hash over the wire details (including over the salt).
   2468       h_wire: HashCode;
   2469 
   2470       // Salt used to compute h_wire.
   2471       salt: HashCode;
   2472 
   2473     }
   2474 
   2475 
   2476 .. http:patch:: [/instances/$INSTANCE]/private/accounts/$H_WIRE
   2477 
   2478   This is used to update a bank account.
   2479 
   2480   **Required permission:** ``accounts-write``
   2481 
   2482   **Request:**
   2483 
   2484   The request must be a `AccountPatchDetails`.
   2485 
   2486   **Response:**
   2487 
   2488   :http:statuscode:`204 No content`:
   2489     The account has successfully modified.
   2490   :http:statuscode:`404 Not found`:
   2491     The account (``H_WIRE``) is unknown to the backend.
   2492 
   2493   **Details:**
   2494 
   2495   .. ts:def:: AccountPatchDetails
   2496 
   2497    interface AccountPatchDetails {
   2498 
   2499       // URL from where the merchant can download information
   2500       // about incoming wire transfers to this account.
   2501       credit_facade_url?: string;
   2502 
   2503       // Credentials to use when accessing the credit facade.
   2504       // Never returned on a GET (as this may be somewhat
   2505       // sensitive data). Can be set in POST
   2506       // or PATCH requests to update (or delete) credentials.
   2507       // To really delete credentials, set them to the type: "none".
   2508       // If the argument is omitted, the old credentials
   2509       // are simply preserved.
   2510       credit_facade_credentials?: FacadeCredentials;
   2511    }
   2512 
   2513 
   2514 .. http:get:: [/instances/$INSTANCE]/private/accounts
   2515 
   2516   This is used to return the list of all the bank accounts
   2517   of an instance.
   2518 
   2519   **Required permission:** ``accounts-read``
   2520 
   2521   **Response:**
   2522 
   2523   :http:statuscode:`200 OK`:
   2524      The backend has successfully returned all the accounts. Returns a `AccountsSummaryResponse`.
   2525   :http:statuscode:`404 Not found`:
   2526      The backend has does not know about the instance.
   2527 
   2528   **Details:**
   2529 
   2530   .. ts:def:: AccountsSummaryResponse
   2531 
   2532     interface AccountsSummaryResponse {
   2533 
   2534       // List of accounts that are known for the instance.
   2535       accounts: BankAccountEntry[];
   2536     }
   2537 
   2538   .. ts:def:: BankAccountEntry
   2539 
   2540     interface BankAccountEntry {
   2541 
   2542       // Full payto:// URI of the account.
   2543       payto_uri: string;
   2544 
   2545       // Hash over the wire details (including over the salt).
   2546       h_wire: HashCode;
   2547 
   2548       // true if this account is active,
   2549       // false if it is historic.
   2550       active: boolean;
   2551     }
   2552 
   2553 .. http:get:: [/instances/$INSTANCE]/private/accounts/$H_WIRE
   2554 
   2555   This is used to obtain detailed information about a specific bank account.
   2556 
   2557 
   2558   **Required permission:** ``accounts-read``
   2559 
   2560   **Response:**
   2561 
   2562   :http:statuscode:`200 OK`:
   2563     The backend has successfully returned the detailed information about a specific bank account.
   2564     Returns a `BankAccountDetail`.
   2565   :http:statuscode:`404 Not found`:
   2566     The bank account or instance is unknown to the backend.
   2567 
   2568   **Details:**
   2569 
   2570   .. ts:def:: BankAccountDetail
   2571 
   2572     interface BankAccountDetail {
   2573 
   2574       // Full payto:// URI of the account.
   2575       payto_uri: string;
   2576 
   2577       // Hash over the wire details (including over the salt).
   2578       h_wire: HashCode;
   2579 
   2580       // Salt used to compute h_wire.
   2581       salt: HashCode;
   2582 
   2583       // URL from where the merchant can download information
   2584       // about incoming wire transfers to this account.
   2585       credit_facade_url?: string;
   2586 
   2587       // true if this account is active,
   2588       // false if it is historic.
   2589       active: boolean;
   2590     }
   2591 
   2592 
   2593 
   2594 .. http:delete:: [/instances/$INSTANCE]/private/accounts/$H_WIRE
   2595 
   2596   **Required permission:** ``accounts-write``
   2597 
   2598   **Response:**
   2599 
   2600   :http:statuscode:`204 No content`:
   2601     The backend has successfully deactivated the account.
   2602   :http:statuscode:`404 Not found`:
   2603     The backend does not know the instance or the account.
   2604 
   2605 
   2606 --------------------
   2607 Inventory management
   2608 --------------------
   2609 
   2610 .. _inventory:
   2611 
   2612 Inventory management is an *optional* backend feature that can be used to
   2613 manage limited stocks of products and to auto-complete product descriptions in
   2614 contracts (such that the frontends have to do less work).  You can use the
   2615 Taler merchant backend to process payments *without* using its inventory
   2616 management.
   2617 
   2618 
   2619 Managing measurement units
   2620 ^^^^^^^^^^^^^^^^^^^^^^^^^^
   2621 
   2622 .. http:get:: [/instances/$INSTANCE]/private/units
   2623 
   2624   Returns the list of measurement units available to an instance.
   2625 
   2626   **Required permission:** ``units-read``
   2627 
   2628   **Response:**
   2629 
   2630   :http:statuscode:`200 OK`:
   2631     The backend returned the unit catalog. The body is a `UnitListResponse`.
   2632 
   2633   **Details:**
   2634 
   2635   .. ts:def:: UnitListResponse
   2636 
   2637     interface UnitListResponse {
   2638       units: MerchantUnit[];
   2639     }
   2640 
   2641   .. ts:def:: MerchantUnit
   2642 
   2643     interface MerchantUnit {
   2644       // Unique serial for the unit.
   2645       unit_serial: Integer;
   2646 
   2647       // Short identifier used in product definitions.
   2648       unit: string;
   2649 
   2650       // Human-readable long label.
   2651       unit_name_long: string;
   2652 
   2653       // Human-readable short label.
   2654       unit_name_short: string;
   2655 
   2656       // Optional translations for the long label.
   2657       unit_name_long_i18n?: { [lang_tag: string]: string };
   2658 
   2659       // Optional translations for the short label.
   2660       unit_name_short_i18n?: { [lang_tag: string]: string };
   2661 
   2662       // Whether fractional quantities are allowed for this unit.
   2663       unit_allow_fraction: boolean;
   2664 
   2665       // Maximum fractional precision (0-6) enforced for this unit.
   2666       unit_precision_level: Integer;
   2667 
   2668       // Whether the unit is currently active.
   2669       unit_active: boolean;
   2670 
   2671       // True if the unit is provided by the backend and cannot be removed.
   2672       unit_builtin: boolean;
   2673     }
   2674 
   2675 .. http:get:: [/instances/$INSTANCE]/private/units/$UNIT
   2676 
   2677   Fetch details for a single measurement unit.
   2678 
   2679   **Required permission:** ``units-read``
   2680 
   2681   **Response:**
   2682 
   2683   :http:statuscode:`200 OK`:
   2684     The backend returned the unit definition. The body is a `MerchantUnit`.
   2685   :http:statuscode:`404 Not found`:
   2686     The unit is unknown to the backend.
   2687 
   2688 .. http:post:: [/instances/$INSTANCE]/private/units
   2689 
   2690   Create a custom measurement unit or reactivate a previously disabled one.
   2691 
   2692   **Required permission:** ``units-write``
   2693 
   2694   **Request:**
   2695 
   2696   The request must be a `UnitAddRequest`.
   2697 
   2698   **Response:**
   2699 
   2700   :http:statuscode:`204 No content`:
   2701     The backend added the unit.
   2702   :http:statuscode:`409 Conflict`:
   2703     A built-in unit with the same short name already exists.
   2704 
   2705   .. ts:def:: UnitAddRequest
   2706 
   2707     interface UnitAddRequest {
   2708       // Short identifier to reference the unit from products and orders.
   2709       unit: string;
   2710 
   2711       // Human-readable long label (e.g. "kilogram").
   2712       unit_name_long: string;
   2713 
   2714       // Human-readable short label (e.g. "kg").
   2715       unit_name_short: string;
   2716 
   2717       // Optional translations for the long label keyed by BCP 47 language tags.
   2718       unit_name_long_i18n?: { [lang_tag: string]: string };
   2719 
   2720       // Optional translations for the short label keyed by BCP 47 language tags.
   2721       unit_name_short_i18n?: { [lang_tag: string]: string };
   2722 
   2723       // Defaults to false; set to true to enable fractional quantities.
   2724       unit_allow_fraction?: boolean;
   2725 
   2726       // Fractional precision (0-6). Ignored when ``unit_allow_fraction`` is false.
   2727       unit_precision_level?: Integer;
   2728 
   2729       // Defaults to true.
   2730       unit_active?: boolean;
   2731     }
   2732 
   2733 .. http:patch:: [/instances/$INSTANCE]/private/units/$UNIT
   2734 
   2735   Update attributes of a measurement unit.
   2736 
   2737   **Required permission:** ``units-write``
   2738 
   2739   **Request:**
   2740 
   2741   The request must be a `UnitPatchRequest`.
   2742 
   2743   **Response:**
   2744 
   2745   :http:statuscode:`204 No content`:
   2746     The backend updated the unit.
   2747   :http:statuscode:`404 Not found`:
   2748     The unit is unknown to the backend.
   2749 
   2750   Built-in units allow changing ``unit_allow_fraction``, ``unit_precision_level``, and
   2751   ``unit_active``; other fields are immutable for built-ins.
   2752 
   2753   .. ts:def:: UnitPatchRequest
   2754 
   2755     interface UnitPatchRequest {
   2756       // Updated human-readable long label.
   2757       unit_name_long?: string;
   2758 
   2759       // Updated human-readable short label.
   2760       unit_name_short?: string;
   2761 
   2762       // Updated translations for the long label keyed by BCP 47 language tags.
   2763       unit_name_long_i18n?: { [lang_tag: string]: string };
   2764 
   2765       // Updated translations for the short label keyed by BCP 47 language tags.
   2766       unit_name_short_i18n?: { [lang_tag: string]: string };
   2767 
   2768       // Override to allow or forbid fractional quantities.
   2769       unit_allow_fraction?: boolean;
   2770 
   2771       // Override for the fractional precision (0-6). Ignored if fractions are disabled.
   2772       unit_precision_level?: Integer;
   2773 
   2774       // Toggle whether the unit is active.
   2775       unit_active?: boolean;
   2776     }
   2777 
   2778   Fractional precision is capped at six decimal places. Disabling
   2779   ``unit_allow_fraction`` forces ``unit_precision_level`` to zero.
   2780 
   2781 .. http:delete:: [/instances/$INSTANCE]/private/units/$UNIT
   2782 
   2783   Remove a custom unit from an instance.
   2784 
   2785     **Required permission:** ``units-write``
   2786 
   2787   **Response:**
   2788 
   2789   :http:statuscode:`204 No content`:
   2790     The unit was removed.
   2791   :http:statuscode:`404 Not found`:
   2792     The unit is unknown to the backend.
   2793   :http:statuscode:`409 Conflict`:
   2794     Built-in units cannot be deleted.
   2795 
   2796 
   2797 Managing product categories
   2798 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   2799 
   2800 .. http:get:: [/instances/$INSTANCE]/private/categories
   2801 
   2802   This request returns the known product categories
   2803   and the number of products in each category.
   2804   Since API version **v16**.
   2805 
   2806   **Required permission:** ``categories-read``
   2807 
   2808   **Response:**
   2809 
   2810   :http:statuscode:`200 Ok`:
   2811     The body is a `CategoryListResponse`.
   2812 
   2813   **Details:**
   2814 
   2815   .. ts:def:: CategoryListResponse
   2816 
   2817     interface CategoryListResponse {
   2818 
   2819       // Array with all of the categories we know.
   2820       categories: CategoryListEntry[];
   2821 
   2822     }
   2823 
   2824   .. ts:def:: CategoryListEntry
   2825 
   2826     interface CategoryListEntry {
   2827 
   2828       // Unique number for the category.
   2829       category_id: Integer;
   2830 
   2831       // Name of the category.
   2832       name: string;
   2833 
   2834       // Translations of the name into various
   2835       // languages.
   2836       name_i18n?: { [lang_tag: string]: string };
   2837 
   2838       // Number of products in this category.
   2839       // A product can be in more than one category.
   2840       product_count: Integer;
   2841 
   2842     }
   2843 
   2844 .. http:get:: [/instances/$INSTANCE]/private/categories/$CATEGORY_ID
   2845 
   2846   This request returns the known products in the given
   2847   category.
   2848   Since API version **v16**.
   2849 
   2850   **Required permission:** ``categories-read``
   2851 
   2852   **Response:**
   2853 
   2854   :http:statuscode:`200 Ok`:
   2855     The body is a `CategoryProductList`.
   2856 
   2857   **Details:**
   2858 
   2859   .. ts:def:: CategoryProductList
   2860 
   2861     interface CategoryProductList {
   2862 
   2863       // Name of the category.
   2864       name: string;
   2865 
   2866       // Translations of the name into various
   2867       // languages.
   2868       name_i18n?: { [lang_tag: string]: string };
   2869 
   2870       // The products in this category.
   2871       products: CategoryProductSummary[];
   2872 
   2873     }
   2874 
   2875   .. ts:def:: CategoryProductSummary
   2876 
   2877     interface CategoryProductSummary {
   2878 
   2879       // ID of a product in the category.
   2880       product_id: string;
   2881 
   2882     }
   2883 
   2884 
   2885 .. http:post:: [/instances/$INSTANCE]/private/categories
   2886 
   2887   This is used to create a new category for the inventory.
   2888   Since API version **v16**.
   2889 
   2890   **Required permission:** ``categories-write``
   2891 
   2892   **Request:**
   2893 
   2894     The request is a `CategoryCreateRequest`.
   2895 
   2896   **Response:**
   2897 
   2898   :http:statuscode:`200 Ok`:
   2899     The response is a `CategoryCreatedResponse`.
   2900 
   2901   **Details:**
   2902 
   2903   .. ts:def:: CategoryCreateRequest
   2904 
   2905     interface CategoryCreateRequest {
   2906 
   2907       // Name of the category.
   2908       name: string;
   2909 
   2910       // Translations of the name into various
   2911       // languages.
   2912       name_i18n?: { [lang_tag: string]: string };
   2913 
   2914     }
   2915 
   2916   .. ts:def:: CategoryCreatedResponse
   2917 
   2918     interface CategoryCreatedResponse {
   2919 
   2920       // Number of the newly created category.
   2921       category_id: Integer;
   2922     }
   2923 
   2924 
   2925 .. http:patch:: [/instances/$INSTANCE]/private/categories/$CATEGORY_ID
   2926 
   2927   This is used to edit a category.
   2928   Since API version **v16**.
   2929 
   2930   **Required permission:** ``categories-write``
   2931 
   2932   **Request:**
   2933 
   2934     The request is a `CategoryCreateRequest`.
   2935 
   2936   **Response:**
   2937 
   2938   :http:statuscode:`204 No Content`:
   2939     The category was modified successfully.
   2940 
   2941 .. http:delete:: [/instances/$INSTANCE]/private/categories/$CATEGORY_ID
   2942 
   2943   This is used to delete a category.
   2944   Since API version **v16**.
   2945 
   2946   **Required permission:** ``categories-write``
   2947 
   2948   **Response:**
   2949 
   2950   :http:statuscode:`204 No Content`:
   2951     The category was deleted.
   2952   :http:statuscode:`404 Not Found`:
   2953     The category was possibly already deleted or is unknown.
   2954 
   2955 
   2956 Adding products to the inventory
   2957 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   2958 
   2959 
   2960 .. http:post:: [/instances/$INSTANCE]/private/products
   2961 
   2962   This is used to add a product to the inventory.
   2963 
   2964   **Required permission:** ``products-write``
   2965 
   2966   **Request:**
   2967 
   2968   The request must be a `ProductAddDetail`.
   2969 
   2970   **Response:**
   2971 
   2972   :http:statuscode:`204 No content`:
   2973     The backend has successfully expanded the inventory.
   2974   :http:statuscode:`409 Conflict`:
   2975     The backend already knows a product with this product ID, but with different details.
   2976 
   2977   **Details:**
   2978 
   2979   .. ts:def:: ProductAddDetail
   2980 
   2981     interface ProductAddDetail {
   2982 
   2983       // Product ID to use.
   2984       product_id: string;
   2985 
   2986       // Human-readable product name.
   2987       // Since API version **v20**.  Optional only for
   2988       // backwards-compatibility, should be considered mandatory
   2989       // moving forward!
   2990       product_name?: string;
   2991 
   2992       // Human-readable product description.
   2993       description: string;
   2994 
   2995       // Map from IETF BCP 47 language tags to localized descriptions.
   2996       description_i18n?: { [lang_tag: string]: string };
   2997 
   2998       // Categories into which the product belongs.
   2999       // Used in the POS-endpoint.
   3000       // Since API version **v16**.
   3001       categories?: Integer[];
   3002 
   3003       // Unit in which the product is measured (liters, kilograms, packages, etc.).
   3004       unit: string;
   3005 
   3006       // Optional override to control whether fractional quantities are permitted.
   3007       // Defaults to the policy implied by ``unit``.
   3008       unit_allow_fraction?: boolean;
   3009 
   3010       // Override for the fractional precision level (0-6). Only relevant if
   3011       // ``unit_allow_fraction`` is true. Defaults come from ``unit``.
   3012       unit_precision_level?: Integer;
   3013 
   3014       // Preferred way to express inventory counts using "<integer>[.<fraction>]" syntax.
   3015       // Use "-1" for unlimited stock. Required unless ``total_stock`` is provided.
   3016       unit_total_stock?: string;
   3017 
   3018       // Legacy stock counter. Deprecated, use ``unit_total_stock`` instead.
   3019       // Still required when ``unit_total_stock`` is omitted.
   3020       total_stock?: Integer;
   3021 
   3022       // Preferred way to express the per-unit price of the product. Supply at least one entry;
   3023       // the first entry represents the base price and MUST include applicable taxes.
   3024       // Zero implies that the product is not sold separately or that the price must be supplied
   3025       // by the frontend.
   3026       unit_price?: Amount[];
   3027 
   3028       // Legacy price field. Deprecated; when present it must match the first element of ``unit_price``.
   3029       price?: Amount;
   3030 
   3031       // An optional base64-encoded product image.
   3032       image?: ImageDataUrl;
   3033 
   3034       // A list of taxes paid by the merchant for one unit of this product.
   3035       taxes?: Tax[];
   3036 
   3037       // Identifies where the product is in stock.
   3038       address?: Location;
   3039 
   3040       // Identifies when we expect the next restocking to happen.
   3041       next_restock?: Timestamp;
   3042 
   3043       // Minimum age buyer must have (in years). Default is 0.
   3044       minimum_age?: Integer;
   3045 
   3046     }
   3047 
   3048   Clients SHOULD migrate to the new ``unit_*`` fields and treat ``total_stock`` and ``price``
   3049   as deprecated compatibility shims. If both the legacy and the new representation are supplied,
   3050   their values must match. Omitting both ``unit_total_stock`` and ``total_stock`` (or both
   3051   ``unit_price`` and ``price``) results in a ``400 Bad Request``. When only ``price`` is given,
   3052   the backend treats it as a one-element ``unit_price`` array.
   3053 
   3054   ``unit_total_stock`` uses a fixed-point decimal string in the form ``INTEGER[.FRACTION]`` with
   3055   at most six fractional digits. Scientific notation or special values such as ``NaN`` are not
   3056   accepted. Supply ``"-1"`` to represent unlimited stock.
   3057 
   3058   Fractional behaviour defaults to the value of ``unit``. The backend disables fractions for
   3059   ``Piece``, ``Set``, ``Custom``, ``WeightUnitMg`` and ``SizeUnitMm``. Other predefined units
   3060   allow fractional quantities with the following default precision levels:
   3061 
   3062   - Precision ``1``: ``WeightUnitG``, ``SizeUnitCm``, ``SurfaceUnitMm2``, ``VolumeUnitMm3``.
   3063   - Precision ``2``: ``WeightUnitOunce``, ``SizeUnitInch``, ``SurfaceUnitCm2``,
   3064     ``VolumeUnitInch3``, ``VolumeUnitOunce``, ``TimeUnitHour``, ``TimeUnitMonth``.
   3065   - Precision ``3``: ``WeightUnitTon``, ``WeightUnitKg``, ``WeightUnitPound``, ``SizeUnitM``,
   3066     ``SizeUnitDm``, ``SizeUnitFoot``, ``SurfaceUnitDm2``, ``SurfaceUnitFoot2``, ``VolumeUnitCm3``,
   3067     ``VolumeUnitLitre``, ``VolumeUnitGallon``, ``TimeUnitSecond``, ``TimeUnitMinute``,
   3068     ``TimeUnitDay``, ``TimeUnitWeek``.
   3069   - Precision ``4``: ``SurfaceUnitM2``, ``SurfaceUnitInch2``, ``TimeUnitYear``.
   3070   - Precision ``5``: ``VolumeUnitDm3``, ``VolumeUnitFoot3``.
   3071   - Precision ``6``: ``VolumeUnitM3``.
   3072 
   3073   Integrations can override these defaults by explicitly setting ``unit_allow_fraction`` and/or
   3074   ``unit_precision_level``.
   3075 
   3076 
   3077 .. http:patch:: [/instances/$INSTANCE]/private/products/$PRODUCT_ID
   3078 
   3079   This is used to update product details in the inventory. Note that the
   3080   ``total_stock`` and ``total_lost`` numbers MUST be greater or equal than
   3081   previous values (this design ensures idempotency).  In case stocks were lost
   3082   but not sold, increment the ``total_lost`` number.  All fields in the
   3083   request are optional, those that are not given are simply preserved (not
   3084   modified).  Note that the ``description_i18n`` and ``taxes`` can only be
   3085   modified in bulk: if it is given, all translations must be provided, not
   3086   only those that changed.  ``never`` should be used for the ``next_restock``
   3087   timestamp to indicate no intention/possibility of restocking, while a time
   3088   of zero is used to indicate "unknown".
   3089 
   3090   **Required permission:** ``products-write``
   3091 
   3092   **Request:**
   3093 
   3094   The request must be a `ProductPatchDetail`.
   3095 
   3096   **Response:**
   3097 
   3098   :http:statuscode:`204 No content`:
   3099     The backend has successfully expanded the inventory.
   3100   :http:statuscode:`404 Not found`:
   3101     The product (ID) is unknown to the backend.
   3102   :http:statuscode:`409 Conflict`:
   3103     The provided information is inconsistent with the current state of the inventory.
   3104 
   3105 
   3106   .. ts:def:: ProductPatchDetail
   3107 
   3108     interface ProductPatchDetail {
   3109 
   3110       // Human-readable product name.
   3111       // Since API version **v20**.  Optional only for
   3112       // backwards-compatibility, should be considered mandatory
   3113       // moving forward!
   3114       product_name?: string;
   3115 
   3116       // Human-readable product description.
   3117       description: string;
   3118 
   3119       // Map from IETF BCP 47 language tags to localized descriptions.
   3120       description_i18n?: { [lang_tag: string]: string };
   3121 
   3122       // Unit in which the product is measured (liters, kilograms, packages, etc.).
   3123       unit: string;
   3124 
   3125       // Optional override to control whether fractional quantities are permitted.
   3126       unit_allow_fraction?: boolean;
   3127 
   3128       // Override for the fractional precision level (0-6). Only relevant if
   3129       // ``unit_allow_fraction`` is true.
   3130       unit_precision_level?: Integer;
   3131 
   3132       // Categories into which the product belongs.
   3133       // Used in the POS-endpoint.
   3134       // Since API version **v16**.
   3135       categories?: Integer[];
   3136 
   3137       // Preferred way to express the per-unit price. Supply at least one entry;
   3138       // the first entry represents the base price and MUST include applicable taxes.
   3139       // Zero implies that the product is not sold separately or that the price must be supplied
   3140       // by the frontend.
   3141       unit_price?: Amount[];
   3142 
   3143       // Legacy price field. Deprecated; when present it must match the first element of ``unit_price``.
   3144       price?: Amount;
   3145 
   3146       // An optional base64-encoded product image.
   3147       image?: ImageDataUrl;
   3148 
   3149       // A list of taxes paid by the merchant for one unit of this product.
   3150       taxes?: Tax[];
   3151 
   3152       // Preferred way to express inventory counts using "<integer>[.<fraction>]" syntax.
   3153       // Use "-1" for unlimited stock.
   3154       unit_total_stock?: string;
   3155 
   3156       // Legacy stock counter. Deprecated, use ``unit_total_stock`` instead.
   3157       total_stock?: Integer;
   3158 
   3159       // Number of units of the product that were lost (spoiled, stolen, etc.).
   3160       total_lost?: Integer;
   3161 
   3162       // Identifies where the product is in stock.
   3163       address?: Location;
   3164 
   3165       // Identifies when we expect the next restocking to happen.
   3166       next_restock?: Timestamp;
   3167 
   3168       // Minimum age buyer must have (in years). Default is 0.
   3169       minimum_age?: Integer;
   3170 
   3171     }
   3172 
   3173   The same compatibility rules for the ``unit_*`` fields and their deprecated counterparts apply
   3174   when patching an existing product.
   3175 
   3176 Inspecting inventory
   3177 ^^^^^^^^^^^^^^^^^^^^
   3178 
   3179 .. http:get:: [/instances/$INSTANCE]/private/products
   3180 
   3181   This is used to return the list of all items in the inventory.
   3182 
   3183   **Required permission:** ``products-read``
   3184 
   3185   **Request:**
   3186 
   3187   :query limit: *Optional*. At most return the given number of results. Negative for descending by row ID, positive for ascending by row ID. Default is ``20``.  Since protocol **v12**.
   3188   :query offset: *Optional*. Starting ``product_serial_id`` for an iteration.  Since protocol **v12**.
   3189   :query category_filter: *Optional*. Only returns products that are in a category where the category name contains the given text as a substring. Matching is case-insensitive. Since protocol **v23**.
   3190   :query name_filter: *Optional*. Only returns products where the product name contains the given text as a substring. Matching is case-insensitive. Since protocol **v23**.
   3191   :query description_filter: *Optional*. Only returns products where the product description contains the given text as a substring. Matching is case-insensitive. Since protocol **v23**.
   3192 
   3193   **Response:**
   3194 
   3195   :http:statuscode:`200 OK`:
   3196     The backend has successfully returned the inventory. Returns
   3197     a `InventorySummaryResponse`.
   3198   :http:statuscode:`404 Not found`:
   3199     The backend has does not know about the instance.
   3200 
   3201   **Details:**
   3202 
   3203   .. ts:def:: InventorySummaryResponse
   3204 
   3205     interface InventorySummaryResponse {
   3206       // List of products that are present in the inventory.
   3207       products: InventoryEntry[];
   3208     }
   3209 
   3210   The `InventoryEntry` object describes an item in the inventory. It has the following structure:
   3211 
   3212   .. ts:def:: InventoryEntry
   3213 
   3214     interface InventoryEntry {
   3215       // Product identifier, as found in the product.
   3216       product_id: string;
   3217 
   3218       // ``product_serial_id`` of the product in the database.
   3219       product_serial: Integer;
   3220 
   3221     }
   3222 
   3223 
   3224 .. http:get:: [/instances/$INSTANCE]/private/products/$PRODUCT_ID
   3225 
   3226   This is used to obtain detailed information about a product in the inventory.
   3227 
   3228   **Required permission:** ``products-read``
   3229 
   3230   **Response:**
   3231 
   3232   :http:statuscode:`200 OK`:
   3233     The backend has successfully returned the inventory. Returns
   3234     a `ProductDetail`.
   3235   :http:statuscode:`404 Not found`:
   3236     The product (ID) is unknown to the backend.
   3237 
   3238   **Details:**
   3239 
   3240   .. ts:def:: ProductDetail
   3241 
   3242     interface ProductDetail {
   3243 
   3244       // Human-readable product name.
   3245       // Since API version **v20**.
   3246       product_name: string;
   3247 
   3248       // Human-readable product description.
   3249       description: string;
   3250 
   3251       // Map from IETF BCP 47 language tags to localized descriptions.
   3252       description_i18n: { [lang_tag: string]: string };
   3253 
   3254       // Unit in which the product is measured (liters, kilograms, packages, etc.).
   3255       unit: string;
   3256 
   3257       // Does the backend allow fractional quantities for this unit?
   3258       unit_allow_fraction: boolean;
   3259 
   3260       // Maximum fractional precision (0-6) enforced for inventory operations.
   3261       unit_precision_level: Integer;
   3262 
   3263       // Categories into which the product belongs.
   3264       // Since API version **v16**.
   3265       categories: Integer[];
   3266 
   3267       // Price tiers for this product. The first entry represents the base price and MUST include
   3268       // applicable taxes. Zero implies the product is not sold separately or that the price is not
   3269       // fixed, and must be supplied by the front-end.
   3270       unit_price: Amount[];
   3271 
   3272       // Legacy price field kept for compatibility. Deprecated; equal to the first element of ``unit_price``.
   3273       price: Amount;
   3274 
   3275       // An optional base64-encoded product image.
   3276       image: ImageDataUrl;
   3277 
   3278       // A list of taxes paid by the merchant for one unit of this product.
   3279       // Optional since **v15**.
   3280       taxes?: Tax[];
   3281 
   3282       // Legacy integer stock counter kept for compatibility. ``-1`` indicates unlimited stock.
   3283       total_stock: Integer;
   3284 
   3285       // Stock expressed using "<integer>[.<fraction>]" syntax with up to six fractional digits.
   3286       // Use ``"-1"`` for unlimited stock.
   3287       unit_total_stock: string;
   3288 
   3289       // Number of units of the product that have already been sold.
   3290       total_sold: Integer;
   3291 
   3292       // Number of units of the product that were lost (spoiled, stolen, etc.).
   3293       total_lost: Integer;
   3294 
   3295       // Identifies where the product is in stock.
   3296       // Optional since **v15**.
   3297       address?: Location;
   3298 
   3299       // Identifies when we expect the next restocking to happen.
   3300       next_restock?: Timestamp;
   3301 
   3302       // Minimum age buyer must have (in years).
   3303       minimum_age?: Integer;
   3304 
   3305     }
   3306 
   3307 .. http:get:: [/instances/$INSTANCE]/private/pos
   3308 
   3309   This is used to return the point-of-sale (POS) configuration with full details on all items in the inventory.
   3310 
   3311   Endpoint was introduced in protocol **v15**.
   3312 
   3313   **Required permission:** ``products-read``
   3314 
   3315   **Response:**
   3316 
   3317   :http:statuscode:`200 OK`:
   3318     The backend has successfully returned the inventory. Returns
   3319     a `FullInventoryDetailsResponse`.
   3320   :http:statuscode:`404 Not found`:
   3321     The backend has does not know about the instance.
   3322 
   3323   **Details:**
   3324 
   3325   .. ts:def:: FullInventoryDetailsResponse
   3326 
   3327     interface FullInventoryDetailsResponse {
   3328 
   3329       // List of products that are present in the inventory.
   3330       products: MerchantPosProductDetail[];
   3331 
   3332       // List of categories in the inventory.
   3333       categories: MerchantCategory[];
   3334 
   3335     }
   3336 
   3337   .. ts:def:: MerchantPosProductDetail
   3338 
   3339     interface MerchantPosProductDetail {
   3340 
   3341       // A unique numeric ID of the product
   3342       product_serial: Integer;
   3343 
   3344       // A merchant-internal unique identifier for the product.
   3345       product_id: string;
   3346 
   3347       // Human-readable product name.
   3348       // Since API version **v20**.
   3349       product_name: string;
   3350 
   3351       // A list of category IDs this product belongs to.
   3352       // Typically, a product only belongs to one category, but more than one is supported.
   3353       categories: Integer[];
   3354 
   3355       // Human-readable product description.
   3356       description: string;
   3357 
   3358       // Map from IETF BCP 47 language tags to localized descriptions.
   3359       description_i18n: { [lang_tag: string]: string };
   3360 
   3361       // Unit in which the product is measured (liters, kilograms, packages, etc.).
   3362       unit: string;
   3363 
   3364       // Does the backend allow fractional quantities for this unit?
   3365       unit_allow_fraction: boolean;
   3366 
   3367       // Maximum fractional precision (0-6) enforced for inventory operations.
   3368       unit_precision_level: Integer;
   3369 
   3370       // Price tiers for this product. The first entry represents the base price and MUST include
   3371       // applicable taxes. Zero implies the product is not sold separately or that the price is not
   3372       // fixed, and must be supplied by the front-end.
   3373       unit_price: Amount[];
   3374 
   3375       // Legacy price field kept for compatibility. Deprecated; equal to the first element of ``unit_price``.
   3376       price: Amount;
   3377 
   3378       // An optional base64-encoded product image.
   3379       image?: ImageDataUrl;
   3380 
   3381       // A list of taxes paid by the merchant for one unit of this product.
   3382       taxes?: Tax[];
   3383 
   3384       // Legacy integer stock counter kept for compatibility. ``-1`` indicates unlimited stock.
   3385       total_stock?: Integer;
   3386 
   3387       // Stock expressed using "<integer>[.<fraction>]" syntax with up to six fractional digits.
   3388       // Use ``"-1"`` for unlimited stock.
   3389       unit_total_stock: string;
   3390 
   3391       // Minimum age buyer must have (in years).
   3392       minimum_age?: Integer;
   3393 
   3394     }
   3395 
   3396   .. ts:def:: MerchantCategory
   3397 
   3398     interface MerchantCategory {
   3399       // A unique numeric ID of the category
   3400       id: Integer;
   3401 
   3402       // The name of the category. This will be shown to users and used in the order summary.
   3403       name: string;
   3404 
   3405       // Map from IETF BCP 47 language tags to localized names
   3406       name_i18n?: { [lang_tag: string]: string };
   3407     }
   3408 
   3409 
   3410 Fetching product images
   3411 ^^^^^^^^^^^^^^^^^^^^^^^
   3412 
   3413 .. http:get:: /products/$IMAGE_HASH/image
   3414 
   3415   Returns a stored product image by its content hash. The hash is the lowercase
   3416   hexadecimal SHA-256 digest of the base64-encoded image data supplied in
   3417   ``image`` during product creation or update.
   3418 
   3419   **Required permission:** none (public endpoint)
   3420 
   3421   **Response:**
   3422 
   3423   :http:statuscode:`200 OK`:
   3424     The body is a `ProductImageResponse`.
   3425   :http:statuscode:`400 Bad Request`:
   3426     The hash is not a valid hex-encoded SHA-256 digest.
   3427   :http:statuscode:`404 Not found`:
   3428     No image is known for the given hash.
   3429 
   3430   .. ts:def:: ProductImageResponse
   3431 
   3432     interface ProductImageResponse {
   3433       // Data URL containing the product image as stored in the backend.
   3434       image: ImageDataUrl;
   3435     }
   3436 
   3437 
   3438 
   3439 Reserving inventory
   3440 ^^^^^^^^^^^^^^^^^^^
   3441 
   3442 .. http:post:: [/instances/$INSTANCE]/private/products/$PRODUCT_ID/lock
   3443 
   3444   This is used to lock a certain quantity of the product for a limited
   3445   duration while the customer assembles a complete order.  Note that
   3446   frontends do not have to "unlock", they may rely on the timeout as
   3447   given in the ``duration`` field.  Re-posting a lock with a different
   3448   ``duration`` or ``quantity`` updates the existing lock for the same UUID
   3449   and does not result in a conflict.
   3450 
   3451   Unlocking by using a ``quantity`` of zero is
   3452   optional but recommended if customers remove products from the
   3453   shopping cart. Note that actually POSTing to ``/orders`` with set
   3454   ``inventory_products`` and using ``lock_uuids`` will **transition** the
   3455   lock to the newly created order (which may have a different ``duration``
   3456   and ``quantity`` than what was requested in the lock operation).
   3457   If an order is for fewer items than originally locked, the difference
   3458   is automatically unlocked.
   3459 
   3460   **Required permission:** ``products-lock``
   3461 
   3462   **Request:**
   3463 
   3464   The request must be a `LockRequest`.
   3465 
   3466   **Response:**
   3467 
   3468   :http:statuscode:`204 No content`:
   3469     The backend has successfully locked (or unlocked) the requested ``quantity``.
   3470   :http:statuscode:`404 Not found`:
   3471     The backend has does not know this product.
   3472   :http:statuscode:`410 Gone`:
   3473     The backend does not have enough of product in stock. Returns an `OutOfStockResponse`.
   3474 
   3475   **Details:**
   3476 
   3477   .. ts:def:: LockRequest
   3478 
   3479     interface LockRequest {
   3480 
   3481       // UUID that identifies the frontend performing the lock
   3482       // Must be unique for the lifetime of the lock.
   3483       lock_uuid: string;
   3484 
   3485       // How long does the frontend intend to hold the lock?
   3486       duration: RelativeTime;
   3487 
   3488       // Legacy integer quantity to lock. Deprecated; defaults to 1 if both
   3489       // ``quantity`` and ``unit_quantity`` are absent.
   3490       quantity?: Integer;
   3491 
   3492       // Preferred way to express the requested quantity using "<integer>[.<fraction>]" syntax.
   3493       unit_quantity?: string;
   3494 
   3495     }
   3496 
   3497   At least one of ``quantity`` or ``unit_quantity`` must be supplied; omitting both defaults to a
   3498   quantity of one. ``unit_quantity`` follows the same decimal-string format described for
   3499   ``unit_total_stock``.
   3500 
   3501   .. note::
   3502 
   3503     The ``GNUNET_CRYPTO_random_timeflake()`` C API can be used
   3504     to generate such timeflakes for clients written in C.
   3505 
   3506 
   3507 Removing products from inventory
   3508 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   3509 
   3510 .. http:delete:: [/instances/$INSTANCE]/private/products/$PRODUCT_ID
   3511 
   3512   Delete information about a product.  Fails if the product is locked by
   3513   anyone.
   3514 
   3515   **Required permission:** ``products-write``
   3516 
   3517   **Response:**
   3518 
   3519   :http:statuscode:`204 No content`:
   3520     The backend has successfully deleted the product.
   3521   :http:statuscode:`404 Not found`:
   3522     The backend does not know the instance or the product.
   3523   :http:statuscode:`409 Conflict`:
   3524     The backend refuses to delete the product because it is locked.
   3525 
   3526 
   3527 ------------------
   3528 Payment processing
   3529 ------------------
   3530 
   3531 To process Taler payments, a merchant must first set up an order with
   3532 the merchant backend. The order is then claimed by a wallet, and
   3533 paid by the wallet. The merchant can check the payment status of the
   3534 order. Once the order is paid, the merchant may (for a limited time)
   3535 grant refunds on the order.
   3536 
   3537 Creating orders
   3538 ^^^^^^^^^^^^^^^
   3539 
   3540 .. _post-order:
   3541 
   3542 .. http:post:: [/instances/$INSTANCE]/private/orders
   3543 
   3544   Create a new order that a customer can pay for.
   3545 
   3546   This request is **not** idempotent unless an ``order_id`` is explicitly specified.
   3547   However, while repeating without an ``order_id`` will create another order, that is
   3548   generally pretty harmless (as long as only one of the orders is returned to the wallet).
   3549 
   3550   .. note::
   3551 
   3552     This endpoint does not return a URL to redirect your user to confirm the
   3553     payment.  To get this URL use either
   3554     :http:get:`[/instances/$INSTANCE]/orders/$ORDER_ID` (with
   3555     ``taler_pay_uri`` in the `StatusUnpaidResponse`), or
   3556     :http:get:`[/instances/$INSTANCE]/private/orders/$ORDER_ID` with the
   3557     ``taler_pay_uri`` in the `CheckPaymentUnpaidResponse`). That said,
   3558     it is also possible to construct the URL by combining the base URL
   3559     with the information from the `PostOrderResponse`.
   3560     The API is structured this way since the payment redirect URL is not
   3561     unique for every order: there might be varying parameters such as the
   3562     session id.
   3563 
   3564   **Required permission:** ``orders-write``
   3565 
   3566   **Request:**
   3567 
   3568   The request must be a `PostOrderRequest`.
   3569 
   3570   **Response:**
   3571 
   3572   :http:statuscode:`200 OK`:
   3573     The backend has successfully created the proposal.  The response is a
   3574     :ts:type:`PostOrderResponse`.
   3575   :http:statuscode:`404 Not found`:
   3576     Possible reasons are:
   3577 
   3578     (1) The order given used products from the inventory, but those were
   3579         not found in the inventory.
   3580     (2) The merchant instance is unknown (including possibly the instance
   3581         being not configured for new orders).
   3582     (3) The wire method specified is not supported by the backend.
   3583     (4) An OTP device ID was specified and is unknown.
   3584 
   3585     Details in the error code.
   3586     NOTE: currently the client has no good way to find out which product
   3587     is not in the inventory, we MAY want to specify that in the reply.
   3588   :http:statuscode:`409 Conflict`:
   3589     A different proposal already exists under the specified order ID,
   3590     or the requested currency is not supported by this backend. Details in
   3591     the error code.
   3592   :http:statuscode:`410 Gone`:
   3593     The order given used products from the inventory that are out of stock.
   3594     The response is a :ts:type:`OutOfStockResponse`.
   3595   :http:statuscode:`451 Unavailable for Legal Reasons`:
   3596     The order could not be created because of legal
   3597     reasons, specifically no exchange would accept
   3598     a payment at this time because we have not yet
   3599     satisfied the respective legal requirements.
   3600     The :ref:`KYC status <merchantkycstatus>` API
   3601     can be used to determine details about how to
   3602     proceed with the KYC process.
   3603     The body is a `PaymentDeniedLegallyResponse` with
   3604     details about the exchange(s) causing the failure.
   3605     Since protocol **v17**.
   3606 
   3607   **Details:**
   3608 
   3609   .. ts:def:: PostOrderRequest
   3610 
   3611     interface PostOrderRequest {
   3612       // The order must at least contain the minimal
   3613       // order detail, but can override all.
   3614       order: Order;
   3615 
   3616       // If set, the backend will then set the refund deadline to the
   3617       // payment deadline plus the specified delay.
   3618       // If it's not set, the default value of the backend might be
   3619       // used. Note that both this value and the backend default
   3620       // will be ignored if ``refund_deadline`` is set in ``order``
   3621       // as the ``refund_deadline`` takes precedence.
   3622       // A value of "forever" is not allowed.
   3623       refund_delay?: RelativeTime;
   3624 
   3625       // Specifies the payment target preferred by the client. Can be used
   3626       // to select among the various (active) wire methods supported by the instance.
   3627       payment_target?: string;
   3628 
   3629       // The session for which the payment is made (or replayed).
   3630       // Only set for session-based payments.
   3631       // Since protocol **v6**.
   3632       session_id?: string;
   3633 
   3634       // Specifies that some products are to be included in the
   3635       // order from the inventory.  For these inventory management
   3636       // is performed (so the products must be in stock) and
   3637       // details are completed from the product data of the backend.
   3638       inventory_products?: MinimalInventoryProduct[];
   3639 
   3640       // Specifies a lock identifier that was used to
   3641       // lock a product in the inventory.  Only useful if
   3642       // ``inventory_products`` is set.  Used in case a frontend
   3643       // reserved quantities of the individual products while
   3644       // the shopping cart was being built.  Multiple UUIDs can
   3645       // be used in case different UUIDs were used for different
   3646       // products (i.e. in case the user started with multiple
   3647       // shopping sessions that were combined during checkout).
   3648       lock_uuids?: string[];
   3649 
   3650       // Should a token for claiming the order be generated?
   3651       // False can make sense if the ORDER_ID is sufficiently
   3652       // high entropy to prevent adversarial claims (like it is
   3653       // if the backend auto-generates one). Default is 'true'.
   3654       // Note: This is NOT related to tokens used for subscriptins or discounts.
   3655       create_token?: boolean;
   3656 
   3657       // OTP device ID to associate with the order.
   3658       // This parameter is optional.
   3659       otp_id?: string;
   3660     }
   3661 
   3662   The `Order` object represents the starting point for new `ContractTerms`.
   3663   After validating and sanatizing all inputs, the merchant backend will add
   3664   additional information to the order and create a new `ContractTerms` object
   3665   that will be stored in the database.
   3666 
   3667   .. ts:def:: Order
   3668 
   3669     type Order = (OrderV1 | OrderV0) & OrderCommon;
   3670 
   3671   .. ts:def:: OrderV1
   3672 
   3673     interface OrderV1 {
   3674       // Version 1 order support discounts and subscriptions.
   3675       // https://docs.taler.net/design-documents/046-mumimo-contracts.html
   3676       // @since protocol **v21**
   3677       version: 1;
   3678 
   3679       // List of contract choices that the customer can select from.
   3680       // @since protocol **v21**
   3681       choices?: OrderChoice[];
   3682     }
   3683 
   3684   .. ts:def:: OrderV0
   3685 
   3686     interface OrderV0 {
   3687       // Optional, defaults to 0 if not set.
   3688       version?: 0;
   3689 
   3690       // Total price for the transaction. The exchange will subtract deposit
   3691       // fees from that amount before transferring it to the merchant.
   3692       amount: Amount;
   3693 
   3694       // Maximum total deposit fee accepted by the merchant for this contract.
   3695       // Overrides defaults of the merchant instance.
   3696       max_fee?: Amount;
   3697     }
   3698 
   3699   .. ts:def:: OrderCommon
   3700 
   3701     interface OrderCommon {
   3702       // Human-readable description of the whole purchase.
   3703       summary: string;
   3704 
   3705       // Map from IETF BCP 47 language tags to localized summaries.
   3706       summary_i18n?: { [lang_tag: string]: string };
   3707 
   3708       // Unique identifier for the order. Only characters
   3709       // allowed are "A-Za-z0-9" and ".:_-".
   3710       // Must be unique within a merchant instance.
   3711       // For merchants that do not store proposals in their DB
   3712       // before the customer paid for them, the ``order_id`` can be used
   3713       // by the frontend to restore a proposal from the information
   3714       // encoded in it (such as a short product identifier and timestamp).
   3715       order_id?: string;
   3716 
   3717       // URL where the same contract could be ordered again (if
   3718       // available). Returned also at the public order endpoint
   3719       // for people other than the actual buyer (hence public,
   3720       // in case order IDs are guessable).
   3721       public_reorder_url?: string;
   3722 
   3723       // See documentation of ``fulfillment_url`` field in `ContractTerms`.
   3724       // Either fulfillment_url or fulfillment_message must be specified.
   3725       // When creating an order, the fulfillment URL can
   3726       // contain ``${ORDER_ID}`` which will be substituted with the
   3727       // order ID of the newly created order.
   3728       fulfillment_url?: string;
   3729 
   3730       // See documentation of ``fulfillment_message`` in `ContractTerms`.
   3731       // Either ``fulfillment_url`` or ``fulfillment_message`` must be specified.
   3732       fulfillment_message?: string;
   3733 
   3734       // Map from IETF BCP 47 language tags to localized fulfillment
   3735       // messages.
   3736       fulfillment_message_i18n?: { [lang_tag: string]: string };
   3737 
   3738       // Minimum age the buyer must have to buy.
   3739       minimum_age?: Integer;
   3740 
   3741       // List of products that are part of the purchase.
   3742       products?: Product[];
   3743 
   3744       // Time when this contract was generated. If null, defaults to current
   3745       // time of merchant backend.
   3746       timestamp?: Timestamp;
   3747 
   3748       // After this deadline has passed, no refunds will be accepted.
   3749       // Overrides deadline calculated from ``refund_delay`` in
   3750       // ``PostOrderRequest``.
   3751       // A value of "never" is not allowed.
   3752       refund_deadline?: Timestamp;
   3753 
   3754       // After this deadline, the merchant won't accept payments for the contract.
   3755       // Overrides deadline calculated from default pay delay configured in
   3756       // merchant backend.
   3757       // A value of "never" is not allowed.
   3758       pay_deadline?: Timestamp;
   3759 
   3760       // Transfer deadline for the exchange. Must be in the deposit permissions
   3761       // of coins used to pay for this order.
   3762       // Overrides deadline calculated from default wire transfer delay
   3763       // configured in merchant backend. Must be after refund deadline.
   3764       // A value of "never" is not allowed.
   3765       wire_transfer_deadline?: Timestamp;
   3766 
   3767       // Base URL of the (public!) merchant backend API.
   3768       // Must be an absolute URL that ends with a slash.
   3769       // Defaults to the base URL this request was made to.
   3770       merchant_base_url?: string;
   3771 
   3772       // Delivery location for (all!) products.
   3773       delivery_location?: Location;
   3774 
   3775       // Time indicating when the order should be delivered.
   3776       // May be overwritten by individual products.
   3777       // Must be in the future.
   3778       delivery_date?: Timestamp;
   3779 
   3780       // See documentation of ``auto_refund`` in ``ContractTerms``.
   3781       // Specifies for how long the wallet should try to get an
   3782       // automatic refund for the purchase.
   3783       auto_refund?: RelativeTime;
   3784 
   3785       // Extra data that is only interpreted by the merchant frontend.
   3786       // Useful when the merchant needs to store extra information on a
   3787       // contract without storing it separately in their database.
   3788       // Must really be an Object (not a string, integer, float or array).
   3789       extra?: Object;
   3790     }
   3791 
   3792 
   3793   The `OrderChoice` object describes a possible choice within an order. The
   3794   choice is done by the wallet and consists of in- and outputs. In the example
   3795   of buying an article, the merchant could present the customer with the
   3796   choice to use a valid subscription token or pay using a gift
   3797   voucher. Available since protocol **v21**.
   3798 
   3799   .. ts:def:: OrderChoice
   3800 
   3801     interface OrderChoice {
   3802       // Total price for the choice. The exchange will subtract deposit
   3803       // fees from that amount before transferring it to the merchant.
   3804       amount: Amount;
   3805 
   3806       // Human readable description of the semantics of the choice
   3807       // within the contract to be shown to the user at payment.
   3808       description?: string;
   3809 
   3810       // Map from IETF 47 language tags to localized descriptions.
   3811       description_i18n?: { [lang_tag: string]: string };
   3812 
   3813       // Inputs that must be provided by the customer, if this choice is selected.
   3814       // Defaults to empty array if not specified.
   3815       inputs?: OrderInput[];
   3816 
   3817       // Outputs provided by the merchant, if this choice is selected.
   3818       // Defaults to empty array if not specified.
   3819       outputs?: OrderOutput[];
   3820 
   3821       // Maximum total deposit fee accepted by the merchant for this contract.
   3822       // Overrides defaults of the merchant instance.
   3823       max_fee?: Amount;
   3824     }
   3825 
   3826   .. ts:def:: OrderInput
   3827 
   3828     // For now, only token inputs are supported.
   3829     type OrderInput = OrderInputToken;
   3830 
   3831   .. ts:def:: OrderInputToken
   3832 
   3833     interface OrderInputToken {
   3834 
   3835       // Token input.
   3836       type: "token";
   3837 
   3838       // Token family slug as configured in the merchant backend. Slug is unique
   3839       // across all configured tokens of a merchant.
   3840       token_family_slug: string;
   3841 
   3842       // How many units of the input are required.
   3843       // Defaults to 1 if not specified. Output with count == 0 are ignored by
   3844       // the merchant backend.
   3845       count?: Integer;
   3846 
   3847     }
   3848 
   3849   .. ts:def:: OrderOutput
   3850 
   3851     type OrderOutput = OrderOutputToken | OrderOutputTaxReceipt;
   3852 
   3853   .. ts:def:: OrderOutputToken
   3854 
   3855     interface OrderOutputToken {
   3856 
   3857       // Token output.
   3858       type: "token";
   3859 
   3860       // Token family slug as configured in the merchant backend. Slug is unique
   3861       // across all configured tokens of a merchant.
   3862       token_family_slug: string;
   3863 
   3864       // How many units of the output are issued by the merchant.
   3865       // Defaults to 1 if not specified. Output with count == 0 are ignored by
   3866       // the merchant backend.
   3867       count?: Integer;
   3868 
   3869       // When should the output token be valid. Can be specified if the
   3870       // desired validity period should be in the future (like selling
   3871       // a subscription for the next month). Optional. If not given,
   3872       // the validity is supposed to be "now" (time of order creation).
   3873       valid_at?: Timestamp;
   3874 
   3875     }
   3876 
   3877   .. ts:def:: OrderOutputTaxReceipt
   3878 
   3879     interface OrderOutputTaxReceipt {
   3880 
   3881       // Tax receipt output.
   3882       type: "tax-receipt";
   3883 
   3884     }
   3885 
   3886   The following `MinimalInventoryProduct` can be provided if the parts of the
   3887   order are inventory-based, that is if the `PostOrderRequest` uses
   3888   ``inventory_products``. For such products, which must be in the backend's inventory,
   3889   the backend can automatically fill in the amount and other details about
   3890   the product that are known to it from its ``products`` table.
   3891   Note that the ``inventory_products`` will be appended to the
   3892   list of ``products`` that the frontend already put into the ``order``.
   3893   So if the frontend can sell additional non-inventory products together
   3894   with ``inventory_products``.  Note that the backend will NOT update
   3895   the ``amount`` of the ``order``, so the frontend must already have calculated
   3896   the total price --- including the ``inventory_products``.
   3897 
   3898   .. ts:def:: MinimalInventoryProduct
   3899 
   3900     // Note that if the frontend does give details beyond these,
   3901     // it will override those details (including price or taxes)
   3902     // that the backend would otherwise fill in via the inventory.
   3903     interface MinimalInventoryProduct {
   3904 
   3905       // Which product is requested (here mandatory!).
   3906       product_id: string;
   3907 
   3908       // Legacy integer quantity. Deprecated; defaults to 1 if both
   3909       // ``quantity`` and ``unit_quantity`` are absent.
   3910       quantity?: Integer;
   3911 
   3912       // Preferred quantity string using "<integer>[.<fraction>]" syntax.
   3913       unit_quantity?: string;
   3914     }
   3915 
   3916   Supply either ``quantity`` or ``unit_quantity`` when referencing inventory products. If both are
   3917   missing the backend assumes a quantity of one. ``unit_quantity`` follows the same decimal-string
   3918   rules as ``unit_total_stock``.
   3919 
   3920   .. ts:def:: PostOrderResponse
   3921 
   3922     interface PostOrderResponse {
   3923       // Order ID of the response that was just created.
   3924       order_id: string;
   3925 
   3926       // Deadline when the offer expires; the customer must pay before.
   3927       // @since protocol **v21**.
   3928       pay_deadline: Timestamp;
   3929 
   3930       // Token that authorizes the wallet to claim the order.
   3931       // Provided only if "create_token" was set to 'true'
   3932       // in the request.
   3933       token?: ClaimToken;
   3934     }
   3935 
   3936   .. ts:def:: OutOfStockResponse
   3937 
   3938     interface OutOfStockResponse {
   3939 
   3940       // Product ID of an out-of-stock item.
   3941       product_id: string;
   3942 
   3943       // Legacy integer quantity requested. Deprecated; see ``unit_requested_quantity``.
   3944       requested_quantity: Integer;
   3945 
   3946       // Requested quantity using "<integer>[.<fraction>]" syntax with up to six fractional digits.
   3947       unit_requested_quantity: string;
   3948 
   3949       // Legacy integer availability (must be below ``requested_quantity``).
   3950       available_quantity: Integer;
   3951 
   3952       // Available quantity using "<integer>[.<fraction>]" syntax with up to six fractional digits.
   3953       unit_available_quantity: string;
   3954 
   3955       // When do we expect the product to be again in stock?
   3956       // Optional, not given if unknown.
   3957       restock_expected?: Timestamp;
   3958     }
   3959 
   3960 
   3961 Inspecting orders
   3962 ^^^^^^^^^^^^^^^^^
   3963 
   3964 .. http:get:: [/instances/$INSTANCE]/private/orders
   3965 
   3966   Returns known orders up to some point in the past.
   3967 
   3968   **Required permission:** ``orders-read``
   3969 
   3970   **Request:**
   3971 
   3972   :query paid: *Optional*. If set to yes, only return paid orders, if no only unpaid orders. Do not give (or use "all") to see all orders regardless of payment status.
   3973   :query refunded: *Optional*. If set to yes, only return refunded orders, if no only unrefunded orders. Do not give (or use "all") to see all orders regardless of refund status.
   3974   :query wired: *Optional*. If set to yes, only return wired orders, if no only orders with missing wire transfers. Do not give (or use "all") to see all orders regardless of wire transfer status.
   3975   :query delta: *Optional*. takes value of the form ``N (-N)``, so that at most ``N`` values strictly older (younger) than ``start`` and ``date_s`` are returned.  Defaults to ``-20`` to return the last 20 entries (before ``start`` and/or ``date_s``).  Deprecated in protocol **v12**. Use *limit* instead.
   3976   :query limit: *Optional*. At most return the given number of results. Negative for descending by row ID, positive for ascending by row ID. Default is ``20``.  Since protocol **v12**.
   3977   :query date_s: *Optional.* Non-negative date in seconds after the UNIX Epoc, see ``delta`` for its interpretation.  If not specified, we default to the oldest or most recent entry, depending on ``limit``.
   3978   :query start: *Optional*. Row number threshold, see ``limit`` for its interpretation.  Defaults to ``INT64_MAX``, namely the biggest row id possible in the database. Deprecated in protocol **v12**. Use *offset* instead.
   3979   :query offset: *Optional*. Starting ``row_id`` for an iteration.  Since protocol **v12**.
   3980   :query timeout_ms: *Optional*. Timeout in milliseconds to wait for additional orders if the answer would otherwise be negative (long polling). Only useful if ``limit`` is positive. Note that the merchant MAY still return a response that contains fewer than ``limit`` orders.
   3981   :query session_id: *Optional*. Since protocol **v6**. Filters by session ID.
   3982   :query fulfillment_url: *Optional*. Since protocol **v6**. Filters by fulfillment URL.
   3983   :query summary_filter: *Optional*. Only returns orders where the summary contains the given text as a substring. Matching is case-insensitive. Since protocol **v23**.
   3984 
   3985   **Response:**
   3986 
   3987   :http:statuscode:`200 OK`:
   3988     The response is an `OrderHistory`.
   3989 
   3990   **Details:**
   3991 
   3992   .. ts:def:: OrderHistory
   3993 
   3994     interface OrderHistory {
   3995       // Timestamp-sorted array of all orders matching the query.
   3996       // The order of the sorting depends on the sign of ``limit``.
   3997       orders : OrderHistoryEntry[];
   3998     }
   3999 
   4000 
   4001   .. ts:def:: OrderHistoryEntry
   4002 
   4003     interface OrderHistoryEntry {
   4004 
   4005       // Order ID of the transaction related to this entry.
   4006       order_id: string;
   4007 
   4008       // Row ID of the order in the database.
   4009       row_id: Integer;
   4010 
   4011       // When the order was created.
   4012       timestamp: Timestamp;
   4013 
   4014       // The amount of money the order is for. If the contract
   4015       // has multiple choices and the user has not yet made a choice,
   4016       // we return the amount of the first choice.
   4017       amount: Amount;
   4018 
   4019       // The total amount of refunds granted by the merchant.
   4020       // Includes refunds that the wallet did not yet pick up.
   4021       // Only available if the order was paid.
   4022       // Since **v24**.
   4023       refund_amount: Amount;
   4024 
   4025       // The amount of refunds the customer's wallet did not yet
   4026       // pick up.  Only available if the order was paid.
   4027       // Since **v24**.
   4028       pending_refund_amount: Amount;
   4029 
   4030       // The summary of the order.
   4031       summary: string;
   4032 
   4033       // Whether some part of the order is refundable,
   4034       // that is the refund deadline has not yet expired
   4035       // and the total amount refunded so far is below
   4036       // the value of the original transaction.
   4037       refundable: boolean;
   4038 
   4039       // Whether the order has been paid or not.
   4040       paid: boolean;
   4041     }
   4042 
   4043 .. http:get:: [/instances/$INSTANCE]/private/orders/$ORDER_ID
   4044 
   4045   Merchant checks the payment status of an order.  If the order exists but is not paid
   4046   and not claimed yet, the response provides a redirect URL.  When the user goes to this URL,
   4047   they will be prompted for payment.  Differs from the ``public`` API both
   4048   in terms of what information is returned and in that the wallet must provide
   4049   the contract hash to authenticate, while for this API we assume that the
   4050   merchant is authenticated (as the endpoint is not ``public``).
   4051 
   4052   **Required permission:** ``orders-read``
   4053 
   4054   **Request:**
   4055 
   4056   :query session_id: *Optional*. Session ID that the payment must be bound to.  If not specified, the payment is not session-bound.
   4057   :query transfer: Deprecated in protocol **V6**. *Optional*. If set to "YES", try to obtain the wire transfer status for this order from the exchange. Otherwise, the wire transfer status MAY be returned if it is available.
   4058   :query timeout_ms: *Optional*. Timeout in milliseconds to wait for a payment if the answer would otherwise be negative (long polling).
   4059   :query allow_refunded_for_repurchase: *Optional*. Since protocol **v9** refunded orders are only returned under "already_paid_order_id" if this flag is set explicitly to "YES".
   4060 
   4061   **Response:**
   4062 
   4063   :http:statuscode:`200 OK`:
   4064     Returns a `MerchantOrderStatusResponse`, whose format can differ based on the status of the payment.
   4065   :http:statuscode:`404 Not found`:
   4066     The order or instance is unknown to the backend. Error code
   4067     is set to either ``MERCHANT_GENERIC_ORDER_UNKNOWN`` or
   4068     ``MERCHANT_GENERIC_INSTANCE_UNKNOWN``.
   4069 
   4070   **Details:**
   4071 
   4072   .. ts:def:: MerchantOrderStatusResponse
   4073 
   4074     type MerchantOrderStatusResponse = CheckPaymentPaidResponse |
   4075                                        CheckPaymentClaimedResponse |
   4076                                        CheckPaymentUnpaidResponse;
   4077 
   4078   .. ts:def:: CheckPaymentPaidResponse
   4079 
   4080     interface CheckPaymentPaidResponse {
   4081       // The customer paid for this contract.
   4082       order_status: "paid";
   4083 
   4084       // Was the payment refunded (even partially)?
   4085       refunded: boolean;
   4086 
   4087       // True if there are any approved refunds that the wallet has
   4088       // not yet obtained.
   4089       refund_pending: boolean;
   4090 
   4091       // Did the exchange wire us the funds?
   4092       wired: boolean;
   4093 
   4094       // Total amount the exchange deposited into our bank account
   4095       // for this contract, excluding fees.
   4096       deposit_total: Amount;
   4097 
   4098       // Numeric `error code <error-codes>` indicating errors the exchange
   4099       // encountered tracking the wire transfer for this purchase (before
   4100       // we even got to specific coin issues).
   4101       // 0 if there were no issues.
   4102       exchange_code: Integer;
   4103 
   4104       // HTTP status code returned by the exchange when we asked for
   4105       // information to track the wire transfer for this purchase.
   4106       // 0 if there were no issues.
   4107       exchange_http_status: Integer;
   4108 
   4109       // Total amount that was refunded, 0 if refunded is false.
   4110       refund_amount: Amount;
   4111 
   4112       // Contract terms.
   4113       contract_terms: ContractTerms;
   4114 
   4115       // Index of the selected choice within the ``choices`` array of
   4116       // ``contract terms``.
   4117       // @since protocol **v21**
   4118       choice_index?: Integer;
   4119 
   4120       // If the order is paid, set to the last time when a payment
   4121       // was made to pay for this order. @since **v14**.
   4122       last_payment: Timestamp;
   4123 
   4124       // The wire transfer status from the exchange for this order if
   4125       // available, otherwise empty array.
   4126       wire_details: TransactionWireTransfer[];
   4127 
   4128       // Reports about trouble obtaining wire transfer details,
   4129       // empty array if no trouble were encountered.
   4130       // @deprecated in protocol **v6**.
   4131       wire_reports: TransactionWireReport[];
   4132 
   4133       // The refund details for this order.  One entry per
   4134       // refunded coin; empty array if there are no refunds.
   4135       refund_details: RefundDetails[];
   4136 
   4137       // Status URL, can be used as a redirect target for the browser
   4138       // to show the order QR code / trigger the wallet.
   4139       order_status_url: string;
   4140     }
   4141 
   4142   .. ts:def:: CheckPaymentClaimedResponse
   4143 
   4144     interface CheckPaymentClaimedResponse {
   4145       // A wallet claimed the order, but did not yet pay for the contract.
   4146       order_status: "claimed";
   4147 
   4148       // Contract terms.
   4149       contract_terms: ContractTerms;
   4150 
   4151       // Status URL, can be used as a redirect target for the browser
   4152       // to show the order QR code / trigger the wallet.
   4153       // Since protocol **v19**.
   4154       order_status_url: string;
   4155     }
   4156 
   4157   .. ts:def:: CheckPaymentUnpaidResponse
   4158 
   4159     interface CheckPaymentUnpaidResponse {
   4160       // The order was neither claimed nor paid.
   4161       order_status: "unpaid";
   4162 
   4163       // URI that the wallet must process to complete the payment.
   4164       taler_pay_uri: string;
   4165 
   4166       // Time when the order was created.
   4167       creation_time: Timestamp;
   4168 
   4169       // Deadline when the offer expires; the customer must pay before.
   4170       // @since protocol **v21**.
   4171       pay_deadline: Timestamp;
   4172 
   4173       // Order summary text.
   4174       summary: string;
   4175 
   4176       // Total amount of the order (to be paid by the customer).
   4177       // Will be undefined for unpaid v1 orders
   4178       total_amount?: Amount;
   4179 
   4180       // Alternative order ID which was paid for already in the same session.
   4181       // Only given if the same product was purchased before in the same session.
   4182       already_paid_order_id?: string;
   4183 
   4184       // Fulfillment URL of an already paid order. Only given if under this
   4185       // session an already paid order with a fulfillment URL exists.
   4186       already_paid_fulfillment_url?: string;
   4187 
   4188       // Status URL, can be used as a redirect target for the browser
   4189       // to show the order QR code / trigger the wallet.
   4190       order_status_url: string;
   4191 
   4192       // We do we NOT return the contract terms here because they may not
   4193       // exist in case the wallet did not yet claim them.
   4194     }
   4195 
   4196   .. ts:def:: RefundDetails
   4197 
   4198     interface RefundDetails {
   4199       // Reason given for the refund.
   4200       reason: string;
   4201 
   4202       // True if a refund is still available for the wallet for this payment.
   4203       pending: boolean;
   4204 
   4205       // When was the refund approved with a POST to
   4206       // [/instances/$INSTANCE]/private/orders/$ORDER_ID/refund
   4207       timestamp: Timestamp;
   4208 
   4209       // Total amount that was refunded (minus a refund fee).
   4210       amount: Amount;
   4211     }
   4212 
   4213   .. ts:def:: TransactionWireTransfer
   4214 
   4215     interface TransactionWireTransfer {
   4216       // Responsible exchange.
   4217       exchange_url: string;
   4218 
   4219       // 32-byte wire transfer identifier.
   4220       wtid: Base32;
   4221 
   4222       // Execution time of the wire transfer.
   4223       execution_time: Timestamp;
   4224 
   4225       // Total amount that has been wire transferred
   4226       // to the merchant.
   4227       amount: Amount;
   4228 
   4229       // Was this transfer confirmed by the merchant via the
   4230       // POST /transfers API, or is it merely claimed by the exchange?
   4231       confirmed: boolean;
   4232     }
   4233 
   4234   .. ts:def:: TransactionWireReport
   4235 
   4236     interface TransactionWireReport {
   4237       // Numerical `error code <error-codes>`.
   4238       code: Integer;
   4239 
   4240       // Human-readable error description.
   4241       hint: string;
   4242 
   4243       // Numerical `error code <error-codes>` from the exchange.
   4244       exchange_code: Integer;
   4245 
   4246       // HTTP status code received from the exchange.
   4247       exchange_http_status: Integer;
   4248 
   4249       // Public key of the coin for which we got the exchange error.
   4250       coin_pub: CoinPublicKey;
   4251     }
   4252 
   4253 
   4254 
   4255 .. _private-order-data-cleanup:
   4256 
   4257 Private order data cleanup
   4258 ^^^^^^^^^^^^^^^^^^^^^^^^^^
   4259 
   4260 Some orders may contain sensitive information that the merchant may not want
   4261 to retain after fulfillment, such as the customer's shipping address.  By
   4262 initially labeling these order components as forgettable, the merchant can
   4263 later tell the backend to forget those details (without changing the hash of
   4264 the contract!) to minimize risks from information leakage.
   4265 
   4266 
   4267 .. http:patch:: [/instances/$INSTANCE]/private/orders/$ORDER_ID/forget
   4268 
   4269   Forget fields in an order's contract terms that the merchant no
   4270   longer needs.
   4271 
   4272   **Required permission:** ``orders-write``
   4273 
   4274   **Request:**
   4275 
   4276   The request must be a `forget request <ForgetRequest>`. The fields specified
   4277   must have been marked as forgettable when the contract was created. Fields in
   4278   the request that are not in the `contract terms <ContractTerms>` are ignored.
   4279 
   4280   A valid
   4281   JSON path is defined as a string beginning with ``$.`` that follows the dot
   4282   notation: ``$.wire_fee``, for example. The ``$`` represents the `contract terms <ContractTerms>`
   4283   object, and an identifier following a ``.`` represents the field of that
   4284   identifier belonging to the object preceding the dot. Arrays can be indexed
   4285   by an non-negative integer within brackets: ``$.products[1]``. An asterisk ``*``
   4286   can be used to index an array as a wildcard, which expands the path into a
   4287   list of paths containing one path for
   4288   each valid array index: ``$.products[*].description``. For a path to be valid,
   4289   it must end with a reference to a field of an object (it cannot end with an
   4290   array index or wildcard).
   4291 
   4292   **Response:**
   4293 
   4294   :http:statuscode:`200 OK`:
   4295     The merchant deleted the specified fields from the contract of
   4296     order $ORDER_ID.
   4297   :http:statuscode:`204 No content`:
   4298     The merchant had already deleted the specified fields
   4299     from the contract of order $ORDER_ID.
   4300   :http:statuscode:`400 Bad request`:
   4301     The request is malformed or one of the paths is invalid.
   4302   :http:statuscode:`404 Not found`:
   4303     The merchant backend could not find the order or the instance
   4304     and thus cannot process the forget request.
   4305   :http:statuscode:`409 Conflict`:
   4306     The request includes a field that was not marked as forgettable, so
   4307     the merchant cannot delete that field.
   4308 
   4309   **Details:**
   4310 
   4311   .. ts:def:: ForgetRequest
   4312 
   4313     interface ForgetRequest {
   4314 
   4315       // Array of valid JSON paths to forgettable fields in the order's
   4316       // contract terms.
   4317       fields: string[];
   4318     }
   4319 
   4320 
   4321 .. http:delete:: [/instances/$INSTANCE]/private/orders/$ORDER_ID
   4322 
   4323   Delete information about an order.  Fails if the order was paid in the
   4324   last 10 years (or whatever ``TAX_RECORD_EXPIRATION`` is set to) or was
   4325   claimed but is unpaid and thus still a valid offer.
   4326 
   4327   **Response:**
   4328 
   4329   :http:statuscode:`204 No content`:
   4330     The backend has successfully deleted the order.
   4331   :http:statuscode:`404 Not found`:
   4332     The backend does not know the instance or the order.
   4333   :http:statuscode:`409 Conflict`:
   4334     The backend refuses to delete the order.
   4335 
   4336 
   4337 .. _merchant_refund:
   4338 
   4339 -----------------
   4340 Approving Refunds
   4341 -----------------
   4342 
   4343 .. http:post:: [/instances/$INSTANCE]/private/orders/$ORDER_ID/refund
   4344 
   4345   Increase the refund amount associated with a given order.  The user should be
   4346   redirected to the ``taler_refund_uri`` to trigger refund processing in the wallet.
   4347 
   4348   **Required permission:** ``orders-refund``
   4349 
   4350   **Request:**
   4351 
   4352   The request body is a `RefundRequest` object.
   4353 
   4354   **Response:**
   4355 
   4356   :http:statuscode:`200 OK`:
   4357     The refund amount has been increased, the backend
   4358     responds with a `MerchantRefundResponse`.
   4359   :http:statuscode:`403 Forbidden`:
   4360     For the given order, the refund delay was zero and thus
   4361     refunds are categorically not allowed.
   4362   :http:statuscode:`404 Not found`:
   4363     The order is unknown to the merchant.
   4364   :http:statuscode:`410 Gone`:
   4365     It is too late for aborting, the exchange may have already wired the funds
   4366     to the merchant.
   4367   :http:statuscode:`409 Conflict`:
   4368     The refund amount exceeds the amount originally paid.
   4369   :http:statuscode:`451 Unavailable for Legal Reasons`:
   4370     The refund could not be awarded because of legal
   4371     reasons (an exchange would refuse). The merchant
   4372     staff needs to find another way to give a refund
   4373     to the customer.
   4374     The body is a `PaymentDeniedLegallyResponse` with
   4375     details about the exchange causing the failure.
   4376     Since protocol **v17**.
   4377 
   4378   **Details:**
   4379 
   4380   .. ts:def:: RefundRequest
   4381 
   4382     interface RefundRequest {
   4383       // Amount to be refunded.
   4384       refund: Amount;
   4385 
   4386       // Human-readable refund justification.
   4387       reason: string;
   4388     }
   4389 
   4390   .. ts:def:: MerchantRefundResponse
   4391 
   4392     interface MerchantRefundResponse {
   4393 
   4394       // URL (handled by the backend) that the wallet should access to
   4395       // trigger refund processing.
   4396       // taler://refund/...
   4397       taler_refund_uri: string;
   4398 
   4399       // Contract hash that a client may need to authenticate an
   4400       // HTTP request to obtain the above URI in a wallet-friendly way.
   4401       h_contract: HashCode;
   4402     }
   4403 
   4404 
   4405 -----------------------
   4406 Tracking Wire Transfers
   4407 -----------------------
   4408 
   4409 This API is used by merchants that want to track the payments from the
   4410 exchange to be sure that they have been paid on time. By telling the merchant
   4411 backend about all incoming wire transfers, the backend can detect if an
   4412 exchange failed to perform a wire transfer that was due.
   4413 
   4414 
   4415 Informing the backend about incoming wire transfers
   4416 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   4417 
   4418 .. http:post:: [/instances/$INSTANCE]/private/transfers
   4419 
   4420   Inform the backend over an incoming wire transfer. The backend should inquire about the details with the exchange and mark the respective orders as wired.  Note that the request will fail if the WTID is not unique (which should be guaranteed by a correct exchange).
   4421   This request is idempotent and should also be used to merely re-fetch the
   4422   transfer information from the merchant's database (assuming we got a non-error
   4423   response from the exchange before).
   4424 
   4425   **Required permission:** ``transfers-write``
   4426 
   4427   **Request:**
   4428 
   4429    The request must provide `transfer information <TransferInformation>`.
   4430 
   4431   **Response:**
   4432 
   4433   :http:statuscode:`204 No content`:
   4434     The wire transfer is now confirmed at the merchant.
   4435   :http:statuscode:`404 Not found`:
   4436     The instance or account are unknown to the exchange.
   4437   :http:statuscode:`409 Conflict`:
   4438     The wire transfer identifier is already known to us, but for a different amount.
   4439 
   4440   **Details:**
   4441 
   4442   .. ts:def:: TransferInformation
   4443 
   4444     interface TransferInformation {
   4445       // How much was wired to the merchant (minus fees).
   4446       credit_amount: Amount;
   4447 
   4448       // Raw wire transfer identifier identifying the wire transfer (a base32-encoded value).
   4449       wtid: WireTransferIdentifierRawP;
   4450 
   4451       // Full payto://-URI of the bank account that received the wire transfer.
   4452       payto_uri: string;
   4453 
   4454       // Base URL of the exchange that made the wire transfer.
   4455       exchange_url: string;
   4456     }
   4457 
   4458 
   4459 Querying known wire transfers
   4460 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   4461 
   4462 .. http:get:: [/instances/$INSTANCE]/private/transfers
   4463 
   4464   Obtain a list of all wire transfers the backend was told
   4465   had been made into the merchant bank account.
   4466   Since protocol **v20** this endpoint is only about
   4467   actually confirmed wire transfers.
   4468 
   4469   **Required permission:** ``transfers-read``
   4470 
   4471   **Request:**
   4472 
   4473   :query payto_uri: *Optional*. Full payto://-URI to filter for transfers to the given bank account (subject and amount MUST NOT be given in the payto:// URI).  Note that the URI must be URL-encoded.
   4474 
   4475   :query before: *Optional*. Filter for transfers executed before the given timestamp.
   4476 
   4477   :query after: *Optional*. Filter for transfers executed after the given timestamp.
   4478 
   4479   :query limit: *Optional*. At most return the given number of results. Negative for descending in execution time, positive for ascending in execution time. Default is ``-20``.
   4480 
   4481   :query offset: *Optional*. Starting ``transfer_serial_id`` for an iteration.
   4482 
   4483   :query expected: *Optional*. Filter transfers that we expected to receive (YES: only expected, NO: only unexpected, ALL: default). Since protocol **v20**.
   4484 
   4485 
   4486   **Response:**
   4487 
   4488   :http:statuscode:`200 OK`:
   4489     The body of the response is a `TransferList`.
   4490 
   4491   **Details:**
   4492 
   4493   .. ts:def:: TransferList
   4494 
   4495     interface TransferList {
   4496        // List of all the transfers that fit the filter that we know.
   4497        transfers : TransferDetails[];
   4498     }
   4499 
   4500   .. ts:def:: TransferDetails
   4501 
   4502     interface TransferDetails {
   4503       // How much was wired to the merchant (minus fees).
   4504       credit_amount: Amount;
   4505 
   4506       // Raw wire transfer identifier identifying the wire transfer (a base32-encoded value).
   4507       wtid: WireTransferIdentifierRawP;
   4508 
   4509       // Full payto://-URI of the bank account that received the wire transfer.
   4510       payto_uri: string;
   4511 
   4512       // Base URL of the exchange that made the wire transfer.
   4513       exchange_url: string;
   4514 
   4515       // Serial number identifying the transfer in the merchant backend.
   4516       // Used for filtering via ``offset``.
   4517       transfer_serial_id: Integer;
   4518 
   4519       // Time of the execution of the wire transfer.
   4520       execution_time: Timestamp;
   4521 
   4522       // True if we checked the exchange's answer and are happy with it.
   4523       // False if we have an answer and are unhappy, missing if we
   4524       // do not have an answer from the exchange.
   4525       // Removed in protocol **v20**.
   4526       verified?: boolean;
   4527 
   4528       // True if the merchant uses the POST /transfers API to confirm
   4529       // that this wire transfer took place (and it is thus not
   4530       // something merely claimed by the exchange).
   4531       // Removed in protocol **v20**.
   4532       confirmed?: boolean;
   4533 
   4534       // True if this wire transfer was expected.
   4535       // (a matching "/private/incoming" record exists).
   4536       // Since protocol **v20**.
   4537       expected?: boolean;
   4538     }
   4539 
   4540 
   4541 
   4542 Querying expected wire transfers
   4543 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   4544 
   4545 .. http:get:: [/instances/$INSTANCE]/private/incoming
   4546 
   4547   Obtain a list of expected incoming wire transfers the backend is
   4548   anticipating.
   4549   Since protocol **v20**.
   4550 
   4551   **Required permission:** ``transfers-read``
   4552 
   4553   **Request:**
   4554 
   4555   :query payto_uri: *Optional*. Full payto://-URI to filter for transfers to the given bank account (subject and amount MUST NOT be given in the payto:// URI).  Note that the URI must be URL-encoded.
   4556 
   4557   :query before: *Optional*. Filter for transfers executed before the given timestamp.
   4558 
   4559   :query after: *Optional*. Filter for transfers executed after the given timestamp.
   4560 
   4561   :query limit: *Optional*. At most return the given number of results. Negative for descending in execution time, positive for ascending in execution time. Default is ``-20``.
   4562 
   4563   :query offset: *Optional*. Starting ``transfer_serial_id`` for an iteration.
   4564 
   4565   :query verified: *Optional*. Filter transfers by verification status (YES: reconcilation worked, NO: reconciliation failed, ALL: default)
   4566 
   4567   :query confirmed: *Optional*. Filter transfers that were confirmed (YES: credit confirmed, NO: credit still pending, ALL: default)
   4568 
   4569 
   4570   **Response:**
   4571 
   4572   :http:statuscode:`200 OK`:
   4573     The body of the response is a `ExpectedTransferList`.
   4574 
   4575   **Details:**
   4576 
   4577   .. ts:def:: ExpectedTransferList
   4578 
   4579     interface ExpectedTransferList {
   4580        // List of all the expected incoming transfers that fit the
   4581        // filter that we know.
   4582        incoming : ExpectedTransferDetails[];
   4583     }
   4584 
   4585   .. ts:def:: ExpectedTransferDetails
   4586 
   4587     interface ExpectedTransferDetails {
   4588       // How much should be wired to the merchant (minus fees).
   4589       expected_credit_amount?: Amount;
   4590 
   4591       // Raw wire transfer identifier identifying the wire transfer (a base32-encoded value).
   4592       wtid: WireTransferIdentifierRawP;
   4593 
   4594       // Full payto://-URI of the bank account that received the wire transfer.
   4595       payto_uri: string;
   4596 
   4597       // Base URL of the exchange that made the wire transfer.
   4598       exchange_url: string;
   4599 
   4600       // Serial number identifying the expected transfer in the backend.
   4601       // Used for filtering via ``offset``.
   4602       expected_transfer_serial_id: Integer;
   4603 
   4604       // Expected time of the execution of the wire transfer
   4605       // by the exchange, according to the exchange.
   4606       execution_time?: Timestamp;
   4607 
   4608       // True if we checked the exchange's answer and are happy with
   4609       // the reconciation data.
   4610       // False if we have an answer and are unhappy, missing if we
   4611       // do not have an answer from the exchange.
   4612       // Does not imply that the wire transfer was settled (for
   4613       // that, see ``confirmed``).
   4614       validated: boolean;
   4615 
   4616       // True if the merchant uses the POST /transfers API to confirm
   4617       // that this wire transfer took place (and it is thus not
   4618       // something merely claimed by the exchange).
   4619       // (a matching entry exists in /private/transfers)
   4620       confirmed: boolean;
   4621 
   4622       // Last HTTP status we received from the exchange, 0 for
   4623       // none (incl. timeout)
   4624       last_http_status: Integer;
   4625 
   4626       // Last Taler error code we got from the exchange.
   4627       last_ec: ErrorCode;
   4628 
   4629       // Last error detail we got back from the exchange.
   4630       last_error_detail?: string;
   4631     }
   4632 
   4633 
   4634 Deleting confirmed wire transfer
   4635 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   4636 
   4637 Deleting a wire transfer can be useful in case of a data entry
   4638 mistake. In particular, if the exchange base URL was entered
   4639 badly, deleting the old entry and adding a correct one is a
   4640 good idea. Note that deleting wire transfers is not possible
   4641 if they were expected.
   4642 
   4643 .. http:delete:: [/instances/$INSTANCE]/private/transfers/$TID
   4644 
   4645    Here, the TID is the 'transfer_serial_id' of the transfer
   4646    to delete.
   4647 
   4648   **Required permission:** ``transfers-write``
   4649 
   4650   **Response:**
   4651 
   4652   :http:statuscode:`204 No content`:
   4653     The transfer was deleted.
   4654   :http:statuscode:`404 Not found`:
   4655     The transfer was already unknown.
   4656   :http:statuscode:`409 Conflict`:
   4657     The transfer cannot be deleted anymore.
   4658 
   4659 
   4660 -----------
   4661 OTP Devices
   4662 -----------
   4663 
   4664 OTP devices can be used to allow offline merchants
   4665 to validate that a customer made a payment.
   4666 
   4667 
   4668 .. http:post:: [/instances/$INSTANCE]/private/otp-devices
   4669 
   4670   This is used to associate an OTP device with an instance.
   4671 
   4672   **Required permission:** ``otp-devices-write``
   4673 
   4674   **Request:**
   4675 
   4676   The request must be a `OtpDeviceAddDetails`.
   4677 
   4678   **Response:**
   4679 
   4680   :http:statuscode:`204 No content`:
   4681     The creation of the template is successful.
   4682   :http:statuscode:`404 Not found`:
   4683     The merchant instance is unknown or it is not in our data.
   4684 
   4685   **Details:**
   4686 
   4687   .. ts:def:: OtpDeviceAddDetails
   4688 
   4689     interface OtpDeviceAddDetails {
   4690 
   4691       // Device ID to use.
   4692       otp_device_id: string;
   4693 
   4694       // Human-readable description for the device.
   4695       otp_device_description: string;
   4696 
   4697       // A key encoded with RFC 3548 Base32.
   4698       // IMPORTANT: This is not using the typical
   4699       // Taler base32-crockford encoding.
   4700       // Instead it uses the RFC 3548 encoding to
   4701       // be compatible with the TOTP standard.
   4702       otp_key: string;
   4703 
   4704       // Algorithm for computing the POS confirmation.
   4705       // "NONE" or 0: No algorithm (no pos confirmation will be generated)
   4706       // "TOTP_WITHOUT_PRICE" or 1: Without amounts (typical OTP device)
   4707       // "TOTP_WITH_PRICE" or 2: With amounts (special-purpose OTP device)
   4708       // The "String" variants are supported @since protocol **v7**.
   4709       otp_algorithm: Integer | string;
   4710 
   4711       // Counter for counter-based OTP devices.
   4712       otp_ctr?: Integer;
   4713     }
   4714 
   4715 
   4716 .. http:patch:: [/instances/$INSTANCE]/private/otp-devices/$DEVICE_ID
   4717 
   4718   This is used to update an OTP device. It is useful when we need to change information in the OTP device or when we have mistake some information.
   4719 
   4720   **Required permission:** ``otp-devices-write``
   4721 
   4722   **Request:**
   4723 
   4724   The request must be a `OtpDevicePatchDetails`.
   4725 
   4726   **Response:**
   4727 
   4728   :http:statuscode:`204 No content`:
   4729     The template has successfully modified.
   4730   :http:statuscode:`404 Not found`:
   4731     The template(ID) is unknown to the backend.
   4732   :http:statuscode:`409 Conflict`:
   4733     The provided information is inconsistent with the current state of the template. Changes made is the same with
   4734     another store.
   4735 
   4736   **Details:**
   4737 
   4738   .. ts:def:: OtpDevicePatchDetails
   4739 
   4740    interface OtpDevicePatchDetails {
   4741 
   4742      // Human-readable description for the device.
   4743      otp_device_description: string;
   4744 
   4745      // A key encoded with RFC 3548 Base32.
   4746      // IMPORTANT: This is not using the typical
   4747      // Taler base32-crockford encoding.
   4748      // Instead it uses the RFC 3548 encoding to
   4749      // be compatible with the TOTP standard.
   4750      otp_key?: string;
   4751 
   4752      // Algorithm for computing the POS confirmation.
   4753      otp_algorithm: Integer;
   4754 
   4755      // Counter for counter-based OTP devices.
   4756      otp_ctr?: Integer;
   4757    }
   4758 
   4759 
   4760 .. http:get:: [/instances/$INSTANCE]/private/otp-devices
   4761 
   4762   This is used to return the list of all the OTP devices.
   4763 
   4764   **Required permission:** ``otp-devices-read``
   4765 
   4766   **Response:**
   4767 
   4768   :http:statuscode:`200 OK`:
   4769      The backend has successfully returned all the templates. Returns a `OtpDeviceSummaryResponse`.
   4770   :http:statuscode:`404 Not found`:
   4771      The backend has does not know about the instance.
   4772 
   4773   **Details:**
   4774 
   4775   .. ts:def:: OtpDeviceSummaryResponse
   4776 
   4777     interface OtpDeviceSummaryResponse {
   4778 
   4779       // Array of devices that are present in our backend.
   4780       otp_devices: OtpDeviceEntry[];
   4781     }
   4782 
   4783   .. ts:def:: OtpDeviceEntry
   4784 
   4785     interface OtpDeviceEntry {
   4786 
   4787       // Device identifier.
   4788       otp_device_id: string;
   4789 
   4790       // Human-readable description for the device.
   4791       device_description: string;
   4792     }
   4793 
   4794 .. http:get:: [/instances/$INSTANCE]/private/otp-devices/$DEVICE_ID
   4795 
   4796   This is used to obtain detailed information about a specific OTP device.
   4797 
   4798   The client can provide additional inputs in the query to allow the backend
   4799   to compute and return a sample OTP code.  Note that it is not an error if
   4800   the client provides query arguments that are not being used *or* that are
   4801   insufficient for the server to compute the ``otp_code``: If the client
   4802   provides inadequate query parameters, the ``otp_code`` is simply omitted
   4803   from the response.
   4804 
   4805   **Required permission:** ``otp-devices-read``
   4806 
   4807   **Query:**
   4808 
   4809   :query faketime=TIMESTAMP: *Optional*. Timestamp in seconds to use when calculating the current OTP code of the device. Since protocol **v10**.
   4810   :query price=AMOUNT: *Optional*. Price to use when calculating the current OTP code of the device. Since protocol **v10**.
   4811 
   4812   **Response:**
   4813 
   4814   :http:statuscode:`200 OK`:
   4815     The backend has successfully returned the detailed information about a specific OTP device.
   4816     Returns a `OtpDeviceDetails`.
   4817   :http:statuscode:`404 Not found`:
   4818     The OTP device or instance is unknown to the backend.
   4819 
   4820   **Details:**
   4821 
   4822   .. ts:def:: OtpDeviceDetails
   4823 
   4824     interface OtpDeviceDetails {
   4825 
   4826       // Human-readable description for the device.
   4827       device_description: string;
   4828 
   4829       // Algorithm for computing the POS confirmation.
   4830       //
   4831       // Currently, the following numbers are defined:
   4832       // 0: None
   4833       // 1: TOTP without price
   4834       // 2: TOTP with price
   4835       otp_algorithm: Integer;
   4836 
   4837       // Counter for counter-based OTP devices.
   4838       otp_ctr?: Integer;
   4839 
   4840       // Current time for time-based OTP devices.
   4841       // Will match the ``faketime`` argument of the
   4842       // query if one was present, otherwise the current
   4843       // time at the backend.
   4844       //
   4845       // Available since protocol **v10**.
   4846       otp_timestamp: Integer;
   4847 
   4848       // Current OTP confirmation string of the device.
   4849       // Matches exactly the string that would be returned
   4850       // as part of a payment confirmation for the given
   4851       // amount and time (so may contain multiple OTP codes).
   4852       //
   4853       // If the ``otp_algorithm`` is time-based, the code is
   4854       // returned for the current time, or for the ``faketime``
   4855       // if a TIMESTAMP query argument was provided by the client.
   4856       //
   4857       // When using OTP with counters, the counter is **NOT**
   4858       // increased merely because this endpoint created
   4859       // an OTP code (this is a GET request, after all!).
   4860       //
   4861       // If the ``otp_algorithm`` requires an amount, the
   4862       // ``amount`` argument must be specified in the
   4863       // query, otherwise the ``otp_code`` is not
   4864       // generated.
   4865       //
   4866       // This field is *optional* in the response, as it is
   4867       // only provided if we could compute it based on the
   4868       // ``otp_algorithm`` and matching client query arguments.
   4869       //
   4870       // Available since protocol **v10**.
   4871       otp_code?: string;
   4872 
   4873    }
   4874 
   4875 .. http:delete:: [/instances/$INSTANCE]/private/otp-devices/$DEVICE_ID
   4876 
   4877   **Required permission:** ``otp-devices-write``
   4878 
   4879   **Response:**
   4880 
   4881   :http:statuscode:`204 No content`:
   4882     The backend has successfully deleted the OTP device.
   4883   :http:statuscode:`404 Not found`:
   4884     The backend does not know the instance or the OTP device.
   4885 
   4886 
   4887 .. _merchant-template-api:
   4888 
   4889 ---------
   4890 Templates
   4891 ---------
   4892 
   4893 The template is a backend feature that is used to allow wallets to create an
   4894 order. This is useful in cases where a store does not have Internet
   4895 connectivity or where a Web site wants to enable payments on a purely static
   4896 Web page (for example to collect donations). In these cases, the GNU Taler
   4897 wallet can be used to setup an order (and then of course pay for it).
   4898 
   4899 The template itself primarily provides order details that cannot be be changed
   4900 by the customer when the wallet creates the order.  The idea is that the user
   4901 *may* be prompted to enter certain information, such as the amount to be paid,
   4902 or the order summary (as a reminder to themselves or a message to the store),
   4903 while the template provides all of the other contract details.
   4904 
   4905 The typical user-experience with templatates is that the user first scans a QR
   4906 code or clicks on a taler://-URI which contains a ``pay-template`` (see `LSD
   4907 0006 <https://lsd.gnunet.org/lsd0006/>`__). The URI specifies which values the
   4908 user should supply, currently either nothing, the amount, the order summary or
   4909 both.  The URI may also specify defaults or partial defaults for those
   4910 values. After the user has supplied those values, the wallet will use the
   4911 public template API to create the order, then fetch the order details, and
   4912 proceed as if it had been given the respective ``pay`` URI in the first place:
   4913 show the full contract details and allow the user to make a payment.  If the
   4914 user chooses to aborts the payment, the wallet should give the user the
   4915 opportunity to edit the values and create another order with different values.
   4916 If the template does not include any values that the user is allowed to edit
   4917 (so it is basically a fixed contract), the wallet should directly create the
   4918 order and immediately proceed to the contract acceptance dialog.
   4919 
   4920 The business process for the templating API is also pretty simple. First, the
   4921 private API is used to setup (or edit) the template, providing all of the
   4922 contract terms that subsequently cannot be changed by the customer/wallet.
   4923 This template data is then stored under the template ID which can be freely
   4924 chosen and must be in URL-encoded format. The SPA should also make it easy
   4925 for the merchant to convert the template ID into a taler://-URI and/or QR code.
   4926 Here, the merchant must additionally specify the defaults (if any) for the
   4927 customer-editable values. Afterwards, the merchant can print out the QR code
   4928 for display at the store, add a link to the taler://-URI and/or embed the
   4929 respective QR-code image into their Web page.
   4930 
   4931 To receive a payment confirmation, the mechant may choose to configure a
   4932 webhook in the merchant backend on the ``pay`` action, for example to send an
   4933 SMS to their mobile phone.  For points-of-sale without a mobile phone or
   4934 Internet connectivity, the OTP mechanism can also be used to confirm payments.
   4935 
   4936 
   4937 
   4938 Adding templates
   4939 ^^^^^^^^^^^^^^^^
   4940 
   4941 .. http:post:: [/instances/$INSTANCE]/private/templates
   4942 
   4943   This is used to create a template.
   4944 
   4945   **Required permission:** ``templates-write``
   4946 
   4947   **Request:**
   4948 
   4949   The request must be a `TemplateAddDetails`.
   4950 
   4951 
   4952   **Response:**
   4953 
   4954   :http:statuscode:`204 No content`:
   4955     The creation of the template is successful.
   4956   :http:statuscode:`404 Not found`:
   4957     The merchant instance is unknown or it is not in our data.
   4958 
   4959   **Details:**
   4960 
   4961 
   4962   .. ts:def:: TemplateAddDetails
   4963 
   4964     interface TemplateAddDetails {
   4965 
   4966       // Template ID to use.
   4967       template_id: string;
   4968 
   4969       // Human-readable description for the template.
   4970       template_description: string;
   4971 
   4972       // OTP device ID.
   4973       // This parameter is optional.
   4974       otp_id?: string;
   4975 
   4976       // Fixed contract information for orders created from
   4977       // this template.
   4978       template_contract: TemplateContractDetails;
   4979 
   4980       // Key-value pairs matching a subset of the
   4981       // fields from ``template_contract`` that are
   4982       // user-editable defaults for this template.
   4983       // Since protocol **v13**.
   4984       editable_defaults?: Object;
   4985     }
   4986 
   4987 
   4988   .. ts:def:: TemplateContractDetails
   4989 
   4990     interface TemplateContractDetails {
   4991 
   4992       // Human-readable summary for the template.
   4993       summary?: string;
   4994 
   4995       // Required currency for payments to the template.
   4996       // The user may specify any amount, but it must be
   4997       // in this currency.
   4998       // This parameter is optional and should not be present
   4999       // if "amount" is given.
   5000       currency?: string;
   5001 
   5002       // The price is imposed by the merchant and cannot be changed by the customer.
   5003       // This parameter is optional.
   5004       amount?: Amount;
   5005 
   5006       // Minimum age buyer must have (in years). Default is 0.
   5007       minimum_age: Integer;
   5008 
   5009       // The time the customer need to pay before his order will be deleted.
   5010       // It is deleted if the customer did not pay and if the duration is over.
   5011       pay_duration: RelativeTime;
   5012 
   5013    }
   5014 
   5015 
   5016 
   5017 Editing templates
   5018 ^^^^^^^^^^^^^^^^^
   5019 
   5020 
   5021 .. http:patch:: [/instances/$INSTANCE]/private/templates/$TEMPLATE_ID
   5022 
   5023   This is used to update a template. It is useful when we need to change information in the template or when we have mistake some information.
   5024 
   5025   **Required permission:** ``templates-write``
   5026 
   5027   **Request:**
   5028 
   5029   The request must be a `TemplatePatchDetails`.
   5030 
   5031   **Response:**
   5032 
   5033   :http:statuscode:`204 No content`:
   5034     The template has successfully modified.
   5035   :http:statuscode:`404 Not found`:
   5036     The template(ID) is unknown to the backend.
   5037   :http:statuscode:`409 Conflict`:
   5038     The provided information is inconsistent with the current state of the template. Changes made is the same with
   5039     another store.
   5040 
   5041   **Details:**
   5042 
   5043 
   5044   .. ts:def:: TemplatePatchDetails
   5045 
   5046     interface TemplatePatchDetails {
   5047 
   5048       // Human-readable description for the template.
   5049       template_description: string;
   5050 
   5051       // OTP device ID.
   5052       // This parameter is optional.
   5053       otp_id?: string;
   5054 
   5055       // Additional information in a separate template.
   5056       template_contract: TemplateContractDetails;
   5057 
   5058       // Key-value pairs matching a subset of the
   5059       // fields from ``template_contract`` that are
   5060       // user-editable defaults for this template.
   5061       // Since protocol **v13**.
   5062       editable_defaults?: Object;
   5063    }
   5064 
   5065 
   5066 
   5067 Inspecting template
   5068 ^^^^^^^^^^^^^^^^^^^
   5069 
   5070 .. http:get:: [/instances/$INSTANCE]/private/templates
   5071 
   5072   This is used to return the list of all the templates.
   5073 
   5074 
   5075   **Required permission:** ``templates-read``
   5076 
   5077   **Response:**
   5078 
   5079   :http:statuscode:`200 OK`:
   5080      The backend has successfully returned all the templates. Returns a `TemplateSummaryResponse`.
   5081   :http:statuscode:`404 Not found`:
   5082      The backend has does not know about the instance.
   5083 
   5084   **Details:**
   5085 
   5086   .. ts:def:: TemplateSummaryResponse
   5087 
   5088     interface TemplateSummaryResponse {
   5089 
   5090       // List of templates that are present in our backend.
   5091       templates: TemplateEntry[];
   5092     }
   5093 
   5094   The `TemplateEntry` object describes a template. It has the following structure:
   5095 
   5096   .. ts:def:: TemplateEntry
   5097 
   5098     interface TemplateEntry {
   5099 
   5100       // Template identifier, as found in the template.
   5101       template_id: string;
   5102 
   5103       // Human-readable description for the template.
   5104       template_description: string;
   5105 
   5106     }
   5107 
   5108 .. http:get:: [/instances/$INSTANCE]/private/templates/$TEMPLATE_ID
   5109 
   5110   This is used to obtain detailed information about a specific template.
   5111 
   5112 
   5113   **Required permission:** ``templates-read``
   5114 
   5115   **Response:**
   5116 
   5117   :http:statuscode:`200 OK`:
   5118     The backend has successfully returned the detailed information about a specific template.
   5119     Returns a `TemplateDetails`.
   5120   :http:statuscode:`404 Not found`:
   5121     The instance or template(ID) is unknown to the backend.
   5122 
   5123   **Details:**
   5124 
   5125 
   5126   .. ts:def:: TemplateDetails
   5127 
   5128     interface TemplateDetails {
   5129 
   5130       // Human-readable description for the template.
   5131       template_description: string;
   5132 
   5133       // OTP device ID.
   5134       // This parameter is optional.
   5135       otp_id?: string;
   5136 
   5137       // Additional information in a separate template.
   5138       template_contract: TemplateContractDetails;
   5139 
   5140       // Key-value pairs matching a subset of the
   5141       // fields from ``template_contract`` that are
   5142       // user-editable defaults for this template.
   5143       // Since protocol **v13**.
   5144       editable_defaults?: Object;
   5145 
   5146       // Required currency for payments.  Useful if no
   5147       // amount is specified in the ``template_contract``
   5148       // but the user should be required to pay in a
   5149       // particular currency anyway.  Merchant backends
   5150       // may reject requests if the ``template_contract``
   5151       // or ``editable_defaults`` do
   5152       // specify an amount in a different currency.
   5153       // This parameter is optional.
   5154       // Since protocol **v13**.
   5155       required_currency?: string;
   5156     }
   5157 
   5158 
   5159 
   5160 Removing template
   5161 ^^^^^^^^^^^^^^^^^
   5162 
   5163 .. http:delete:: [/instances/$INSTANCE]/private/templates/$TEMPLATE_ID
   5164 
   5165   This is used to delete information about a template. If we no longer use it.
   5166 
   5167   **Required permission:** ``templates-write``
   5168 
   5169   **Response:**
   5170 
   5171   :http:statuscode:`204 No content`:
   5172     The backend has successfully deleted the template.
   5173   :http:statuscode:`404 Not found`:
   5174     The backend does not know the instance or the template.
   5175 
   5176 
   5177 
   5178 Using template
   5179 ^^^^^^^^^^^^^^
   5180 
   5181 .. http:get:: [/instances/$INSTANCE]/templates/$TEMPLATE_ID
   5182 
   5183   This is used to obtain information about a specific template by wallets
   5184   before they ask the user to fill in details.
   5185   This endpoint is available since protocol **v11**.
   5186 
   5187   **Response:**
   5188 
   5189   :http:statuscode:`200 OK`:
   5190     The backend has successfully returned the detailed information about a specific template.
   5191     Returns a `WalletTemplateDetails`.
   5192   :http:statuscode:`404 Not found`:
   5193     The instance or template(ID) is unknown to the backend.
   5194 
   5195   **Details:**
   5196 
   5197   .. ts:def:: WalletTemplateDetails
   5198 
   5199     interface WalletTemplateDetails {
   5200 
   5201       // Hard-coded information about the contrac terms
   5202       // for this template.
   5203       template_contract: TemplateContractDetails;
   5204 
   5205       // Key-value pairs matching a subset of the
   5206       // fields from ``template_contract`` that are
   5207       // user-editable defaults for this template.
   5208       // Since protocol **v13**.
   5209       editable_defaults?: Object;
   5210 
   5211       // Required currency for payments.  Useful if no
   5212       // amount is specified in the ``template_contract``
   5213       // but the user should be required to pay in a
   5214       // particular currency anyway.  Merchant backends
   5215       // may reject requests if the ``template_contract``
   5216       // or ``editable_defaults`` do
   5217       // specify an amount in a different currency.
   5218       // This parameter is optional.
   5219       // Since protocol **v13**.
   5220       required_currency?: string;
   5221     }
   5222 
   5223 
   5224 .. http:post:: [/instances/$INSTANCES]/templates/$TEMPLATE_ID
   5225 
   5226   This using template can be modified by everyone and will be used to create order.
   5227 
   5228 
   5229   **Request:**
   5230 
   5231   The request must be a `UsingTemplateDetails` and we accept JSON application and URL encoded.
   5232 
   5233 
   5234   **Response:**
   5235 
   5236   The response is exactly the same type of response as when
   5237   creating an order using :ref:`POST /private/orders <post-order>`.
   5238 
   5239   **Details:**
   5240 
   5241   .. ts:def:: UsingTemplateDetails
   5242 
   5243     interface UsingTemplateDetails {
   5244 
   5245       // Summary of the template
   5246       summary?: string;
   5247 
   5248       // The amount entered by the customer.
   5249       amount?: Amount;
   5250     }
   5251 
   5252 
   5253 --------
   5254 Webhooks
   5255 --------
   5256 
   5257 The webhook is a backend feature that is used to send a confirmation to the merchant. It can be send with a SMS, email or with another method. It will confirm that the
   5258 customer paid the merchant. It will show the date and the price the customer paid. For details on setup and supported event payloads, see the
   5259 `Merchant manual – Setting up a webhook <https://docs.taler.net/taler-merchant-manual.html#setting-up-a-webhook>`_.
   5260 
   5261 Each webhook is bound to an ``event_type``. The backend currently recognizes the following types, which are mirrored in the ``WebhookEventType`` enum so API clients can
   5262 validate their payloads without guesswork:
   5263 
   5264 .. ts:def:: WebhookEventType
   5265 
   5266    enum WebhookEventType {
   5267       ORDER_CREATED = "order_created",
   5268       PAY = "pay",
   5269       REFUND = "refund",
   5270       ORDER_SETTLED = "order_settled",
   5271       CATEGORY_ADDED = "category_added",
   5272       CATEGORY_UPDATED = "category_updated",
   5273       CATEGORY_DELETED = "category_deleted",
   5274       INVENTORY_ADDED = "inventory_added",
   5275       INVENTORY_UPDATED = "inventory_updated",
   5276       INVENTORY_DELETED = "inventory_deleted"
   5277    }
   5278 
   5279 - ``order_created``: fired whenever a new order is created and exposes the ``order_id``, contract, and owning ``instance_id``.
   5280 - ``pay``: emitted after a payment succeeds; the payload contains the paid contract terms and ``order_id``.
   5281 - ``refund``: triggered when a refund is approved and includes timestamp, refunded amount, and reason.
   5282 - ``order_settled``: sent when reconciliation links a wire transfer to an order (includes ``order_id`` and ``wtid``).
   5283 - ``category_added`` / ``category_updated`` / ``category_deleted``: cover lifecycle changes to product categories.
   5284 - ``inventory_added`` / ``inventory_updated`` / ``inventory_deleted``: cover lifecycle changes to inventory items, including descriptive fields and stock state.
   5285 
   5286 For the full payloads associated with each event consult the merchant manual section linked above.
   5287 
   5288 
   5289 
   5290 Adding webhooks
   5291 ^^^^^^^^^^^^^^^
   5292 
   5293 .. http:post:: [/instances/$INSTANCES]/private/webhooks
   5294 
   5295   This is used to create a webhook.
   5296 
   5297   **Required permission:** ``webhooks-write``
   5298 
   5299   **Request:**
   5300 
   5301   The request must be a `WebhookAddDetails`.
   5302 
   5303   **Response:**
   5304 
   5305   :http:statuscode:`204 No content`:
   5306     The creation of the webhook is successsful.
   5307 
   5308   :http:statuscode:`404 Not found`:
   5309     The merchant instance is unknown or it not in our data.
   5310 
   5311   **Details:**
   5312 
   5313   .. ts:def:: WebhookAddDetails
   5314 
   5315     interface WebhookAddDetails {
   5316 
   5317       // Webhook ID to use.
   5318       webhook_id: string;
   5319 
   5320       // The event of the webhook: why the webhook is used.
   5321       event_type: WebhookEventType;
   5322 
   5323       // URL of the webhook where the customer will be redirected.
   5324       url: string;
   5325 
   5326       // Method used by the webhook
   5327       http_method: string;
   5328 
   5329       // Header template of the webhook
   5330       header_template?: string;
   5331 
   5332       // Body template by the webhook
   5333       body_template?: string;
   5334 
   5335    }
   5336 
   5337 
   5338 Editing webhooks
   5339 ^^^^^^^^^^^^^^^^
   5340 
   5341 .. http:patch:: [/instances/$INSTANCES]/private/webhooks/$WEBHOOK_ID
   5342 
   5343   This is used to update a webhook.
   5344 
   5345   **Required permission:** ``webhooks-write``
   5346 
   5347   **Request:**
   5348 
   5349   The request must be a `WebhookPatchDetails`.
   5350 
   5351   **Response:**
   5352 
   5353   :http:statuscode:`204 No content`:
   5354      The webhook has successfully modified.
   5355   :http:statuscode:`404 Not found`:
   5356      The webhook(ID) is unknown to the backend.
   5357   :http:statuscode:`409 Conflict`:
   5358      The provided information is inconsistent with the current state of the webhook. Changes made is the same with another store.
   5359 
   5360   **Details:**
   5361 
   5362   .. ts:def:: WebhookPatchDetails
   5363 
   5364     interface WebhookPatchDetails {
   5365 
   5366       // The event of the webhook: why the webhook is used.
   5367       event_type: WebhookEventType;
   5368 
   5369       // URL of the webhook where the customer will be redirected.
   5370       url: string;
   5371 
   5372       // Method used by the webhook
   5373       http_method: string;
   5374 
   5375       // Header template of the webhook
   5376       header_template?: string;
   5377 
   5378       // Body template by the webhook
   5379       body_template?: string;
   5380 
   5381    }
   5382 
   5383 
   5384 
   5385 Inspecting webhook
   5386 ^^^^^^^^^^^^^^^^^^
   5387 
   5388 .. http:get:: [/instances/$INSTANCES]/private/webhooks
   5389 
   5390   This is used to return all the webhooks that are present in our backend.
   5391 
   5392   **Required permission:** ``webhooks-read``
   5393 
   5394   **Response:**
   5395 
   5396   :http:statuscode:`200 OK`:
   5397     The backend has successfully returned all the webhooks. Returns a `WebhookSummaryResponse`.
   5398 
   5399   :http:statuscode:`404 Not found`:
   5400     The backend has does not know about the instance.
   5401 
   5402   **Details:**
   5403 
   5404   .. ts:def:: WebhookSummaryResponse
   5405 
   5406     interface WebhookSummaryResponse {
   5407 
   5408       // Return webhooks that are present in our backend.
   5409       webhooks: WebhookEntry[];
   5410 
   5411    }
   5412 
   5413   The `WebhookEntry` object describes a webhook. It has the following structure:
   5414 
   5415   .. ts:def:: WebhookEntry
   5416 
   5417     interface WebhookEntry {
   5418 
   5419       // Webhook identifier, as found in the webhook.
   5420       webhook_id: string;
   5421 
   5422       // The event of the webhook: why the webhook is used.
   5423       event_type: WebhookEventType;
   5424 
   5425    }
   5426 
   5427 
   5428 .. http:get:: [/instances/$INSTANCES]/private/webhooks/$WEBHOOK_ID
   5429 
   5430   This is used to obtain detailed information about apecific template.
   5431 
   5432   **Required permission:** ``webhooks-read``
   5433 
   5434   **Response:**
   5435 
   5436   :http:statuscode:`200 OK`:
   5437     The backend has successfully returned the detailed information about a specific webhook. Returns a `WebhookDetails`.
   5438 
   5439   :http:statuscode:`404 Not found`:
   5440     The webhook(ID) is unknown to the backend.
   5441 
   5442   **Details:**
   5443 
   5444   .. ts:def:: WebhookDetails
   5445 
   5446     interface WebhookDetails {
   5447 
   5448       // The event of the webhook: why the webhook is used.
   5449       event_type: WebhookEventType;
   5450 
   5451       // URL of the webhook where the customer will be redirected.
   5452       url: string;
   5453 
   5454       // Method used by the webhook
   5455       http_method: string;
   5456 
   5457       // Header template of the webhook
   5458       header_template?: string;
   5459 
   5460       // Body template by the webhook
   5461       body_template?: string;
   5462 
   5463    }
   5464 
   5465 
   5466 Removing webhook
   5467 ^^^^^^^^^^^^^^^^
   5468 
   5469 .. http:delete:: [/instances/$INSTANCES]/private/webhooks/$WEBHOOK_ID
   5470 
   5471   This is used to delete information about a webhook.
   5472 
   5473   **Required permission:** ``webhooks-write``
   5474 
   5475   **Response:**
   5476 
   5477   :http:statuscode:`204 No content`:
   5478     The backend has successfully deleted the webhook.
   5479 
   5480   :http:statuscode:`404 Not found`:
   5481     The webhook(ID) or the instance is unknown to the backend.
   5482 
   5483 
   5484 
   5485 ----------------------------------------
   5486 Token Families: Subscriptions, Discounts
   5487 ----------------------------------------
   5488 
   5489 This API provides functionalities for the issuance, management, and revocation
   5490 of token families. Tokens facilitate the implementation of subscriptions and
   5491 discounts, engaging solely the merchant and the user. Each token family
   5492 encapsulates details pertaining to its respective tokens, guiding the merchant's
   5493 backend on the appropriate processing and handling.
   5494 
   5495 
   5496 Creating token families
   5497 ^^^^^^^^^^^^^^^^^^^^^^^
   5498 
   5499 .. http:post:: [/instances/$INSTANCES]/private/tokenfamilies
   5500 
   5501   This is used to create a token family.
   5502 
   5503   **Required permission:** ``tokenfamilies-write``
   5504 
   5505   **Request:**
   5506 
   5507   The request must be a `TokenFamilyCreateRequest`.
   5508 
   5509   **Response:**
   5510 
   5511   :http:statuscode:`204 No content`:
   5512     The token family was created successfully.
   5513 
   5514   :http:statuscode:`404 Not found`:
   5515     The merchant backend is unaware of the instance.
   5516 
   5517   **Details:**
   5518 
   5519   .. ts:def:: TokenFamilyCreateRequest
   5520 
   5521     interface TokenFamilyCreateRequest {
   5522 
   5523       // Identifier for the token family consisting of unreserved characters
   5524       // according to RFC 3986.
   5525       slug: string;
   5526 
   5527       // Human-readable name for the token family.
   5528       name: string;
   5529 
   5530       // Human-readable description for the token family.
   5531       description: string;
   5532 
   5533       // Optional map from IETF BCP 47 language tags to localized descriptions.
   5534       description_i18n?: { [lang_tag: string]: string };
   5535 
   5536       // Additional meta data, such as the ``trusted_domains``
   5537       // or ``expected_domains``. Depends on the ``kind``.
   5538       extra_data?: object;
   5539 
   5540       // Start time of the token family's validity period.
   5541       // If not specified, merchant backend will use the current time.
   5542       valid_after?: Timestamp;
   5543 
   5544       // End time of the token family's validity period.
   5545       valid_before: Timestamp;
   5546 
   5547       // Validity duration of an issued token.
   5548       duration: RelativeTime;
   5549 
   5550       // Rounding granularity for the start validity of keys.
   5551       // The desired time is rounded down to a multiple of this
   5552       // granularity and then the ``start_offset`` is added to
   5553       // compute the actual start time of the token keys' validity.
   5554       // The end is then computed by adding the ``duration``.
   5555       // Must be 1 minute, 1 hour, 1 day, 1 week, 30 days, 90 days
   5556       // or 365 days (1 year).
   5557       validity_granularity: RelativeTime;
   5558 
   5559       // Offset to subtract from the start time rounded to ``validity_granularity``
   5560       // to compute the actual start time for a key.
   5561       // Default is zero.
   5562       start_offset: RelativeTime;
   5563 
   5564       // Kind of the token family.
   5565       kind: TokenFamilyKind;
   5566 
   5567    }
   5568 
   5569   .. ts:def:: TokenFamilyKind
   5570 
   5571     enum TokenFamilyKind {
   5572       Discount = "discount",
   5573       Subscription = "subscription",
   5574     }
   5575 
   5576 
   5577 Updating token families
   5578 ^^^^^^^^^^^^^^^^^^^^^^^
   5579 
   5580 .. http:patch:: [/instances/$INSTANCES]/private/tokenfamilies/$TOKEN_FAMILY_SLUG
   5581 
   5582   This is used to update a token family.
   5583 
   5584   **Required permission:** ``tokenfamilies-write``
   5585 
   5586   **Request:**
   5587 
   5588   The request must be a `TokenFamilyUpdateRequest`.
   5589 
   5590   **Response:**
   5591 
   5592   :http:statuscode:`204 No Content`:
   5593     The token family was successsful updated.
   5594 
   5595   :http:statuscode:`404 Not found`:
   5596     The merchant backend is unaware of the token family or instance.
   5597 
   5598   **Details:**
   5599 
   5600   .. ts:def:: TokenFamilyUpdateRequest
   5601 
   5602     interface TokenFamilyUpdateRequest {
   5603 
   5604       // Human-readable name for the token family.
   5605       name: string;
   5606 
   5607       // Human-readable description for the token family.
   5608       description: string;
   5609 
   5610       // Optional map from IETF BCP 47 language tags to localized descriptions.
   5611       description_i18n: { [lang_tag: string]: string };
   5612 
   5613       // Additional meta data, such as the ``trusted_domains``
   5614       // or ``expected_domains``. Depends on the ``kind``.
   5615       extra_data?: object;
   5616 
   5617       // Start time of the token family's validity period.
   5618       valid_after: Timestamp;
   5619 
   5620       // End time of the token family's validity period.
   5621       valid_before: Timestamp;
   5622 
   5623    }
   5624 
   5625 
   5626 
   5627 Inspecting token families
   5628 ^^^^^^^^^^^^^^^^^^^^^^^^^
   5629 
   5630 .. http:get:: [/instances/$INSTANCES]/private/tokenfamilies
   5631 
   5632   This is used to list all configured token families for an instance.
   5633 
   5634   **Required permission:** ``tokenfamilies-read``
   5635 
   5636   **Response:**
   5637 
   5638   :http:statuscode:`200 OK`:
   5639     The merchant backend has successfully returned all token families.
   5640     Returns a `TokenFamiliesList`.
   5641 
   5642   :http:statuscode:`404 Not found`:
   5643     The merchant backend is unaware of the instance.
   5644 
   5645   **Details:**
   5646 
   5647   .. ts:def:: TokenFamiliesList
   5648 
   5649     // TODO: Add pagination
   5650 
   5651     interface TokenFamiliesList {
   5652 
   5653       // All configured token families of this instance.
   5654       token_families: TokenFamilySummary[];
   5655 
   5656    }
   5657 
   5658   .. ts:def:: TokenFamilySummary
   5659 
   5660     interface TokenFamilySummary {
   5661       // Identifier for the token family consisting of unreserved characters
   5662       // according to RFC 3986.
   5663       slug: string;
   5664 
   5665       // Human-readable name for the token family.
   5666       name: string;
   5667 
   5668       // Human-readable description for the token family.
   5669       // @since protocol **v23**.
   5670       description: string;
   5671 
   5672       // Optional map from IETF BCP 47 language tags to localized descriptions.
   5673       // @since protocol **v23**.
   5674       description_i18n?: { [lang_tag: string]: string };
   5675 
   5676       // Start time of the token family's validity period.
   5677       valid_after: Timestamp;
   5678 
   5679       // End time of the token family's validity period.
   5680       valid_before: Timestamp;
   5681 
   5682       // Kind of the token family.
   5683       kind: TokenFamilyKind;
   5684    }
   5685 
   5686 
   5687 .. http:get:: [/instances/$INSTANCES]/private/tokenfamilies/$TOKEN_FAMILY_SLUG
   5688 
   5689   This is used to get detailed information about a specific token family.
   5690 
   5691   **Required permission:** ``tokenfamilies-read``
   5692 
   5693   **Response:**
   5694 
   5695   :http:statuscode:`200 OK`:
   5696     The merchant backend has successfully returned the detailed information
   5697     about a specific token family. Returns a `TokenFamilyDetails`.
   5698 
   5699   :http:statuscode:`404 Not found`:
   5700     The merchant backend is unaware of the token family or instance.
   5701 
   5702   **Details:**
   5703 
   5704   The `TokenFamilyDetails` object describes a configured token family.
   5705 
   5706   .. ts:def:: TokenFamilyDetails
   5707 
   5708     interface TokenFamilyDetails {
   5709 
   5710       // Identifier for the token family consisting of unreserved characters
   5711       // according to RFC 3986.
   5712       slug: string;
   5713 
   5714       // Human-readable name for the token family.
   5715       name: string;
   5716 
   5717       // Human-readable description for the token family.
   5718       description: string;
   5719 
   5720       // Optional map from IETF BCP 47 language tags to localized descriptions.
   5721       description_i18n?: { [lang_tag: string]: string };
   5722 
   5723       // Additional meta data, such as the ``trusted_domains``
   5724       // or ``expected_domains``. Depends on the ``kind``.
   5725       extra_data?: object;
   5726 
   5727       // Start time of the token family's validity period.
   5728       // No token validities can start before this time
   5729       // (but they could be sold before).
   5730       valid_after: Timestamp;
   5731 
   5732       // End time of the token family's validity period.
   5733       // No tokens will be accepted after this time.
   5734       valid_before: Timestamp;
   5735 
   5736       // Validity duration of an issued token.
   5737       duration: RelativeTime;
   5738 
   5739       // Rounding granularity for the start validity of keys.
   5740       // The desired time is rounded down to a multiple of this
   5741       // granularity and then the ``start_offset`` is added to
   5742       // compute the actual start time of the token keys' validity.
   5743       // The end is then computed by adding the ``duration``.
   5744       validity_granularity: RelativeTime;
   5745 
   5746       // Offset in seconds to subtract from the start time rounded to ``validity_granularity``
   5747       // to compute the actual start time for a key.
   5748       start_offset: RelativeTime;
   5749 
   5750       // Kind of the token family.
   5751       kind: TokenFamilyKind;
   5752 
   5753       // How many tokens have been issued for this family.
   5754       issued: Integer;
   5755 
   5756       // How many tokens have been used for this family.
   5757       used: Integer;
   5758 
   5759    }
   5760 
   5761 
   5762 
   5763 Deleting token families
   5764 ^^^^^^^^^^^^^^^^^^^^^^^
   5765 
   5766 .. http:delete:: [/instances/$INSTANCES]/private/tokenfamilies/$TOKEN_FAMILY_SLUG
   5767 
   5768   This is used to delete a token family. Issued tokens of this family will not
   5769   be spendable anymore.
   5770 
   5771   **Required permission:** ``tokenfamilies-write``
   5772 
   5773   **Response:**
   5774 
   5775   :http:statuscode:`204 No content`:
   5776     The backend has successfully deleted the token family.
   5777 
   5778   :http:statuscode:`404 Not found`:
   5779     The merchant backend is unaware of the token family or instance.
   5780 
   5781 
   5782 -----------------------
   5783 Donau Charity Instances
   5784 -----------------------
   5785 
   5786 A merchant instance can link one or more **Donau charity instances**.
   5787 Each link associates the instance’s own public key with a charity registered
   5788 at some Donau service.  These links are managed under the private API.
   5789 
   5790 Permissions
   5791 ^^^^^^^^^^^
   5792 
   5793 * ``donau-read``  — list linked charities.
   5794 * ``donau-write`` — add or remove charity links.
   5795 
   5796 Listing charity instances
   5797 ^^^^^^^^^^^^^^^^^^^^^^^^^
   5798 
   5799 .. http:get:: [/instances/$INSTANCE]/private/donau
   5800 
   5801   Return all Donau charity instances currently linked to ``$INSTANCE``.
   5802 
   5803   **Required permission:** ``donau-read``
   5804 
   5805   **Response:**
   5806 
   5807   :http:statuscode:`200 OK`:
   5808     Body is a :ts:type:`DonauInstancesResponse`.
   5809   :http:statuscode:`401 Unauthorized`:
   5810     Missing or invalid credentials.
   5811   :http:statuscode:`404 Not found`:
   5812     The merchant instance is unknown.
   5813 
   5814   **Details:**
   5815 
   5816   .. ts:def:: DonauInstancesResponse
   5817 
   5818     interface DonauInstancesResponse {
   5819       // List of linked charity instances
   5820       donau_instances: DonauInstance[];
   5821     }
   5822 
   5823   .. ts:def:: DonauInstance
   5824 
   5825     interface DonauInstance {
   5826       // Serial number identifying the record inside the backend
   5827       donau_instance_serial: Integer;
   5828 
   5829       // Base URL of the Donau service
   5830       donau_url: string;
   5831 
   5832       // Human-readable charity name
   5833       charity_name: string;
   5834 
   5835       // EdDSA public key of the charity (binary)
   5836       charity_pub_key: Bytes;
   5837 
   5838       // Charity identifier inside the Donau service
   5839       charity_id: Integer;
   5840 
   5841       // Maximum donation amount per calendar year
   5842       charity_max_per_year: Amount;
   5843 
   5844       // Cumulative receipts in the current year
   5845       charity_receipts_to_date: Amount;
   5846 
   5847       // Calendar year the receipts refer to
   5848       current_year: Integer;
   5849 
   5850       // Exchange-style ``/keys`` response published by Donau,
   5851       // missing if not yet known to the merchant backend.
   5852       donau_keys_json?: object;
   5853     }
   5854 
   5855 Adding a charity instance
   5856 ^^^^^^^^^^^^^^^^^^^^^^^^^
   5857 
   5858 .. http:post:: [/instances/$INSTANCE]/private/donau
   5859 
   5860   Link a new Donau charity instance to ``$INSTANCE``.
   5861   The backend fetches and validates the charity’s metadata from the given
   5862   Donau service before persisting the link.
   5863 
   5864   **Required permission:** ``donau-write``
   5865 
   5866   **Request:**
   5867 
   5868   The body **must** be a :ts:type:`PostDonauRequest`.
   5869 
   5870   .. ts:def:: PostDonauRequest
   5871 
   5872     interface PostDonauRequest {
   5873       // Base URL of the Donau service hosting the charity
   5874       donau_url: string;
   5875 
   5876       // Numeric charity identifier inside the Donau service
   5877       charity_id: Integer;
   5878     }
   5879 
   5880   **Response:**
   5881 
   5882   :http:statuscode:`204 No content`:
   5883     The charity link was created successfully.
   5884   :http:statuscode:`202 Accepted`:
   5885     Operation requires MFA; a :ts:type:`ChallengeResponse` is returned.  @since **v21**
   5886   :http:statuscode:`400 Bad request`:
   5887     Malformed JSON or missing fields.
   5888   :http:statuscode:`409 Conflict`:
   5889     * The charity is already linked with different parameters, or
   5890     * The charity’s public key does **not** match the merchant instance’s public key.
   5891   :http:statuscode:`502 Bad gateway`:
   5892     Communication with the Donau service failed.
   5893 
   5894 Deleting a charity instance
   5895 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   5896 
   5897 .. http:delete:: [/instances/$INSTANCE]/private/donau/$DONAU_SERIAL
   5898 
   5899   Unlink the Donau charity instance identified by ``$DONAU_SERIAL``.
   5900 
   5901   **Required permission:** ``donau-write``
   5902 
   5903   **Response:**
   5904 
   5905   :http:statuscode:`204 No content`:
   5906     Charity link removed.
   5907   :http:statuscode:`404 Not found`:
   5908     No such charity link exists.
   5909 
   5910 
   5911 
   5912 ------------------
   5913 The Contract Terms
   5914 ------------------
   5915 
   5916 This section describes the overall structure of
   5917 the contract terms that are the foundation for
   5918 Taler payments.
   5919 
   5920 .. _contract-terms:
   5921 
   5922 The contract terms must have the following structure:
   5923 
   5924 .. ts:def:: ContractTerms
   5925 
   5926   type ContractTerms = (ContractTermsV1 | ContractTermsV0) & ContractTermsCommon;
   5927 
   5928 .. ts:def:: ContractTermsV1
   5929 
   5930   interface ContractTermsV1 {
   5931     // Version 1 supports the ``choices`` array, see
   5932     // https://docs.taler.net/design-documents/046-mumimo-contracts.html.
   5933     // @since protocol **v21**
   5934     version: 1;
   5935 
   5936     // List of contract choices that the customer can select from.
   5937     // @since protocol **v21**
   5938     choices: ContractChoice[];
   5939 
   5940     // Map of storing metadata and issue keys of
   5941     // token families referenced in this contract.
   5942     // @since protocol **v21**
   5943     token_families: { [token_family_slug: string]: ContractTokenFamily };
   5944   }
   5945 
   5946 .. ts:def:: ContractTermsV0
   5947 
   5948   interface ContractTermsV0 {
   5949     // Defaults to version 0.
   5950     version?: 0;
   5951 
   5952     // Total price for the transaction.
   5953     // The exchange will subtract deposit fees from that amount
   5954     // before transferring it to the merchant.
   5955     amount: Amount;
   5956 
   5957     // Maximum total deposit fee accepted by the merchant for this contract.
   5958     // Overrides defaults of the merchant instance.
   5959     max_fee: Amount;
   5960   }
   5961 
   5962 .. ts:def:: ContractTermsCommon
   5963 
   5964   interface ContractTermsCommon {
   5965     // Human-readable description of the whole purchase.
   5966     summary: string;
   5967 
   5968     // Map from IETF BCP 47 language tags to localized summaries.
   5969     summary_i18n?: { [lang_tag: string]: string };
   5970 
   5971     // Unique, free-form identifier for the proposal.
   5972     // Must be unique within a merchant instance.
   5973     // For merchants that do not store proposals in their DB
   5974     // before the customer paid for them, the ``order_id`` can be used
   5975     // by the frontend to restore a proposal from the information
   5976     // encoded in it (such as a short product identifier and timestamp).
   5977     order_id: string;
   5978 
   5979     // URL where the same contract could be ordered again (if
   5980     // available). Returned also at the public order endpoint
   5981     // for people other than the actual buyer (hence public,
   5982     // in case order IDs are guessable).
   5983     public_reorder_url?: string;
   5984 
   5985     // URL that will show that the order was successful after
   5986     // it has been paid for.  Optional, but either ``fulfillment_url``
   5987     // or ``fulfillment_message`` must be specified in every
   5988     // contract terms.
   5989     //
   5990     // If a non-unique fulfillment URL is used, a customer can only
   5991     // buy the order once and will be redirected to a previous purchase
   5992     // when trying to buy an order with the same fulfillment URL a second
   5993     // time. This is useful for digital goods that a customer only needs
   5994     // to buy once but should be able to repeatedly download.
   5995     //
   5996     // For orders where the customer is expected to be able to make
   5997     // repeated purchases (for equivalent goods), the fulfillment URL
   5998     // should be made unique for every order. The easiest way to do
   5999     // this is to include a unique order ID in the fulfillment URL.
   6000     //
   6001     // When POSTing to the merchant, the placeholder text "${ORDER_ID}"
   6002     // is be replaced with the actual order ID (useful if the
   6003     // order ID is generated server-side and needs to be
   6004     // in the URL). Note that this placeholder can only be used once.
   6005     // Front-ends may use other means to generate a unique fulfillment URL.
   6006     fulfillment_url?: string;
   6007 
   6008     // Message shown to the customer after paying for the order.
   6009     // Either fulfillment_url or fulfillment_message must be specified.
   6010     fulfillment_message?: string;
   6011 
   6012     // Map from IETF BCP 47 language tags to localized fulfillment
   6013     // messages.
   6014     fulfillment_message_i18n?: { [lang_tag: string]: string };
   6015 
   6016     // List of products that are part of the purchase (see `Product`).
   6017     products: Product[];
   6018 
   6019     // Time when this contract was generated.
   6020     timestamp: Timestamp;
   6021 
   6022     // After this deadline has passed, no refunds will be accepted.
   6023     refund_deadline: Timestamp;
   6024 
   6025     // After this deadline, the merchant won't accept payments for the contract.
   6026     pay_deadline: Timestamp;
   6027 
   6028     // Transfer deadline for the exchange.  Must be in the
   6029     // deposit permissions of coins used to pay for this order.
   6030     wire_transfer_deadline: Timestamp;
   6031 
   6032     // Merchant's public key used to sign this proposal; this information
   6033     // is typically added by the backend. Note that this can be an ephemeral key.
   6034     merchant_pub: EddsaPublicKey;
   6035 
   6036     // Base URL of the (public!) merchant backend API.
   6037     // Must be an absolute URL that ends with a slash.
   6038     merchant_base_url: string;
   6039 
   6040     // More info about the merchant, see below.
   6041     merchant: Merchant;
   6042 
   6043     // The hash of the merchant instance's wire details.
   6044     h_wire: HashCode;
   6045 
   6046     // Wire transfer method identifier for the wire method associated with ``h_wire``.
   6047     // The wallet may only select exchanges via a matching auditor if the
   6048     // exchange also supports this wire method.
   6049     // The wire transfer fees must be added based on this wire transfer method.
   6050     wire_method: string;
   6051 
   6052     // Exchanges that the merchant accepts even if it does not accept any auditors that audit them.
   6053     exchanges: Exchange[];
   6054 
   6055     // Delivery location for (all!) products.
   6056     delivery_location?: Location;
   6057 
   6058     // Time indicating when the order should be delivered.
   6059     // May be overwritten by individual products.
   6060     delivery_date?: Timestamp;
   6061 
   6062     // Nonce generated by the wallet and echoed by the merchant
   6063     // in this field when the proposal is generated.
   6064     nonce: string;
   6065 
   6066     // Specifies for how long the wallet should try to get an
   6067     // automatic refund for the purchase. If this field is
   6068     // present, the wallet should wait for a few seconds after
   6069     // the purchase and then automatically attempt to obtain
   6070     // a refund.  The wallet should probe until "delay"
   6071     // after the payment was successful (i.e. via long polling
   6072     // or via explicit requests with exponential back-off).
   6073     //
   6074     // In particular, if the wallet is offline
   6075     // at that time, it MUST repeat the request until it gets
   6076     // one response from the merchant after the delay has expired.
   6077     // If the refund is granted, the wallet MUST automatically
   6078     // recover the payment.  This is used in case a merchant
   6079     // knows that it might be unable to satisfy the contract and
   6080     // desires for the wallet to attempt to get the refund without any
   6081     // customer interaction.  Note that it is NOT an error if the
   6082     // merchant does not grant a refund.
   6083     auto_refund?: RelativeTime;
   6084 
   6085     // Extra data that is only interpreted by the merchant frontend.
   6086     // Useful when the merchant needs to store extra information on a
   6087     // contract without storing it separately in their database.
   6088     // Must really be an Object (not a string, integer, float or array).
   6089     extra?: Object;
   6090 
   6091     // Minimum age the buyer must have (in years). Default is 0.
   6092     // This value is at least as large as the maximum over all
   6093     // mimimum age requirements of the products in this contract.
   6094     // It might also be set independent of any product, due to
   6095     // legal requirements.
   6096     minimum_age?: Integer;
   6097 
   6098   }
   6099 
   6100 .. ts:def:: ContractChoice
   6101 
   6102   interface ContractChoice {
   6103     // Price to be paid for this choice. Could be 0.
   6104     // The price is in addition to other instruments,
   6105     // such as rations and tokens.
   6106     // The exchange will subtract deposit fees from that amount
   6107     // before transferring it to the merchant.
   6108     amount: Amount;
   6109 
   6110     // Human readable description of the semantics of the choice
   6111     // within the contract to be shown to the user at payment.
   6112     description?: string;
   6113 
   6114     // Map from IETF 47 language tags to localized descriptions.
   6115     description_i18n?: { [lang_tag: string]: string };
   6116 
   6117     // List of inputs the wallet must provision (all of them) to
   6118     // satisfy the conditions for the contract.
   6119     inputs: ContractInput[];
   6120 
   6121     // List of outputs the merchant promises to yield (all of them)
   6122     // once the contract is paid.
   6123     outputs: ContractOutput[];
   6124 
   6125     // Maximum total deposit fee accepted by the merchant for this contract.
   6126     max_fee: Amount;
   6127   }
   6128 
   6129 .. ts:def:: ContractInput
   6130 
   6131   // For now, only tokens are supported as inputs.
   6132   type ContractInput = ContractInputToken;
   6133 
   6134 .. ts:def:: ContractInputToken
   6135 
   6136   interface ContractInputToken {
   6137     type: "token";
   6138 
   6139     // Slug of the token family in the
   6140     // ``token_families`` map on the order.
   6141     token_family_slug: string;
   6142 
   6143     // Number of tokens of this type required.
   6144     // Defaults to one if the field is not provided.
   6145     count?: Integer;
   6146   };
   6147 
   6148 .. ts:def:: ContractOutput
   6149 
   6150   // For now, only tokens are supported as outputs.
   6151   type ContractOutput = ContractOutputToken | ContractOutputTaxReceipt;
   6152 
   6153 .. ts:def:: ContractOutputToken
   6154 
   6155   interface ContractOutputToken {
   6156     type: "token";
   6157 
   6158     // Slug of the token family in the
   6159     // 'token_families' map on the top-level.
   6160     token_family_slug: string;
   6161 
   6162     // Number of tokens to be issued.
   6163     // Defaults to one if the field is not provided.
   6164     count?: Integer;
   6165 
   6166     // Index of the public key for this output token
   6167     // in the `ContractTokenFamily` ``keys`` array.
   6168     key_index: Integer;
   6169 
   6170   }
   6171 
   6172 .. ts:def:: ContractOutputTaxReceipt
   6173 
   6174   interface ContractOutputTaxReceipt {
   6175 
   6176     // Tax receipt output.
   6177     type: "tax-receipt";
   6178 
   6179     // Array of base URLs of donation authorities that can be
   6180     // used to issue the tax receipts. The client must select one.
   6181     donau_urls: string[];
   6182 
   6183     // Total amount that will be on the tax receipt.
   6184     amount: Amount;
   6185 
   6186   }
   6187 
   6188 .. ts:def:: ContractTokenFamily
   6189 
   6190   interface ContractTokenFamily {
   6191     // Human-readable name of the token family.
   6192     name: string;
   6193 
   6194     // Human-readable description of the semantics of
   6195     // this token family (for display).
   6196     description: string;
   6197 
   6198     // Map from IETF BCP 47 language tags to localized descriptions.
   6199     description_i18n?: { [lang_tag: string]: string };
   6200 
   6201     // Public keys used to validate tokens issued by this token family.
   6202     keys: TokenIssuePublicKey[];
   6203 
   6204     // Kind-specific information of the token
   6205     details: ContractTokenDetails;
   6206 
   6207     // Must a wallet understand this token type to
   6208     // process contracts that use or issue it?
   6209     critical: boolean;
   6210   };
   6211 
   6212 .. ts:def:: TokenIssuePublicKey
   6213 
   6214   type TokenIssuePublicKey =
   6215     | TokenIssueRsaPublicKey
   6216     | TokenIssueCsPublicKey;
   6217 
   6218 .. ts:def:: TokenIssueRsaPublicKey
   6219 
   6220   interface TokenIssueRsaPublicKey {
   6221     cipher: "RSA";
   6222 
   6223     // RSA public key.
   6224     rsa_pub: RsaPublicKey;
   6225 
   6226     // Start time of this key's signatures validity period.
   6227     signature_validity_start: Timestamp;
   6228 
   6229     // End time of this key's signatures validity period.
   6230     signature_validity_end: Timestamp;
   6231 
   6232   }
   6233 
   6234 .. ts:def:: TokenIssueCsPublicKey
   6235 
   6236   interface TokenIssueCsPublicKey {
   6237     cipher: "CS";
   6238 
   6239     // CS public key.
   6240     cs_pub: Cs25519Point;
   6241 
   6242     // Start time of this key's signatures validity period.
   6243     signature_validity_start: Timestamp;
   6244 
   6245     // End time of this key's signatures validity period.
   6246     signature_validity_end: Timestamp;
   6247 
   6248   }
   6249 
   6250 .. ts:def:: ContractTokenDetails
   6251 
   6252   type ContractTokenDetails =
   6253     | ContractSubscriptionTokenDetails
   6254     | ContractDiscountTokenDetails;
   6255 
   6256 .. ts:def:: ContractSubscriptionTokenDetails
   6257 
   6258   interface ContractSubscriptionTokenDetails {
   6259     class: "subscription";
   6260 
   6261     // Array of domain names where this subscription
   6262     // can be safely used (e.g. the issuer warrants that
   6263     // these sites will re-issue tokens of this type
   6264     // if the respective contract says so).  May contain
   6265     // "*" for any domain or subdomain.
   6266     trusted_domains: string[];
   6267   };
   6268 
   6269 .. ts:def:: ContractDiscountTokenDetails
   6270 
   6271   interface ContractDiscountTokenDetails {
   6272     class: "discount";
   6273 
   6274     // Array of domain names where this discount token
   6275     // is intended to be used.  May contain "*" for any
   6276     // domain or subdomain.  Users should be warned about
   6277     // sites proposing to consume discount tokens of this
   6278     // type that are not in this list that the merchant
   6279     // is accepting a coupon from a competitor and thus
   6280     // may be attaching different semantics (like get 20%
   6281     // discount for my competitors 30% discount token).
   6282     expected_domains: string[];
   6283   };
   6284 
   6285 
   6286 The wallet must select an exchange that either the merchant accepts directly by
   6287 listing it in the exchanges array, or for which the merchant accepts an auditor
   6288 that audits that exchange by listing it in the auditors array.
   6289 
   6290 The `Product` object describes the product being purchased from the merchant.
   6291 It has the following structure:
   6292 
   6293 .. ts:def:: Product
   6294 
   6295   interface Product {
   6296 
   6297     // Merchant-internal identifier for the product.
   6298     product_id?: string;
   6299 
   6300     // Name of the product.
   6301     // Since API version **v20**.  Optional only for
   6302     // backwards-compatibility, should be considered mandatory
   6303     // moving forward!
   6304     product_name?: string;
   6305 
   6306     // Human-readable product description.
   6307     description: string;
   6308 
   6309     // Map from IETF BCP 47 language tags to localized descriptions.
   6310     description_i18n?: { [lang_tag: string]: string };
   6311 
   6312     // Legacy integer portion of the quantity to deliver defaults to 1 if not specified.
   6313     quantity?: Integer;
   6314 
   6315     // Preferred quantity string using "<integer>[.<fraction>]" syntax with up to six fractional digits.
   6316     unit_quantity?: string;
   6317 
   6318     // Unit in which the product is measured (liters, kilograms, packages, etc.).
   6319     unit?: string;
   6320 
   6321     // The price of the product; this is the total price for ``quantity`` times ``unit`` of this product.
   6322     price?: Amount;
   6323 
   6324     // An optional base64-encoded product image.
   6325     image?: ImageDataUrl;
   6326 
   6327     // A list of taxes paid by the merchant for this product. Can be empty.
   6328     taxes?: Tax[];
   6329 
   6330     // Time indicating when this product should be delivered.
   6331     delivery_date?: Timestamp;
   6332   }
   6333 
   6334 .. ts:def:: Tax
   6335 
   6336   interface Tax {
   6337     // The name of the tax.
   6338     name: string;
   6339 
   6340     // Amount paid in tax.
   6341     tax: Amount;
   6342   }
   6343 
   6344 .. ts:def:: Merchant
   6345 
   6346   interface Merchant {
   6347     // The merchant's legal name of business.
   6348     name: string;
   6349 
   6350     // Email address for contacting the merchant.
   6351     email?: string;
   6352 
   6353     // Label for a location with the business address of the merchant.
   6354     website?: string;
   6355 
   6356     // An optional base64-encoded product image.
   6357     logo?: ImageDataUrl;
   6358 
   6359     // Label for a location with the business address of the merchant.
   6360     address?: Location;
   6361 
   6362     // Label for a location that denotes the jurisdiction for disputes.
   6363     // Some of the typical fields for a location (such as a street address) may be absent.
   6364     jurisdiction?: Location;
   6365   }
   6366 
   6367 
   6368 .. ts:def:: Location
   6369 
   6370   // Delivery location, loosely modeled as a subset of
   6371   // ISO20022's PostalAddress25.
   6372   interface Location {
   6373     // Nation with its own government.
   6374     country?: string;
   6375 
   6376     // Identifies a subdivision of a country such as state, region, county.
   6377     country_subdivision?: string;
   6378 
   6379     // Identifies a subdivision within a country sub-division.
   6380     district?: string;
   6381 
   6382     // Name of a built-up area, with defined boundaries, and a local government.
   6383     town?: string;
   6384 
   6385     // Specific location name within the town.
   6386     town_location?: string;
   6387 
   6388     // Identifier consisting of a group of letters and/or numbers that
   6389     // is added to a postal address to assist the sorting of mail.
   6390     post_code?: string;
   6391 
   6392     // Name of a street or thoroughfare.
   6393     street?: string;
   6394 
   6395     // Name of the building or house.
   6396     building_name?: string;
   6397 
   6398     // Number that identifies the position of a building on a street.
   6399     building_number?: string;
   6400 
   6401     // Free-form address lines, should not exceed 7 elements.
   6402     address_lines?: string[];
   6403   }
   6404 
   6405 .. ts:def:: Auditor
   6406 
   6407   interface Auditor {
   6408     // Official name.
   6409     name: string;
   6410 
   6411     // Auditor's public key.
   6412     auditor_pub: EddsaPublicKey;
   6413 
   6414     // Base URL of the auditor.
   6415     url: string;
   6416   }
   6417 
   6418 .. ts:def:: Exchange
   6419 
   6420   interface Exchange {
   6421     // The exchange's base URL.
   6422     url: string;
   6423 
   6424     // How much would the merchant like to use this exchange.
   6425     // The wallet should use a suitable exchange with high
   6426     // priority. The following priority values are used, but
   6427     // it should be noted that they are NOT in any way normative.
   6428     //
   6429     // 0: likely it will not work (recently seen with account
   6430     //    restriction that would be bad for this merchant)
   6431     // 512: merchant does not know, might be down (merchant
   6432     //    did not yet get /wire response).
   6433     // 1024: good choice (recently confirmed working)
   6434     priority: Integer;
   6435 
   6436     // Master public key of the exchange.
   6437     master_pub: EddsaPublicKey;
   6438 
   6439     // Maximum amount that the merchant could be paid
   6440     // using this exchange (due to legal limits).
   6441     // New in protocol **v17**.
   6442     // Optional, no limit if missing.
   6443     max_contribution?: Amount;
   6444   }
   6445 
   6446 In addition to the fields described above,
   6447 each object (from ``ContractTerms`` down)
   6448 can mark certain fields as "forgettable" by listing the names of those fields
   6449 in a special peer field ``_forgettable``.
   6450 (See :ref:`Private order data cleanup <private-order-data-cleanup>`.)