diff options
Diffstat (limited to 'integration-merchant.rst')
-rw-r--r-- | integration-merchant.rst | 155 |
1 files changed, 103 insertions, 52 deletions
diff --git a/integration-merchant.rst b/integration-merchant.rst index b4e623a9..d8be8037 100644 --- a/integration-merchant.rst +++ b/integration-merchant.rst @@ -1,16 +1,21 @@ .. 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 <http://www.gnu.org/licenses/> @author Marcello Stanisci + @author Christian Grothoff ================================== Interaction with merchant websites @@ -22,52 +27,112 @@ Interaction with merchant websites The payment process +++++++++++++++++++ -Before delving into the technical details, it is worth surveying the payment process from an -abstract point of view. By design, Taler implements the following three points: - -0. The user must accept a contract before paying for something -1. The bought item(s) must be made available again in the future by the merchant to the customer - (in case of physical items, this point means that the merchant must provide the receipt again - in the future to the customer) -2. The user must be able to *share* what he bought; in other words, we want a URI which would - hold any information about the purchase (and therefore the contract), like which items the - user bought and any other relevant detail. This way, any person who may get in possession - of this URI may repeat the same purchase. - -In Taler terminology, we call an *offering URL* an URL of the merchant's website that triggers -the generation of a contract, being it automatically or requiring the user interaction. For example, -some merchants may implement the offering URL such that it just returns the contract's JSON, and -some other may implement it as a shopping chart page where the user can then confirm its purchase and -get the contract JSON. We call a *fulfillment URL* an URL of the merchant's website which implements -points 1. and 2. For example, let's say that Alice bought a movie and a picture, and the fulfillment URL -for this purchase is *http://merchant.example.com/fulfillment?x=8ru42*. Each time Alice visits -*http://merchant.example.com/fulfillment?x=8ru42* she gets the same movie and picture. If then Alice -decides to give Bob this URL and he visits it, then he can decide to buy or not the same movie and -picture. +By design, the Taler payment process ensures the following three properties: + +1. The user must see and accept a contract in a secure context before the payment happens. +2. The payment process must be idempotent, that is at any later time the customer must + be able to replay the payment and again retrieve the online resource he paid for. + In case where a physical item was bought, this online resource is the merchant's + order status page, which may contain tracking information for the customer. +3. The user must be able to *share* the link to both the page with the unpaid offer or + the order status page. If the links are shared with another user, they should + typically allow the other user to perform the same purchase (assuming the item + is still available). + +We call an *offer URL* the user-visible URL of the merchant's Web site +that triggers the generation of a contract, and the display of the +contract to the user via the wallet. The offer URL may include support +for payment systems other than Taler, for example by including a credit +card form in the body. The interaction with the wallet can be started +over JavaScript or by returning a "402 Payment Required" status code +with Taler-specific headers. + +The merchant may have a *contract URL* which generates the contract +in JSON format for Taler. Alternatively, the contract may be embedded +within the page returned by the offer URL and given to the wallet +via JavaScript or via an HTTP header. + +The merchant must have a *fulfillment URL* which checks whether the +customer has paid. When the fulfillment URL is triggered the first +time, this will not (yet) be the case. In this case, the merchant +generates another "402 Payment Required" status code which will trigger +the actual payment from the wallet to the *pay URL*. The wallet will +then reload the fulfillment URL, and this time the merchant should +return the online resource the customer paid for (or the shipping +status for physical goods). + +------- +Example +------- + +For example, suppose Alice wants to pay for a movie. She will first +select the movie from the catalog, which directs her to the offer URL +*https://merchant/offer?x=8ru42*. This URL generates a "402 Payment +Required" response, with a contract stating that Alice is about to buy +some movie. The contract includes a fresh transaction ID, say 62. +Alice's browser detects the response code and displays the contract +for Alice. + +Alice then confirms that she wants to buy the movie. Her wallet +associates her confirmation with the details of the contract. After +Alice confirms, the wallet redirects her to the fulfillment URL, say +*https://merchant/fulfillment?x=8ru42&tid=62* that is specified in the +contract. + +The first time Alice visits this URL, the merchant will again +generate a "402 Payment Required" response, this time not including +the full contract but merely the hash of the contract (which includes +Alice's transaction ID 62), as well as the offer URL (which Alice +will ignore) and the pay URL. Alice's wallet will detect that +Alice already confirmed that she wants to execute this particular +contract. The wallet will then transmit the payment to the pay URL, +obtain a response from the merchant confirming that the payment was +successful, and then reload the fulfillment URL. + +This time (and every time in the future where Alice visits the +fulfillment URL), she receives the movie. If the browser has lost the +session state, the merchant will again ask her to pay, and she will +authenticate by replaying the payment. + +If Alice decides to share the fulfillment URL with Bob and he visits +it, his browser will not have the right session state and furthermore +his wallet will not be able to replay the payment. Instead, his wallet +will automatically redirect Bob to the offer URL and allow him to +purchase the movie himself. + --------------- -Payment details +Making an offer --------------- -A payment process is triggered whenever the user visits a fulfillment URL and he has no rights -in the session state to get the items accounted in the fulfillment URL. Note that when the user is -not visiting a fulfillment URL he got from someone else, it is the wallet which points the browser -to a fulfillment URL after the user accepts the contract. Since each fulfillment URL carries all the -details useful to reconstruct a contract, the merchant reconstructs the contract and sends back to -the user's browser a `taler-execute-payment` DOM event, defined as follows: +The offer URL is a location where the user must pass by in order to +get a contract. + +FIXME: Add more details. - .. code-block:: tsref - { - // base32 encoding of the Contract's hashcode - H_contract: string; +------------------------------- +Fulfillment interaction details +------------------------------- - // URL where to send the deposit permission (AKA coins) - pay_url: string; +A payment process is triggered whenever the user visits a fulfillment +URL and he has no rights in the session state to get the items +accounted in the fulfillment URL. Note that when the user is not +visiting a fulfillment URL he got from someone else, it is the wallet +which points the browser to a fulfillment URL after the user accepts +the contract. - // Offering URL - offering_url: string; - } +A fulfillment URL must carry all the details necessary to reconstruct +a contract. For simple contracts, a Web shop should encode the unique +contract details (in particular, the transaction identifier) in the +URL. This way, the Web shop can generate fulfillment URLs without +actually having to write the full contract proposal to its database. +This allows the merchant to delay disk (write) operations until +customers actually pay. + + +FIXME: This is outdated! Describe 402 vs. JavaScript interactions +as in paper! This event is listened to by the wallet which can take two decisions based on the `H_contract` field: if `H_contract` is known to the wallet, then the user has already accepted the contract @@ -78,17 +143,3 @@ state for the claimed item(s) to ``payed`` and now the wallet can point again th fulfillment URL and finally get the claimed item(s). It's worth noting that each deposit permission is associated with a contract and the wallet can reuse the same deposit permission to get the item(s) mentioned in the contract without spending new coins. - ------------- -The contract ------------- - -As said, the offering URL is a location where the user must pass by in order to get a contract, and -the contract is handed by the merchant to the browser by the mean of a `taler-confirm-contract` DOM -event, defined as follows: - - .. code-block:: tsref - - { - contract_wrapper: Offer; - } |