major edits of pay process
This commit is contained in:
parent
1a6f39f407
commit
f0b08e6b4c
@ -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.
|
||||
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}).
|
||||
|
||||
\subsection{Managing browser session state}
|
||||
\subsubsection{Fulfillment}
|
||||
|
||||
% FIXME: this is where we probably want to revise quite a bit,
|
||||
% including improving the description AND addressing the JS-less
|
||||
% implementation.
|
||||
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.
|
||||
|
||||
% Say that this doesn't require accounts!
|
||||
% explain that HTTP session state can be restored
|
||||
% from the wallet state (replay!)
|
||||
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.
|
||||
|
||||
% explain repurchase correlation ID
|
||||
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}.
|
||||
|
||||
% contract vs complete fulfillment 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.
|
||||
|
||||
% 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 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:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user