summaryrefslogtreecommitdiff
path: root/core/api-terminal.rst
blob: 91d9b7e6007fb1dcf027a1d61e2b0e1f722f1215 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
..
  This file is part of GNU TALER.

  Copyright (C) 2024 Taler Systems SA

  TALER is free software; you can redistribute it and/or modify it under the
  terms of the GNU Affero General Public License as published by the Free Software
  Foundation; either version 2.1, or (at your option) any later version.

  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License along with
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>

.. target audience: developer, core developer

.. _terminal-api:

============
Terminal API
============

.. contents:: Table of Contents
  :local:

Introduction
------------

Terminals are devices where users can withdraw digital cash.

This API is offered by a payment service backend and is used by such
terminals.  It enables imposing limits on withdrawals per unique user ID (and
communicating such limits to the terminals) as well as setting up and
triggering withdrawal operations.

Implementations of this API typically interact with a terminal-specific
payment service (or a bank) to realize the service.


Authentication
--------------

Terminals must authenticate against all terminal API using basic auth according to `HTTP basic auth <https://tools.ietf.org/html/rfc7617>`_.


Config
------

.. http:get:: /config

  Return the protocol version and configuration information about the bank.
  This specification corresponds to ``current`` protocol being version **0**.

  **Response:**

  :http:statuscode:`200 OK`:
    Response is a `TerminalConfig`.

  **Details:**

  .. ts:def:: TerminalConfig

    interface TerminalConfig {
      // Name of the API.
      name: "taler-terminal";

      // libtool-style representation of the Bank protocol version, see
      // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
      // The format is "current:revision:age".
      version: string;

      // Terminal provider display name to be used in user interfaces.
      provider_name: string;

      // The currency supported by this Terminal-API
      // must be the same as the currency specified 
      // in the currency field of the wire gateway config
      currency: string;

      // Wire transfer type supported by the terminal.
      // FIXME: needed?
      wire_type: string;
    }


.. http:get:: /quotas/$UUID

  Obtain the current transaction limit for the given $UUID.
  The UUID should be an encoding of a unique identifier of
  the user.

  **Response:**

  :http:statuscode:`200 OK`:
    Response is a `WithdrawLimit`.

  **Details:**

  .. ts:def:: WithdrawLimit

    interface WithdrawLimit {
      // Maximum amount that can be withdrawn now.
      limit: Amount;

      // Time when the limit may increase.
      expiration: Timestamp;
    }


.. http:post:: /quotas/$UUID/lock

  This endpoint allows a terminal to reserve a given amount
  from the user's quota, ensuring that a subsequent operation
  will not fail due to a quota violation.

  **Request:**

  The request should be a `WithdrawLimitLock`.

  **Response:**

  :http:statuscode:`204 No content`:
    The change was accepted.
  :http:statuscode:`409 Conflict`:
    The proposed lock would push the user above the limit.

  **Details:**

  .. ts:def:: WithdrawLimitLock

    interface WithdrawLimitLock {

      // Amount that should be reserved from the quota.
      limit: Amount;

      // ID for the lock.  FIXME: could also be 32-byte nonce?
      lock: string;

      // How long should the lock be held?
      expiration: Timestamp;
    }

.. http:delete:: /quotas/$UUID/lock/$LOCK

  This endpoint allows the terminal to clear a lock it may have
  previously created.

  **Response:**

  :http:statuscode:`204 No content`:
    The lock was cleared.
  :http:statuscode:`404 Not found`:
    The lock is unknown.
  :http:statuscode:`409 Conflict`:
    The lock was already used in a withdrawal operation.


.. http:post:: /withdrawals

  This endpoint allows the terminal to set up a new withdrawal
  operation.

  **Request:**

  The request should be a `TerminalWithdrawalSetup`.

  **Response:**

  :http:statuscode:`200 Ok`:
    The operation was created.  The response will be
    a `TerminalWithdrawalSetupResponse`.
  :http:statuscode:`404 Not found`:
    A lock was specified but the lock is not known for
    the given user.
  :http:statuscode:`409 Conflict`:
    A conflicting withdrawal operation already exists or
    the amount would violate the quota for the specified user.

  **Details:**

  .. ts:def:: TerminalWithdrawalSetup

    interface TerminalWithdrawalSetup {

      // Amount to withdraw.  If given, the wallet
      // cannot change the amount!
      amount?: Amount;

      // Suggested amount to withdraw. If given, the wallet can
      // still change the suggestion.
      suggested_amount?: Amount;

      // A provider-specific transaction identifier.
      // This identifier may be used to attest the
      // payment at the provider's backend. Optional,
      // as we may not know it at this time.
      provider_transaction_id?: string;

      // The non-Taler fees the customer will have
      // to pay to the service provider
      // they are using to make this withdrawal.
      // If the fees cannot be precalculated,
      // they can be specified in the /withdrawals/$WITHDRAWAL_ID/check
      // request after the transaction was executed.
      terminal_fees?: Amount;

      // Unique request ID to make retried requests idempotent.
      request_uid: string;

      // Unique user ID of the user.  Optional
      // in case a user Id is not (yet) known.
      user_uuid?: string;

      // ID identifying a lock on the quota that the client
      // may wish to use in this operation.  May only be
      // present if ``user_uuid`` is also given.
      lock?: string;
    }

  .. ts:def:: TerminalWithdrawalSetupResponse

    interface TerminalWithdrawalSetupResponse {

      // ID identifying the withdrawal operation being created.
      withdrawal_id: string;
    }


