From 735fb8a89f51875196783b167e8ae622368808fc Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Mon, 26 Dec 2016 18:42:18 +0100 Subject: Still on splitting --- integration-merchant.rst | 315 ----------------------------------------------- 1 file changed, 315 deletions(-) delete mode 100644 integration-merchant.rst (limited to 'integration-merchant.rst') diff --git a/integration-merchant.rst b/integration-merchant.rst deleted file mode 100644 index f3221617..00000000 --- a/integration-merchant.rst +++ /dev/null @@ -1,315 +0,0 @@ -.. - This file is part of GNU TALER. - -.. - Note that this page is more a protocol-explaination than a guide that teaches - merchants how to work with Taler wallets - - 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 Christian Grothoff - -================================== -Interaction with merchant websites -================================== - -.. _payprot: - -+++++++++++++++++++ -The payment process -+++++++++++++++++++ - -By design, the Taler payment process ensures the following properties: - -1. The user must see and accept a contract in a secure context before the payment happens. - That contract accounts for all the items which are supposed to be bought. - -2. The payment process must be idempotent, that is at any later time the customer must - be able to replay the payment and retrieve the 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. - Note that by `replaying the payment` we mean reusing the `same coins` used to pay for - the product the first time to get the `same product` the user got the first time. - So the replay does NOT subtract further credit from the user's total budget. - -3. Purchases are shareable: any purchase is given a URL that allows other users to - buy the same item(s). - -We call an *offer URL* any URL at the merchant's Web site that notifies the -wallet that the user needs to pay for something. The offer URL must take into -account that the user has no wallet installed, and manage the situation accordingly -(for example, by showing a credit card paywall). The notification can happen either -via JavaScript or via HTTP headers. - -The merchant needs to have a *contract URL* which generates the JSON -contract 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 also provide a *pay URL* to which the wallet can -transmit the payment. Again, how this URL is made known from the merchant -to the wallet, it is managed by the HTTP headers- or JavaScript-based protocol. - -The merchant must also have a *fulfillment URL*, that addresses points 2 and 3 above. -In particular, fulfillment URL is responsible for: - -* Deliver the final product to the user after the payment -* Instruct the wallet to send the payment to the pay URL -* Redirect the user to the offer URL in case they hit a shared fulfillment URL. - -Again, Taler provides two ways of doing that: JavaScript- and HTTP headers-based. - -Taler helps merchants on the JavaScript-based interaction by providing the -``taler-wallet-lib``. See https://git.taler.net/web-common.git/tree/taler-wallet-lib.ts - -------- -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, and will instruct the wallet about the contract's -URL. Then the wallet downloads the contract that states that Alice is -about to buy a 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 and a hash 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 (as it happened the -very first time she visited the fulfillment URL), 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. - -.. _offer: - ---------------- -Making an offer ---------------- - -When a user visits a offer URL, the merchant returns a page that can interact -with the wallet either via JavaScript or by returning a "402 Payment Required". -This page's main objective is to inform the wallet on where it should get the -contract. In case of JavaScript interaction, the merchant should just return -a page whose javascript contains an invocation to ``offerContractFrom()`` -from ``taler-wallet-lib``. This function will download the contract from -`` and hand it to the wallet. - -In case of HTTP headers-based protocol, the merchant needs to set the header -`X-Taler-contract-url` to the contract URL. Once this information reaches the -browser, the wallet will takes action by reading that header and downloading -the contract. - -Either way, the contract gets to the wallet which then renders it to the user. - -.. _fulfillment: - -------------------------------- -Fulfillment interaction details -------------------------------- - -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 after the user accepts a -contract, the wallet will automatically point the browser to the -fulfillment URL. - -Becasue fulfillment URLs implements replayable and shareable payments -(see points 2,3 above), fulfillment URL parameter must encompass all the -details necessary to reconstruct a contract. - -That saves the merchant from writing contracts to disk upon every contract -generation, and defer this operation until customers actually pay. - -.................. -HTTP headers based -.................. - -Once the fulfillment URL gets visited, deliver the final product if the user has -paid, otherwise: the merchant will reconstruct the contract and re-hash it, sending -back to the client a "402 Payment required" status code and some HTTP headers which -will help the wallet to manage the payment. Namely: - -* `X-taler-contract-hash` -* `X-taler-pay-URL` -* `X-taler-offer-URL` - -The wallet then looks at `X-taler-contract-hash`, and can face two situations: - -1. This hashcode is already present in the wallet's database (meaning that the user did accept the related contract), so the wallet can send the payment to `X-taler-pay-URL`. During this operation, the wallet associates the coins it sent to `X-taler-pay-URL` with this hashcode, so that it can replay payments whenever it gets this hashcode again. - -2. This hashcode is unknown to the wallet (meaning that the user visited a shared fulfillment URL). The wallet then points the browser to `X-taler-offer-URL`, which is in charge of generating a contract referring to the same items accounted in the fulfillment URL. Of course, the user is then able to accept or not the contract. - -................ -JavaScript based -................ - -Once the fulfillment URL gets visited, deliver the final product if the user has paid, otherwise: -the merchant will reconstruct the contract and re-hash it. Then it will return a page whose JavaScript -needs to include a call to ``taler.executeContract(..)``. See the following example: - -.. sourcecode:: html - - - - - - - .. - - - -The logic which will take place is the same as in the HTTP header based protocol. -Once ``executePayment(..)`` gets executed in the browser, it will hand its three -parameters to the wallet, which will: - -1. Send the payment to `` if `` is found in its database (meaning that the user accepted it). -2. Redirect the browser to ``, if `` is NOT found in its database, meaning that the user visited a shared fulfillment URL. - --------------------- -Example: Essay Store --------------------- - -This section is a high-level description of a merchant :ref:`frontend `, -and is inspired by our demonstration essay store running at `https://blog.demo.taler.net/`. -Basically, it tells how the frontend reacts to clients visiting `offer` and `fulfillment` -URLs. - -The website is implemented in Python+Flask, and is available at -https://git.taler.net/merchant-frontends.git/tree/talerfrontends/blog. - -The desired effect is that the homepage has a list of buyable articles, and once the -user clicks on one of them, they will either get the Taler :ref:`contract ` -or a credit card paywall if they have no Taler wallet installed. - -In particular, any buyable article on the homepage links to an `offer URL`: - -.. sourcecode:: html - - - ... -

