taler-docs

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

api-terminal.rst (11319B)


      1 ..
      2   This file is part of GNU TALER.
      3 
      4   Copyright (C) 2024 Taler Systems SA
      5 
      6   TALER is free software; you can redistribute it and/or modify it under the
      7   terms of the GNU Affero General Public License as published by the Free Software
      8   Foundation; either version 2.1, or (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     11   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     12   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
     13 
     14   You should have received a copy of the GNU Affero General Public License along with
     15   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     16 
     17 .. target audience: developer, core developer
     18 
     19 .. _terminal-api:
     20 
     21 ============
     22 Terminal API
     23 ============
     24 
     25 
     26 Introduction
     27 ------------
     28 
     29 Terminals are devices where users can withdraw digital cash.
     30 
     31 This API is offered by a payment service backend and is used by such
     32 terminals.  It enables imposing limits on withdrawals per unique user ID (and
     33 communicating such limits to the terminals) as well as setting up and
     34 triggering withdrawal operations.
     35 
     36 Implementations of this API typically interact with a terminal-specific
     37 payment service (or a bank) to realize the service.
     38 
     39 
     40 ---------------
     41 Version History
     42 ---------------
     43 
     44 The current protocol version is **v0**.
     45 
     46 * cash2ecash is currently targeting protocol version **v0**.
     47 * cashless2ecash is currently targeting protocol version **v0**.
     48 
     49 **Version history:**
     50 
     51 * ``v0``: Initial version.
     52 
     53 **Upcoming versions:**
     54 
     55 * None anticipated.
     56 
     57 **Ideas for future version:**
     58 
     59 * ``vXXX``: marker for features not yet targeted for release
     60 
     61 
     62 
     63 
     64 Authentication
     65 --------------
     66 
     67 Terminals must authenticate against all terminal API using basic auth according to `HTTP basic auth <https://tools.ietf.org/html/rfc7617>`_.
     68 
     69 
     70 Config
     71 ------
     72 
     73 .. http:get:: /config
     74 
     75   Return the protocol version and configuration information about the bank.
     76   This specification corresponds to ``current`` protocol being version **0**.
     77 
     78   **Response:**
     79 
     80   :http:statuscode:`200 OK`:
     81     Response is a `TerminalConfig`.
     82 
     83   **Details:**
     84 
     85   .. ts:def:: TerminalConfig
     86 
     87     interface TerminalConfig {
     88       // Name of the API.
     89       name: "taler-terminal";
     90 
     91       // libtool-style representation of the Bank protocol version, see
     92       // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
     93       // The format is "current:revision:age".
     94       version: string;
     95 
     96       // Terminal provider display name to be used in user interfaces.
     97       provider_name: string;
     98 
     99       // The currency supported by this Terminal-API
    100       // must be the same as the currency specified
    101       // in the currency field of the wire gateway config
    102       currency: string;
    103 
    104       // The withdrawal fees which of this Terminals API endpoint.
    105       // If the Exchange chooses to charge no fees, then just configure
    106       // the zero amount.
    107       withdrawal_fees: Amount;
    108 
    109       // Wire transfer type supported by the terminal.
    110       // FIXME: needed?
    111       wire_type: string;
    112     }
    113 
    114 
    115 .. http:get:: /quotas/$UUID
    116 
    117   Obtain the current transaction limit for the given $UUID.
    118   The UUID should be an encoding of a unique identifier of
    119   the user.
    120 
    121   **Response:**
    122 
    123   :http:statuscode:`200 OK`:
    124     Response is a `WithdrawLimit`.
    125 
    126   **Details:**
    127 
    128   .. ts:def:: WithdrawLimit
    129 
    130     interface WithdrawLimit {
    131       // Maximum amount that can be withdrawn now.
    132       limit: Amount;
    133 
    134       // Time when the limit may increase.
    135       expiration: Timestamp;
    136     }
    137 
    138 
    139 .. http:post:: /quotas/$UUID/lock
    140 
    141   This endpoint allows a terminal to reserve a given amount
    142   from the user's quota, ensuring that a subsequent operation
    143   will not fail due to a quota violation.
    144 
    145   **Request:**
    146 
    147   The request should be a `WithdrawLimitLock`.
    148 
    149   **Response:**
    150 
    151   :http:statuscode:`204 No content`:
    152     The change was accepted.
    153   :http:statuscode:`409 Conflict`:
    154     The proposed lock would push the user above the limit.
    155 
    156   **Details:**
    157 
    158   .. ts:def:: WithdrawLimitLock
    159 
    160     interface WithdrawLimitLock {
    161 
    162       // Amount that should be reserved from the quota.
    163       limit: Amount;
    164 
    165       // ID for the lock.  FIXME: could also be 32-byte nonce?
    166       lock: string;
    167 
    168       // How long should the lock be held?
    169       expiration: Timestamp;
    170     }
    171 
    172 .. http:delete:: /quotas/$UUID/lock/$LOCK
    173 
    174   This endpoint allows the terminal to clear a lock it may have
    175   previously created.
    176 
    177   **Response:**
    178 
    179   :http:statuscode:`204 No content`:
    180     The lock was cleared.
    181   :http:statuscode:`404 Not found`:
    182     The lock is unknown.
    183   :http:statuscode:`409 Conflict`:
    184     The lock was already used in a withdrawal operation.
    185 
    186 
    187 .. http:post:: /withdrawals
    188 
    189   This endpoint allows the terminal to set up a new withdrawal
    190   operation.
    191 
    192   **Request:**
    193 
    194   The request should be a `TerminalWithdrawalSetup`.
    195 
    196   **Response:**
    197 
    198   :http:statuscode:`200 Ok`:
    199     The operation was created.  The response will be
    200     a `TerminalWithdrawalSetupResponse`.
    201   :http:statuscode:`404 Not found`:
    202     A lock was specified but the lock is not known for
    203     the given user.
    204   :http:statuscode:`409 Conflict`:
    205     A conflicting withdrawal operation already exists or
    206     the amount would violate the quota for the specified user.
    207 
    208   **Details:**
    209 
    210   .. ts:def:: TerminalWithdrawalSetup
    211 
    212     interface TerminalWithdrawalSetup {
    213 
    214       // Amount to withdraw.  If given, the wallet
    215       // cannot change the amount!
    216       amount?: Amount;
    217 
    218       // Suggested amount to withdraw. If given, the wallet can
    219       // still change the suggestion.
    220       suggested_amount?: Amount;
    221 
    222       // A provider-specific transaction identifier.
    223       // This identifier may be used to attest the
    224       // payment at the provider's backend. Optional,
    225       // as we may not know it at this time.
    226       provider_transaction_id?: string;
    227 
    228       // The non-Taler fees the customer will have
    229       // to pay to the service provider
    230       // they are using to make this withdrawal.
    231       // If the fees cannot be precalculated,
    232       // they can be specified in the /withdrawals/$WITHDRAWAL_ID/check
    233       // request after the transaction was executed.
    234       terminal_fees?: Amount;
    235 
    236       // Unique request ID to make retried requests idempotent.
    237       request_uid: string;
    238 
    239       // Unique user ID of the user.  Optional
    240       // in case a user Id is not (yet) known.
    241       user_uuid?: string;
    242 
    243       // ID identifying a lock on the quota that the client
    244       // may wish to use in this operation.  May only be
    245       // present if ``user_uuid`` is also given.
    246       lock?: string;
    247     }
    248 
    249   .. ts:def:: TerminalWithdrawalSetupResponse
    250 
    251     interface TerminalWithdrawalSetupResponse {
    252 
    253       // ID identifying the withdrawal operation being created.
    254       withdrawal_id: string;
    255     }
    256 
    257 
    258 .. http:post:: /withdrawals/$WITHDRAWAL_ID/check
    259 
    260   Endpoint for providers to notify the terminal backend about a payment having
    261   happened.  This will cause the bank to validate the transaction and allow
    262   the withdrawal to proceed. The API is idempotent, meaning sending a payment
    263   notification for the same ``WITHDRAWAL_ID`` return successfuly but not
    264   change anything.  This endpoint is always *optional*: the bank, exchange and
    265   wallet should all eventually notice the wire transfer with or without this
    266   endpoint being called.  However, by calling this endpoint checks that might
    267   otherwise only happen periodically can be triggered immediately.
    268 
    269   The endpoint may also be used to associate a user ID at a very late stage
    270   with the withdrawal --- and still get an immediate failure if we are above
    271   the quota.
    272 
    273   .. note::
    274 
    275     The backend shall **never** just accept this claim that the payment was
    276     confirmed, but instead needs to internally attest that the payment was
    277     successful using provider-specific transaction validation logic!  The point
    278     of this endpoint is merely to trigger this validation **now**.
    279 
    280   **Request:**
    281 
    282   The body of the request must be a `TerminalWithdrawalConfirmationRequest`.
    283 
    284   **Response:**
    285 
    286   :http:statuscode:`204 No content`:
    287     The payment notification was processed successfully.
    288   :http:statuscode:`404 Not found`:
    289     The withdrawal operation was not found.
    290   :http:statuscode:`409 Conflict`:
    291     The withdrawal operation has been previously aborted
    292     and cannot be confirmed anymore.
    293   :http:statuscode:`451 Unavailable for Legal Reasons`:
    294     The withdrawal operation cannot be confirmed because
    295     it would put the user above the legal limit.  The
    296     payment service will eventually bounce the transfer
    297     (if it were to become effective), but the user should
    298     already be shown an error.
    299 
    300   **Details:**
    301 
    302   .. ts:def:: TerminalWithdrawalConfirmationRequest
    303 
    304     interface TerminalWithdrawalConfirmationRequest {
    305 
    306       // A provider-specific transaction identifier.
    307       // This identifier may be used to facilitate the
    308       // backend to check that the credit was confirmed.
    309       provider_transaction_id?: string;
    310 
    311       // The fees which the customer had to pay to the
    312       // provider
    313       terminal_fees?: Amount;
    314 
    315       // A user-specific identifier for quota checks.
    316       user_uuid?: string;
    317 
    318       // ID identifying a lock on the quota that the client
    319       // may wish to use in this operation.  May only be
    320       // present if ``user_uuid`` is also given.
    321       lock?: string;
    322     }
    323 
    324 .. http:get:: /withdrawals/$WITHDRAWAL_ID
    325 
    326   Query information about a withdrawal, identified by the ``WITHDRAWAL_ID``.
    327 
    328   **Request:**
    329 
    330   :query long_poll_ms:
    331     *Optional.*  If specified, the bank will wait up to ``long_poll_ms``
    332     milliseconds for operationt state to be different from ``old_state`` before sending the HTTP
    333     response.  A client must never rely on this behavior, as the bank may
    334     return a response immediately.
    335   :query old_state:
    336     *Optional.* Defaults to "pending".
    337 
    338   **Response:**
    339 
    340   :http:statuscode:`200 OK`:
    341     The withdrawal operation is known to the bank, and details are given
    342     in the `BankWithdrawalOperationStatus` response body.
    343   :http:statuscode:`404 Not found`:
    344     The operation was not found.
    345 
    346 .. http:delete:: /withdrawals/$WITHDRAWAL_ID/abort
    347 
    348   Aborts ``WITHDRAWAL_ID`` operation.  Has no effect on an already aborted
    349   operation.  This endpoint can be used by the terminal if the terminal aborts
    350   the transaction, ensuring that the operation is also aborted at the
    351   bank.
    352 
    353   **Request:**
    354 
    355   The request body is empty.
    356 
    357   **Response:**
    358 
    359   :http:statuscode:`204 No content`:
    360     The withdrawal operation has been aborted.
    361   :http:statuscode:`404 Not found`:
    362     The withdrawal operation was not found.
    363   :http:statuscode:`409 Conflict`:
    364     The withdrawal operation has been confirmed previously and
    365     can't be aborted.
    366 
    367 
    368 Endpoints for Integrated Sub-APIs
    369 ---------------------------------
    370 
    371 .. http:any:: /taler-integration/*
    372 
    373   All endpoints under this prefix are specified by the.
    374   :doc:`GNU Taler bank integration API </core/api-bank-integration>`.
    375   This API handles the communication with Taler wallets.
    376 
    377 
    378 .. http:any:: /taler-wire-gateway/*
    379 
    380    All endpoints under this prefix are specified
    381    by the :doc:`GNU Taler wire gateway API </core/api-bank-wire>`.
    382 
    383    The endpoints are only available for accounts configured with ``is_taler_exchange=true``.