summaryrefslogtreecommitdiff
path: root/example-essay-store.rst
blob: f498ad4f7e106c814d2f87047355b3011dbda93b (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
..
  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

==================================
Example: Essay Store
==================================

..
  The main page of the essay store shows links to essays of the form `/essay?name=:name`.
  
  The `/essay` URL takes the following query parameters:
   * `name`: mandatory, name of the essay
   * `tid`: optional, transaction ID generated by the merchant for the
     contract that was used to purchase an instance of the article
   * `timestamp`, optional, timestamp for the contract that was used to purchase
     the essay with the given `tid`.
  
  These are the steps for showing `/essay`.  If the wallet is not present in
  steps 2 and 3, the user agent is redirected to a mock credit card
  payment page.
  
  1. The server checks the status of the the essay with the name `name` in the server-side
     session state
  
    * If the essay is marked as payed, display the essay.
    * Otherwise proceed with step 2
  
  2. The server checks if the `tid` and `timestamp` query parameters are present
  
    * If `tid` and `timestamp` are present, restore the contract for the essay
      (using `tid` as transaction id in the contract, `timestamp` as timestamp
      and `timestamp+REFUND_DELTA` as refund deadline) and emit the
      `taler-execute-contract` DOM event in the user agent.
    * Otherwise proceed with step 3
  
  3. The server generates a new contract and emits the `taler-confirm-contract` DOM event in the user agent,
     with the essay name as repurchase correlation identifier and `/essay?name=:name?tid=:tid` as fulfillment url.
  
  
  In step 2, the `taler-execute-contract` event has the following parameters:
  
  * `H_contract`: hash of the contract that was restored
  * `payment_url`: The internal URL `/pay?H_contract=...` of the essay store,
    will set the server-side session state for the article associated with the
    contract hash on successful coin deposit.  The contract hash is associated
    with the article name in the server-side session state when the contract is restored.
  * `offer_url`: Link to a teaser page (`/teaser?name=...`), which also contains a link to the article
    page, without the `tid` parameter.
  
  
  Note that we assume that all essays cost the same (otherwise the amount would have to be included in
  the restoration information in the /essay fulfillment URL).  The refund deadline is computed
  by adding the merchant-specific constant `REFUND_DELTA` to the contract's timestamp.

..
  Describing implementation of the above scenario

--------------
Before reading
--------------
To properly understand this example, the reader should be familiar with Taler's terminology;
in particular, definitions like `contract`, `fulfillment URL`, `offering URL`, `IIG` and `deposit permission`,
are assumed to be known.  Refer to :ref:`contract`, :ref:`payprot` and :ref:`deposit` in order to get
some general insight on terms and interactions between components.

This section describes how the demonstrator essay store interacts with the Taler system.  As for Taler's
terminology, the demonstrator essay store is an example of `frontend`.
This demonstrator lies in `examples/blog` of `git://taler.net/merchant/examples/blog`

The essay store, available at https://blog.demo.taler.net, is such that its homepage
is a list of buyable articles and each article is a reference to an `offering
URL` (see :ref:`offer`).  In particular, this offering URL has the following format:

  `https://blog.demo.taler.net/essay_fulfillment.php?article=articleId`

It is worth noting that in our implementation the `offering` and the `fulfillment` URLs
differ only respect to the parameters given to the path `/essay_fulfillment.php`.  Namely,
the offering URL becomes a fulfillment URL whenever the user adds the parameters needed to
reconstruct the contract, which are `tid` (transaction id) and `timestamp`
(see :ref:`contract`, and :ref:`ffil`).  For the sake of completeness,


  `https://blog.demo.taler.net/essay_fulfillment.php?article=articleId&tid=3489&timestamp=8374738`

would be a fulfillment URL.

Once the user visits the offering URL by clicking on some article's title, the merchant

1. checks if the state associated to this article corresponds to "payed".  If this is the
   case, point 7. is triggered, which is what happens when point 0 of :ref:`offer` is true.

2. checks if the user gave additional parameters to the URL above, actually making it a
   fulfillment URL.  If so, jump to point `y`.

3. returns a page which can detect if a Taler wallet is installed in the user's browser and,
   if so, automatically downloads the contract from the merchant; if not, displays a paywall
   for credit card payment.  Note that the contract's request is entirely managed by the page's
   JavaScript and not by the wallet; that gives more flexibility to the merchants by reducing
   the communication between wallets and shops. The wallet gets involved once the
   contract arrives and the JavaScript fires a `taler-confirm-contract` event containing the
   contract, see point 1. of :ref:`offer`.

4. the wallet visits the fulfillment URL associated with this purchase (the fulfillment
   URL's path is indicated in the contract, so the wallet has to just add `tid` and `timestamp`
   to it).

5. the same script as in point 1. gets executed, but this time it detects that the user is visiting
   a fulfillment URL.  The script can now reconstruct the contract and store its hash in the state.
   The hash is stored in an associative array having resource names as keys; in this case the key
   `articleId` points to the contract's hash.  This way is easier to detect if a resource which is
   to be payed is actually mentioned in the deposit permission.  Without this control, a malicious
   wallet can send a deposit permission for `articleA` and get the resource `articleB`, see point 6.
   As a last step, the script returns a page which fires a `taler-execute-payment` event in the user's
   browser carrying the same data structure as in point 4. of :ref:`offer`.
   Note that both in point 3. and 5. the HTML page returned is the same, namely it is the page showing
   the credit card payment.  It is designed so that it is possible to `inject` the event to fire at the
   user's browser.  So in point 3. the injected event is `taler-confirm-contract`, and in point 5. is
   `taler-execute-payment`.  This way if the Taler wallet responds to the event, then the payment is
   kept Taler-style, otherwise the user just sees a credit card form (without making further requests).

6. the wallet POSTs the deposit permission to `pay_url`, which is

   `https://blog.demo.taler.net/essay_pay.php?article=articleId`
   
   This step is responsible for setting the state for `articleId` as payed;  to that end it uses
   `articleId` as the key to get `H_contract` from the state and checks if `H_contract` equals
   the contract's hash contained in the deposit permission.  If they are equal, then the deposit
   permission is forwarded to the backend.  If the backend return a HTTP status 200, then `essay_pay.php`
   sets the state for `articleId` as payed and notify the wallet about the payment's outcome.
   If the backend reports any problem, `essay_pay.php` will just forward the data gotten from the
   backend to the wallet, which will be in charge of managing the error.

7. the wallet visit the fulfillment URL, but now the state for `articleId` is set to payed, so the
   script will just show the wanted article.

  `https://blog.demo.taler.net/essay_fulfillment.php?article=articleId&tid=3489&timestamp=8374738`

----------------------
IIG by fulfillment URL
----------------------

TBD