..
This file is part of GNU TALER.
Copyright (C) 2014, 2015, 2016 INRIA
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
@author Marcello Stanisci
@author Florian Dold
=================================
Merchant Reference Implementation
=================================
-----------------------
Architectural Overview
-----------------------
The merchant reference implementationis divided into two independent
compontents, the `frontend` and the `backend`.
The `frontend` is the existing shopping portal of the merchant.
The architecture tries to minimize the amount of modifications necessary
to the `frontend` as well as the trust that needs to be placed into the
`frontend` logic. Taler requires the frontend to facilitate two
JSON-based interactions between the wallet and the `backend`, and
one of those is trivial.
The `backend` is a standalone C application intended to implement all
the cryptographic routines required to interact with the Taler wallet
and a Taler exchange.
------------------------------
The Frontent HTTP API
------------------------------
.. http:get:: /taler/contract
Triggers the contract generation. Note that the URL may differ between
merchants.
**Request:**
The request depends entirely on the merchant implementation.
**Response**
:status 200 OK: The request was successful. The body contains an :ref:`offer `.
:status 400 Bad Request: Request not understood.
:status 500 Internal Server Error:
In most cases, some error occurred while the backend was generating the
contract. For example, it failed to store it into its database.
------------------------------
The Merchant Backend HTTP API
------------------------------
The following API are made available by the merchant's `backend` to the merchant's `frontend`.
.. http:post:: /contract
Ask the backend to add some missing (mostly related to cryptography) information to the contract.
**Request:**
The `proposition` that is to be sent from the frontend is a `contract` object without the fields
* `exchanges`
* `auditors`
* `H_wire`
* `merchant_pub`
The `backend` then completes this information based on its configuration.
**Response**
:status 200 OK:
The backend has successfully created the contract. It responds with a `ContractBackendResponse`_ object. This request should virtually always be successful.
On success, the `frontend` should pass this response verbatim to the wallet.
:status 403 Forbidden:
The frontend used the same transaction ID twice. This is only allowed if the response from the backend was lost ("instant" replay), but to assure that frontends usually create fresh transaction IDs this is forbidden if the contract was already paid. So attempting to have the backend sign a contract for a contract that was already paid by a wallet (and thus was generated by the frontend a "long" time ago), is forbidden and results in this error. Frontends must make sure that they increment the transaction ID properly and persist the largest value used so far.
**Details:**
.. _ContractBackendResponse:
.. code-block:: tsref
interface ContractBackendResponse {
// Contract with additional fields added by the backend.
contract : Object;
// Signature of the merchant over the contract.
// Purpose: TALER_SIGNATURE_MERCHANT_CONTRACT
merchant_sig: EddsaSignature;
// Hash of the contract, technically redundant, but allows
// the frontend to not have logic for canonicalizing the
// contract and doing the hasing itself.
H_contract: HashCode;
}
.. http:post:: /pay
Asks the `backend` to execute the transaction with the exchange and deposit the coins.
**Request:**
The `frontend` passes the :ref:`deposit permission `
received from the wallet, and optionally adding a field named `pay_deadline`,
indicating a deadline by which he would expect to receive the bank transfer
for this deal. Note that the `pay_deadline` must be after the `refund_deadline`.
The backend calculates the `pay_deadline` by adding the `wire_transfer_delay`
value found in the configuration to the current time.
**Response:**
:status 200 OK:
The exchange accepted all of the coins. The `frontend` should now fullfill the
contract. This response has no meaningful body, the frontend needs to
generate the fullfillment page.
:status 412 Precondition Failed:
The given exchange is not acceptable for this merchant, as it is not in the
list of accepted exchanges and not audited by an approved auditor.
:status 403 Forbidden:
The exchange rejected the payment because a coin was already spent before.
The response will include the `coin_pub` for which the payment failed,
in addition to the response from the exchange to the `/deposit` request.
The `backend` will return verbatim the error codes received from the exchange's
:ref:`deposit ` API. If the wallet made a mistake, like by
double-spending for example, the `frontend` should pass the reply verbatim to
the browser/wallet. This should be the expected case, as the `frontend`
cannot really make mistakes; the only reasonable exception is if the
`backend` is unavailable, in which case the customer might appreciate some
reassurance that the merchant is working on getting his systems back online.