.. http:post:: /withdrawals/$WITHDRAWAL_ID/check

  Endpoint for providers to notify the terminal backend about a payment having
  happened.  This will cause the bank to validate the transaction and allow
  the withdrawal to proceed. The API is idempotent, meaning sending a payment
  notification for the same ``WITHDRAWAL_ID`` return successfuly but not
  change anything.  This endpoint is always *optional*: the bank, exchange and
  wallet should all eventually notice the wire transfer with or without this
  endpoint being called.  However, by calling this endpoint checks that might
  otherwise only happen periodically can be triggered immediately.

  The endpoint may also be used to associate a user ID at a very late stage
  with the withdrawal --- and still get an immediate failure if we are above
  the quota.

  .. note::

    The backend shall **never** just accept this claim that the payment was
    confirmed, but instead needs to internally attest that the payment was
    successful using provider-specific transaction validation logic!  The point
    of this endpoint is merely to trigger this validation **now**.

  **Request:**

  The body of the request must be a `TerminalWithdrawalConfirmationRequest`.

  **Response:**

  :http:statuscode:`204 No content`:
    The payment notification was processed successfully.
  :http:statuscode:`404 Not found`:
    The withdrawal operation was not found.
  :http:statuscode:`409 Conflict`:
    The withdrawal operation has been previously aborted
    and cannot be confirmed anymore.
  :http:statuscode:`451 Unavailable for Legal Reasons`:
    The withdrawal operation cannot be confirmed because
    it would put the user above the legal limit.  The
    payment service will eventually bounce the transfer
    (if it were to become effective), but the user should
    already be shown an error.

  **Details:**

  .. ts:def:: TerminalWithdrawalConfirmationRequest

    interface TerminalWithdrawalConfirmationRequest {

      // A provider-specific transaction identifier.
      // This identifier may be used to facilitate the
      // backend to check that the credit was confirmed.
      provider_transaction_id?: string;

      // The fees which the customer had to pay to the 
      // provider
      terminal_fees?: Amount;

      // A user-specific identifier for quota checks.
      user_uuid?: string;

      // ID identifying a lock on the quota that the client
      // may wish to use in this operation.  May only be
      // present if ``user_uuid`` is also given.
      lock?: string;
    }

.. http:get:: /withdrawals/$WITHDRAWAL_ID

  Query information about a withdrawal, identified by the ``WITHDRAWAL_ID``.

  **Request:**

  :query long_poll_ms:
    *Optional.*  If specified, the bank will wait up to ``long_poll_ms``
    milliseconds for operationt state to be different from ``old_state`` before sending the HTTP
    response.  A client must never rely on this behavior, as the bank may
    return a response immediately.
  :query old_state:
    *Optional.* Default to "pending".

  **Response:**

  :http:statuscode:`200 OK`:
    The withdrawal operation is known to the bank, and details are given
    in the `BankWithdrawalOperationStatus` response body.
  :http:statuscode:`404 Not found`:
    The operation was not found.

.. http:delete:: /withdrawals/$WITHDRAWAL_ID/abort

  Aborts ``WITHDRAWAL_ID`` operation.  Has no effect on an already aborted
  operation.  This endpoint can be used by the terminal if the terminal aborts
  the transaction, ensuring that the operation is also aborted at the
  bank.

  **Request:**

  The request body is empty.

  **Response:**

  :http:statuscode:`204 No content`:
    The withdrawal operation has been aborted.
  :http:statuscode:`404 Not found`:
    The withdrawal operation was not found.
  :http:statuscode:`409 Conflict`:
    The withdrawal operation has been confirmed previously and
    can't be aborted.


Endpoints for Integrated Sub-APIs
---------------------------------

.. http:any:: /taler-integration/*

  All endpoints under this prefix are specified by the.
  :doc:`GNU Taler bank integration API </core/api-bank-integration>`.
  This API handles the communication with Taler wallets.


.. http:any:: /taler-wire-gateway/*

   All endpoints under this prefix are specified
   by the :doc:`GNU Taler wire gateway API </core/api-bank-wire>`.

   The endpoints are only available for accounts configured with ``is_taler_exchange=true``.