From 67232ff07977b83288577b060e0f1bab4bb27293 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 7 Jan 2020 20:22:46 +0100 Subject: restructure bank docs, update wire plugin HTTP API --- core/api-bank.rst | 409 +----------------------------------------- core/api-wire-plugin-bank.rst | 171 ++++++++++++++++++ core/index.rst | 1 + 3 files changed, 177 insertions(+), 404 deletions(-) create mode 100644 core/api-wire-plugin-bank.rst (limited to 'core') diff --git a/core/api-bank.rst b/core/api-bank.rst index be492b58..82ccda60 100644 --- a/core/api-bank.rst +++ b/core/api-bank.rst @@ -17,50 +17,14 @@ @author Marcello Stanisci @author Christian Grothoff -========= -Bank API -========= +============== +Taler Bank API +============== -.. contents:: Table of Contents - - -------- -Testing -------- - -.. _bank-register: -.. http:post:: /register - - This API provides programmatic user registration at the bank. +This chapter describe the APIs that banks need to offer to tightly integrate with GNU Taler. - **Request** The body of this request must have the format of a - `BankRegistrationRequest`. - - **Response** - - :status 200 OK: - The new user has been correctly registered. - :status 409 Conflict: - The username requested by the client is not available anymore. - :status 406 Not Acceptable: - Unacceptable characters were given for the username. See - https://docs.djangoproject.com/en/2.2/ref/contrib/auth/#django.contrib.auth.models.User.username - for the accepted character set. - -**Details** - -.. ts:def:: BankRegistrationRequest - - interface BankRegistrationRequest { - - // Username to use for registration; max length is 150 chars. - username: string; +.. contents:: Table of Contents - // Password to associate with the username. Any characters and - // any length are valid; next releases will enforce a minimum length - // and a safer characters choice. - password: string; - } ----------- Withdrawing @@ -117,366 +81,3 @@ Withdrawing // if the user used the default exchange. exchange_url: string; } - ---------------------------------- -Making and Rejecting Transactions ---------------------------------- - -.. _bank-deposit: -.. http:post:: /admin/add/incoming - - This API allows one user to send money to another user, within the same "test" - bank. The user calling it has to authenticate by including his credentials in the - request. - - - **Request:** The body of this request must have the format of a `BankDepositRequest`. - - **Response:** - - :status 200 OK: - The request has been correctly handled, so the funds have been transferred to - the recipient's account. The body is a `BankDepositDetails` - :status 400 Bad Request: The bank replies a `BankError` object. - :status 406 Not Acceptable: The request had wrong currency; the bank replies a `BankError` object. - - **Details:** - - .. ts:def:: BankDepositDetails - - interface BankDepositDetails { - - // Timestamp related to the transaction being made. - timestamp: Timestamp; - - // Row id number identifying the transaction in the bank's - // database. - row_id: number; - } - - .. ts:def:: BankDepositRequest - - interface BankDepositRequest { - - // Authentication method used - auth: BankAuth; - - // JSON 'amount' object. The amount the caller wants to transfer - // to the recipient's count - amount: Amount; - - // Exchange base URL, used to perform tracking requests against the - // wire transfer ID. Note that in the actual bank wire transfer, - // the schema may have to be encoded differently, i.e. - // "https://exchange.com/" may become "https exchange.com" due to - // character set restrictions. It is the responsibility of the - // wire transfer adapter to properly encode/decode the URL. - // Payment service providers must ensure that their URL is short - // enough to fit together with the wire transfer identifier into - // the wire transfer subject of their respective banking system. - exchange_url: string; - - // The subject of this wire transfer. - subject: string; - - // The sender's account identificator. NOTE, in the current stage - // of development this field is _ignored_, as it's always the bank account - // of the logged user that plays as the "debit account". - // In future releases, a logged user may specify multiple bank accounts - // of her/his as the debit account. - debit_account: number; - - // The recipient's account identificator - credit_account: number; - - } - - .. ts:def:: BankAuth - - interface BankAuth { - - // authentication type. At this stage of development, - // only value "basic" is accepted in this field. - // The credentials must be indicated in the following HTTP - // headers: "X-Taler-Bank-Username" and "X-Taler-Bank-Password". - type: string; - } - - - .. ts:def:: BankError - - interface BankError { - - // Human readable explanation of the failure. - error: string; - - // Numeric Taler error code (`TALER_ErrorCode`) - ec: number; - - } - - -.. http:put:: /reject - - Rejects an inbound transaction. This can be used by the receiver of a wire transfer to - cancel that transaction, nullifying its effect. This basically creates a correcting - entry that voids the original transaction. Henceforth, the /history must show - the original transaction as "cancelled+" or "cancelled-" for creditor and debitor respectively. - This API is used when the exchange receives a wire transfer with an invalid wire - transfer subject that fails to decode to a public key. - - **Request** The body of this request must have the format of a `BankCancelRequest`. - - :query auth: - authentication method used. At this stage of development, only - value ``"basic"`` is accepted. Note that username and password need to be - given as request's headers. - The dedicated headers are: ``X-Taler-Bank-Username`` and ``X-Taler-Bank-Password``. - :query row_id: row identifier of the transaction that should be cancelled. - :query account_number: - bank account for which the incoming transfer was made and - for which ``auth`` provides the authentication data. - **Currently ignored**, as multiple bank accounts per user are not implemented yet. - - .. ts:def:: BankCancelRequest - - interface BankCancelRequest { - - // Authentication method used - auth: BankAuth; - - // The row id of the wire transfer to cancel - row_id: number; - - // The recipient's account identificator - credit_account: number; - - } - - **Response** In case of an error, the body is a `BankError` object. - - :status 204 No Content: The request has been correctly handled, so the original transaction was voided. The body is empty. - :status 400 Bad Request: The bank replies a `BankError` object. - :status 404 Not Found: The bank does not know this rowid for this account. - - ---------------------- -Querying Transactions ---------------------- - - -.. http:get:: /history-range - - Filters and returns the list of transactions in the time range specified by - ``start`` and ``end`` - - **Request** - - :query auth: - authentication method used. At this stage of development, only - value ``"basic"`` is accepted. Note that username and password need to be - given as request's headers. The dedicated headers are: - ``X-Taler-Bank-Username`` and ``X-Taler-Bank-Password``. - :query start: - unix timestamp indicating the oldest transaction accepted in - the result. - :query end: - unix timestamp indicating the youngest transaction accepted in - the result. - :query direction: - argument taking values ``debit`` or ``credit``, according to - the caller willing to receive both incoming and outgoing, only outgoing, or - only incoming records. Use ``both`` to return both directions. - :query cancelled: - argument taking values ``omit`` or ``show`` to filter out rejected - transactions - :query account_number: - bank account whose history is to be returned. *Currently ignored*, as - multiple bank accounts per user are not implemented yet. - :query ordering: - can be ``descending`` or ``ascending`` and regulates whether - the row are returned youger-to-older or vice versa. Defaults to - ``descending``. - - - **Response** - - :status 200 OK: JSON object whose field ``data`` is an array of type `BankTransaction`. - :status 204 No content: in case no records exist for the targeted user. - - -.. http:get:: /history - - Filters and returns the list of transactions for the bank account of the - customer specified in the request. Clients must provide authentication - information via the ``X-Taler-Bank-Username`` and ``Taler-Bank-Password`` - headers. - - Transactions are identified by an opaque string identifier, referred to here - as "row ID". The semantics of the row ID (including its sorting order) are - determined by the bank server and completely opaque to the client. - - The list of returned transactions is determined by a row ID *starting point* - and a signed non-zero integer *delta*: - - * If *delta* is positive, return a list of up to *delta* transactions (all matching - the filter criteria) strictly **after** the starting point. The transactions are sorted - in **ascending** order of the row ID. - * If *delta* is negative, return a list of up to *-delta* transactions (allmatching - the filter criteria) strictly **before** the starting point. The transactions are sorted - in **descending** order of the row ID. - - If *starting point* is not explicitly given, it defaults to: - - * A value that is **smaller** than all other row IDs if *delta* is **positive**. - * A value that is **larger** than all other row IDs if *delta* is **negative**. - - **Request** - - :query start: *Optional.* - Row identifier to explicitly set the *starting point* of the query. - :query delta: - The *delta* value that determines the range of the query. - :query direction: - Filter transactions by type. Can be ``debit`` to return only - transactions that debit this account, ``credit`` to return only transactions - that credit this account, or ``both`` for both types. - :query cancelled: - Filter transactions by their cancellation state. - Can be ``omit`` to omit rejected transactions or ``show`` to keep rejected transaction. - :query account_number: - Bank account whose history is to be returned. - *Currently ignored*, as multiple bank accounts per user are not implemented - yet. - :query long_poll_ms: *Optional.* If this parameter is specified and the - result of the query would be empty, the bank will wait up to ``long_poll_ms`` - milliseconds for new transactions that match the query to arrive and only - then send the HTTP response. A client must never rely on this behavior, as - the bank may return a response immediately or after waiting only a fraction - of ``long_poll_ms``. - - **Response** - - :status 200 OK: JSON object whose field ``data`` is an array of type `BankTransaction`. - :status 204 No content: in case no records exist for the targeted user. - - .. ts:def:: BankTransaction - - interface BankTransaction { - - // identification number of the record - row_id: number; - - // Date of the transaction - date: Timestamp; - - // Amount transferred - amount: Amount; - - // "-" if the transfer was outgoing, "+" if it was - // incoming; "cancel+" or "cancel-" if the transfer - // was /reject-ed by the receiver. - sign: string; - - // Bank account number of the other party involved in the - // transaction. - counterpart: number; - - // Wire transfer subject line. - wt_subject: string; - - } - - .. - The counterpart currently only points to the same bank as - the client using the bank. A reasonable improvement is to - specify a bank URL too, so that Taler can run across multiple - banks. - ------------------------- -Interactions with wallet ------------------------- - -.. warning:: - - This section is completely outdated. - -A bank and a wallet need to communicate for (1) make some elements visible -only if the wallet is installed, (2) exchange information when the user withdraws -coins. - -Make elements visible. -^^^^^^^^^^^^^^^^^^^^^^ - -This feature works via CSS injection from the wallet. To enable it, the -page must contain the ```` element, so that -the wallet will do the injection. - -Whenever a element ```` needs to be visualized (hidden) if the wallet is -installed, the special class ``taler-installed-show`` (``taler-installed-hide``) -must be added to ``x``, as follows: - -* ``y`` will make ``y`` visible. -* ``y`` will make ``y`` visible. - -Clearly, a fallback page must be provided, which will be useful if the -wallet is *not* installed. This special page will hide any element of -the class ``taler-install-show``; it can be downloaded at the following -URL: ``git://taler.net/web-common/taler-fallback.css``. - -Withdrawing coins -^^^^^^^^^^^^^^^^^ - -After the user confirms the withdrawal, the bank must return a ``202 Accepted`` response, -along with the following HTTP headers: - -* ``X-Taler-Operation: create-reserve`` -* ``X-Taler-Callback-Url: ``; this URL will be automatically visited by the wallet after the user confirms the exchange. -* ``X-Taler-Wt-Types: '["test"]'``; stringified JSON list of supported wire transfer types (only 'test' supported so far). -* ``X-Taler-Amount: ``; stringified Taler-style JSON :ref:`amount `. -* ``X-Taler-Sender-Wire: ``; stringified `WireDetails`. -* ``X-Taler-Suggested-Exchange: ``; this header is optional, and ```` is the suggested exchange URL as given in the ``SUGGESTED_EXCHANGE`` configuration option. - -.. ts:def:: WireDetails - - interface WireDetails { - // Only 'test' value admitted so far. - type: string; - - // URL of the bank. - bank_uri: string; - - // bank account number of the user attempting to withdraw. - account_number: number; - } - -After the user confirms the exchange to withdraw coins from, the wallet will -visit the callback URL, in order to let the user answer some security questions -and provide all relevant data to create a reserve. - -.. note:: - Currently, the bank is in charge of creating the reserve at the chosen - exchange. In future, the exchange will "poll" its bank account and automatically - creating a reserve whenever it receives any funds, without any bank's - intervention. - -The callback URL implements the following API. - -.. http:get:: - - **Request** - - :query amount_value: integer part of the amount to be withdrawn. - :query amount_fraction: fractional part of the amount to be withdrawn. - :query amount_currency: currency of the amount to be withdrawn. - :query exchange: base URL of the exchange where the reserve is to be created. - :query reserve_pub: public key of the reserve to create. - :query exchange_wire_details: stringification of the chosen exchange's `WireDetails`. - - **Response** - - Because the wallet is not supposed to take action according to this response, - the bank implementers are not required to return any particular status code here. - - For example, our demonstrator bank always redirects the browser to the user's - profile page and let them know the outcome via a informational bar. diff --git a/core/api-wire-plugin-bank.rst b/core/api-wire-plugin-bank.rst new file mode 100644 index 00000000..a56027d2 --- /dev/null +++ b/core/api-wire-plugin-bank.rst @@ -0,0 +1,171 @@ +.. + This file is part of GNU TALER. + Copyright (C) 2019 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING. If not, see + +========================== +Taler Bank Wire Plugin API +========================== + +This section describes the API that the ``taler-bank`` wire plugin expects. +This API is currently implemented by the Taler Demo Bank, as well as by +LibEuFin (work in progress). + + +-------------- +Authentication +-------------- + +The wire plugin authenticates requests to the bank service via the +``X-Taler-Bank-Username`` and ``X-Taler-Bank-Password`` headers. + +------------------- +Making Transactions +------------------- + + +.. http:post:: /taler/transaction + + This API allows the exchange to make a transaction, typically to a merchant. The bank account + of the exchange is not included in the request, but instead derived from the user name in the + authentication header. + + To make the API idempotent, the client must include a nonce. Requests with the same nonce + are rejected unless the request is the same. + + **Request:** The body of this request must have the format of a `TransactionRequest`. + + **Response:** + + :status 200 OK: + The request has been correctly handled, so the funds have been transferred to + the recipient's account. The body is a `TransactionResponse` + :status 400 Bad Request: The bank replies a `BankError` object. + :status 406 Not Acceptable: The request had wrong currency; the bank replies a `BankError` object. + + **Details:** + + .. ts:def:: TransactionResponse + + interface TransactionResponse { + + // Timestamp related to the transaction being made. + timestamp: Timestamp; + + // Opaque of the transaction that the bank has made. + row_id: string; + } + + .. ts:def:: TransactionRequest + + interface TransactionResponse { + // Nonce to make the request idempotent. Requests with the same + // transaction_uid that differ in any of the other fields + // are rejected. + transaction_uid: HashCode; + + // Amount to transfer. + amount: Amount; + + // Reserve public key, will be included in the details + // of the wire transfer. + reserve_pub: string; + + // The recipient's account identifier as a payto URI + credit_account: string; + } + + + .. ts:def:: BankError + + interface BankError { + + // Human readable explanation of the failure. + error: string; + + // Numeric Taler error code (`TALER_ErrorCode`) + ec: number; + } + + +-------------------------------- +Querying the transaction history +-------------------------------- + +.. http:get:: /taler/history + + Return a list of transactions made to the exchange. The transaction + list shall be filtered to only include transactions that include a valid + reserve public key. + + The bank account of the exchange is determined via the user name in the ``X-Taler-Bank-Username`` header. + In fact the transaction history might come from a "virtual" account, where multiple real bank accounts + are merged into one history. + + Transactions are identified by an opaque string identifier, referred to here + as "row ID". The semantics of the row ID (including its sorting order) are + determined by the bank server and completely opaque to the client. + + The list of returned transactions is determined by a row ID *starting point* + and a signed non-zero integer *delta*: + + * If *delta* is positive, return a list of up to *delta* transactions (all matching + the filter criteria) strictly **after** the starting point. The transactions are sorted + in **ascending** order of the row ID. + * If *delta* is negative, return a list of up to *-delta* transactions (allmatching + the filter criteria) strictly **before** the starting point. The transactions are sorted + in **descending** order of the row ID. + + If *starting point* is not explicitly given, it defaults to: + + * A value that is **smaller** than all other row IDs if *delta* is **positive**. + * A value that is **larger** than all other row IDs if *delta* is **negative**. + + **Request** + + :query start: *Optional.* + Row identifier to explicitly set the *starting point* of the query. + :query delta: + The *delta* value that determines the range of the query. + :query long_poll_ms: *Optional.* If this parameter is specified and the + result of the query would be empty, the bank will wait up to ``long_poll_ms`` + milliseconds for new transactions that match the query to arrive and only + then send the HTTP response. A client must never rely on this behavior, as + the bank may return a response immediately or after waiting only a fraction + of ``long_poll_ms``. + + **Response** + + :status 200 OK: JSON object whose field ``transactions`` is an array of type `BankTransaction`. + :status 204 No content: in case no records exist for the targeted user. + + .. ts:def:: BankTransaction + + interface BankTransaction { + + // Opaque identifier of the returned record + row_id: string; + + // Date of the transaction + date: Timestamp; + + // Amount transferred + amount: Amount; + + // Payto URI to identify the sender of funds + debit_account: string; + + // The reserve public key extracted from the transaction details + reserve_pub: string; + } + diff --git a/core/index.rst b/core/index.rst index 9e770c74..ce4b451a 100644 --- a/core/index.rst +++ b/core/index.rst @@ -32,6 +32,7 @@ interfaces between the core components of Taler. api-common api-error api-exchange + api-wire-plugin-bank api-merchant api-auditor api-bank -- cgit v1.2.3