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}
|
\label{listing:http-contract}
|
||||||
\end{figure*}
|
\end{figure*}
|
||||||
|
|
||||||
|
\subsubsection{Offer}
|
||||||
|
|
||||||
The offer URL of the Web shop can then initiate payments by sending a
|
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
|
\emph{contract proposal} (Figure~\ref{listing:json-contract}) to the
|
||||||
code {\tt 402 Payment Required} (Figure~\ref{listing:http-contract}), or via Taler's JavaScript API
|
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
|
(Figure~\ref{listing:contract}). The wallet then presents the
|
||||||
contract to the user. The format of the contract is in an extensible
|
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
|
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
|
need to be covered by the customer, these are shown together with the
|
||||||
rest of the proposed contract.
|
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}
|
The Taler wallet operates from a securely isolated {\em background}
|
||||||
context on the client side. The user interface that displays the
|
context on the client side. The user interface that displays the
|
||||||
contract and allows the user to confirm the payment is displayed by
|
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
|
would still not have access to the private keys of the coins that are
|
||||||
exclusive to the background context.
|
exclusive to the background context.
|
||||||
|
|
||||||
%The current Taler specification is written to accommodate for
|
If the customer approves the contract by clicking the ``Confirm
|
||||||
%the rather restrictive set of APIs that WebExtension, a
|
Payment'' button (Figure~\ref{subfig:payment}), their wallet signs the
|
||||||
%cross-browser extension API, provides.
|
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,
|
The fulfillment URL uniquely identifies a purchase by some customer,
|
||||||
% including improving the description AND addressing the JS-less
|
while the offer URL identifies a generic offer that is not specific to
|
||||||
% implementation.
|
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!
|
When a customer has completed a purchase, navigating to the
|
||||||
% explain that HTTP session state can be restored
|
fulfillment URL in a browser will show the resource associated with
|
||||||
% from the wallet state (replay!)
|
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
|
If the contract hash does not match a payment which the user
|
||||||
|
already approved, for example because the user obtained the link
|
||||||
A purchase by a customer, completed or in progress, is uniquely
|
from another user, the wallet navigates to the offer URL included
|
||||||
identified by a URL, called the \emph{fulfillment URL}. The
|
in the header.
|
||||||
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?
|
|
||||||
|
|
||||||
\begin{figure*}[t!]
|
\begin{figure*}[t!]
|
||||||
\lstset{language={}}
|
\lstset{language={}}
|
||||||
@ -922,41 +933,7 @@ X-Taler-Offer-Url: https://shop/generate-contract/42
|
|||||||
\label{listing:http-execute}
|
\label{listing:http-execute}
|
||||||
\end{figure*}
|
\end{figure*}
|
||||||
|
|
||||||
In order to ensure that only the paying customer has access to the Web
|
\subsubsection{Discussion}
|
||||||
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.
|
|
||||||
|
|
||||||
Various failure modes are considered in this design:
|
Various failure modes are considered in this design:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user