From f0b08e6b4c02138abd4ecaab5fc9a661ed050efc Mon Sep 17 00:00:00 2001
From: Christian Grothoff <christian@grothoff.org>
Date: Fri, 26 Aug 2016 15:32:27 +0200
Subject: major edits of pay process

---
 articles/ui/ui.tex | 147 ++++++++++++++++++++++-------------------------------
 1 file changed, 62 insertions(+), 85 deletions(-)

(limited to 'articles/ui/ui.tex')

diff --git a/articles/ui/ui.tex b/articles/ui/ui.tex
index d1f95523b..c48d76494 100644
--- a/articles/ui/ui.tex
+++ b/articles/ui/ui.tex
@@ -825,9 +825,12 @@ X-Taler-Contract-Url: https://shop/generate-contract/42
   \label{listing:http-contract}
 \end{figure*}
 
+\subsubsection{Offer}
+
 The offer URL of the Web shop can then initiate payments by sending a
-\emph{contract proposal} (Figure~\ref{listing:json-contract}) to the wallet, either via the HTTP status
-code {\tt 402 Payment Required} (Figure~\ref{listing:http-contract}), or via Taler's JavaScript API
+\emph{contract proposal} (Figure~\ref{listing:json-contract}) to the
+wallet, either via the HTTP status code {\tt 402 Payment Required}
+(Figure~\ref{listing:http-contract}), or via Taler's JavaScript API
 (Figure~\ref{listing:contract}).  The wallet then presents the
 contract to the user.  The format of the contract is in an extensible
 JSON-based format defined by Taler and not HTML, as the rendering of
@@ -836,16 +839,6 @@ representation of the terms and prices.  In case that transaction fees
 need to be covered by the customer, these are shown together with the
 rest of the proposed contract.
 
-If the customer approves the contract by clicking the ``Confirm
-Payment'' button (Figure~\ref{subfig:payment}), their wallet signs the
-contract with enough coins to cover the contract's cost, stores all of
-the information in its local database, and transmits the payment to
-the {\em payment} URI of the Web shop.  Once the Web shop confirms the
-payment, the wallet redirects the browser to the {\em fulfillment} URL
-provided by the merchant (Figure~\ref{subfig:fulfillment}).
-
-\subsection{Browser security}
-
 The Taler wallet operates from a securely isolated {\em background}
 context on the client side.  The user interface that displays the
 contract and allows the user to confirm the payment is displayed by
@@ -857,44 +850,62 @@ wallet's payment page (Figure~\ref{subfig:payment}), as such a page
 would still not have access to the private keys of the coins that are
 exclusive to the background context.
 