How to write a frontend

- ... - - -whence the offer URL design is as follows:: - - https:///essay/ - -`` is just a token that uniquely identifies the article within the shop. - -The server-side handler for the offer URL will return a special page to the client that -will either HTTP GET the contract from the frontend, or show the credit card paywall. -See `above `_ how this special page works. - -It is interesting to note that the fulfillment URL is just the offer URL plus -two additional parameters. It looks as follows:: - - https:///essay/?tid=×tamp= - -.. note:: - - Taler does not require that offer and fulfillment URL have this kind of relationship. - In fact, it is perfectly acceptable for the fulfillment URL to be hosted on a different - server under a different domain name. - -The fulfillment URL server-side handler implements the following logic: it checks the state -to see if `` has been payed, and if so, returns the article to the user. -If the user didn't pay, then it `executes` the contract by returning a special page to the -browser. The contract execution is the order to pay that the frontend gives to the wallet. - -Basically, the frontend points the wallet to the hashcode of the contract which is to be paid -and the wallet responds by giving coins to the frontend. Because the frontend doesn't perform -any cryptographic work by design, it forwards ``, `` and -`` to the frontend in order to get the contract's hashcode. - -See `above `_ for a detailed description of how the frontend triggers the -payment in the wallet. - -.................. -State and security -.................. - -The server-side state gets updated in two situations, (1) when an article is -"about" to be bought, which means when the user visits the fulfillment URL, -and (2) when the user actually pays. For (1), we use the contract hascode to -access the state, whereas in (2) we just define a list of payed articles. -For example: - -.. sourcecode:: python - - session[] = {'article_name': 'How_to_write_a_frontend'} # (1) - session['payed_articles'] = ['How_to_write_a_frontend', 'How_to_install_a_backend'] # (2) - -The list of payed articles is used by the frontend to deliver the article to the user: -if the article name is among ``session['payed_articles']``, then the user gets what they -paid for. - -The reason for using `` as the key is to prevent the wallet to send bogus -parameters along the fulfillment URL. `` is the contract hashcode that -the fulfillment handler gets from the backend using the fulfillment URL parameters. - -In fact, when the wallet sends the payment to the frontend pay handler, it has to provide -both coins and contract hashcode. That hascode is (1) verified by the backend when it -receives the coins, (2) used by the frontend to update the list of payed articles. - -See below an example of pay handler: - -.. sourcecode:: python - - ... - - # 'deposit_permission' is the JSON object sent by the wallet - # which contains coins and the contract hashcode. - response = send_payment_to_backend(deposit_permission) - - # The backend accepted the payment - if 200 == response.status_code: - # Here we pick the article name from the state defined at - # fulfillment time. - # deposit_permission['H_contract'] is the contract hashcode - payed_article = session[deposit_permission['H_contract']]['article_name'] - session['payed_articles'].append(payed_article) - - -So the wallet is forced to send a valid contract hashcode along the payment, -and since that hashcode is then used to update the list of payed articles, -the wallet is forced to send fulfillment URL parameters that match that hashcode, -therefore being valid parameters. -- cgit v1.2.3