-%The current Taler specification is written to accommodate for
-%the rather restrictive set of APIs that WebExtension, a
-%cross-browser extension API, provides.
-
-\subsection{Managing browser session state}
-
-% FIXME: this is where we probably want to revise quite a bit,
-% including improving the description AND addressing the JS-less
-% implementation.
-
-% Say that this doesn't require accounts!
-% explain that HTTP session state can be restored
-% from the wallet state (replay!)
-
-% explain repurchase correlation ID
-
-% contract vs complete fulfillment URL
-
-% design that allows merchant to not store any information
-
-A purchase by a customer, completed or in progress, is uniquely
-identified by a URL, called the \emph{fulfillment URL}.  The
-information contained in the fulfillment URL must allow the merchant
-to restore the full contract that was associated with the purchase,
-either directly from the URL or indirectly from an identifier in a
-database.  Efficiently reconstructing the contract entirely from the
-URL instead of using costly database transactions can be important, as
-costly disk operations for incomplete purchases make merchants
-more susceptible to denial-of-service attacks from adversaries
-pretending to be customers.
-
-When a customer completed a purchase, navigating to the fulfillment
-URL in a browser will show the resource associated with the purchase.
-This resource can be a digital good such as a news article, or simply
-a confirmation for products that are delivered by other means.
-
-% FIXME: maybe we should have the URL that we are requesting
-% in the example, and not just the response?
+If the customer approves the contract by clicking the ``Confirm
+Payment'' button (Figure~\ref{subfig:payment}), their wallet signs the
+contract with enough coins to cover the contract's cost, stores all of
+the information in its local database, and redirects the browser to
+the {\em fulfillment} URL provided by the merchant in the contract
+(Figure~\ref{subfig:fulfillment}).
+
+\subsubsection{Fulfillment}
+
+The fulfillment URL uniquely identifies a purchase by some customer,
+while the offer URL identifies a generic offer that is not specific to
+a customer.  The purchase identified by a fulfillment URL may have
+been completed or still be in progress.  The information contained in
+the fulfillment URL must allow the merchant to restore the full
+contract (including a unique transaction identifier) that was
+associated with the purchase, either directly from the URL or
+indirectly from an identifier in a database.  Efficiently
+reconstructing the contract entirely from the URL instead of using
+costly database transactions can be important, as costly disk
+operations for incomplete purchases make merchants more susceptible to
+denial-of-service attacks from adversaries pretending to be customers.
+
+When a customer has completed a purchase, navigating to the
+fulfillment URL in a browser will show the resource associated with
+the purchase.  This resource can be a digital good such as a news
+article, or simply a confirmation for products that are delivered by
+other means.
+
+When a customer has not yet completed a purchase (this is always the
+case when a customer visits the fulfillment URL for the first time),
+or when the Web shop cannot confirm that this visitor has paid for the
+contract, for example because the session state was
+lost,\footnote{This can happen when when privacy conscious users
+  delete their cookies.  Also, some user agents (such as the TOR
+  browser) do not support persistent (non-session) cookies.} the Web
+store responds by (again) triggering a payment process (either via
+JavaScript or using {\tt 402 Payment Required}, see
+Figure~\ref{listing:http-execute}).  However, unlike the response from
+the offer URL, the 402 response from the fulfillment page includes the
+headers {\tt X-Taler-Contract-Hash}, {\tt X-Taler-Pay-Url} and {\tt
+  X-Taler-Offer-Url}.
+
+If the contract hash matches a payment which the user already
+previously approved, the wallet reacts to this by injecting the logic
+to transmit the payment to the {\em pay} URL of the Web shop into
+the page.  Then the wallet inspects the response as it may contain
+error reports about a failed payment which the wallet has to handle.
+By submitting the payment this way, we also ensure that this
+intermediate request does not require JavaScript and still does not
+interfer with navigation.  Once the Web shop confirms the payment, the
+wallet causes the fulfillment URL to be reloaded.
+
+If the contract hash does not match a payment which the user
+already approved, for example because the user obtained the link
+from another user, the wallet navigates to the offer URL included
+in the header.
 
 \begin{figure*}[t!]
   \lstset{language={}}
@@ -922,41 +933,7 @@ X-Taler-Offer-Url: https://shop/generate-contract/42
   \label{listing:http-execute}
 \end{figure*}
 
-In order to ensure that only the paying customer has access to the Web
-resources behind the fulfillment URL, the Web store's server must
-check the browser's session state.  If the merchant can confirm that
-the visitor has paid, the respective Web resource is returned.  If the
-merchant cannot confirm that the visitor has paid for the contract,
-for example because the session state was lost,\footnote{This can
-  happen when when privacy conscious users delete their cookies.
-  Also, some user agents (such as the TOR browser) do not support
-  persistent (non-session) cookies.} it {\em again} triggers a payment
-process (either via JavaScript or using {\tt 402 Payment Required}, see Figure~\ref{listing:http-execute}).
-Since the fulfillment URL refers to a contract that typically is already known
-to the user's wallet, it suffices to pass the contract hash (instead of
-full contract) to the wallet.
-If the user previously approved paying for the contract with this hash, the
-wallet will (re-)transmit the signed coins that are associated
-with the contract to the merchant.
-
-When a user visits a fulfillment URL without having the associated
-contract in their wallet, the wallet redirects the browser to the {\em
-  offer} URL for that purchase, if applicable.  This behavior is
-useful when a user wishes to share a fulfillment link with another
-user to point him to the same resource.
-
-Note that due to the limited WebExtensions API, the session state can
-only be acquired when the wallet causes the browser to navigate to the
-fulfillment URL (first without session state), since the session state
-must be set from the same origin as the fulfillment URL.  As a result,
-the shop cannot simply return the fulfillment information in response
-to the wallet performing the payment.  However, this extra round trip
-is also justified as the wallet needs to inspect the response anyway
-as it may contain error reports about a failed payment which the wallet
-has to handle.  Finally, it ensures that the fulfillment page is fetched
-via an HTTP GET request instead of an HTTP POST request, which is
-important to nicely support the use of navigation (``back'', ``forward''
-buttons) and bookmarks.
+\subsubsection{Discussion}
 
 Various failure modes are considered in this design:
 
-- 
cgit v1.2.3

