From 4d85ea42e9f51297b537ee67ad923ccbc6ba008c Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Tue, 6 Dec 2016 21:42:34 +0100 Subject: Still on fulfillment --- php/doc/tutorial.texi | 54 ++++++++++++++++++++++++++++++----------------- php/generate-contract.php | 3 +-- 2 files changed, 36 insertions(+), 21 deletions(-) (limited to 'php') diff --git a/php/doc/tutorial.texi b/php/doc/tutorial.texi index d085cda..ac496da 100644 --- a/php/doc/tutorial.texi +++ b/php/doc/tutorial.texi @@ -160,8 +160,8 @@ the ``donate'' button is clicked, the customer will receive a Taler contract offering him the opportunity to make a fixed donation, for example to donate 1 KUDOS to the charity operating the shop. -Please note the all the code samples shown below in the tutorial -can be found at @url{https://git.taler.net/merchant-frontend-examples.git/tree/php}. +All the code samples shown below in the tutorial can be found at +@url{https://git.taler.net/merchant-frontend-examples.git/tree/php}. @c NOTE: include explaining wallet installation to Web developer here! @@ -175,7 +175,7 @@ credit card payments. @cindex backend @cindex configuration @cindex currency -For many critical operations, the frontend we will need to communicate +For many critical operations, the frontend needs to communicate with a Taler backend. Assuming that you do not yet have a backend configured, you can use the public backend provided by the Taler project for testing. This public backend has been set-up at @@ -200,7 +200,7 @@ need to specify the currency used by the backend. For example: @cindex backend Given the above configuration, we can now implement two simple functions @code{get_to_backend} and @code{post_to_backend} to -send requests to the backend. The function @code{get_to_backend}, +send requests to the backend. The function @code{get_to_backend} is in charge of performing HTTP GET requests to the backend, while @code{post_to_backend} will send HTTP POST requests. @@ -209,7 +209,7 @@ while @code{post_to_backend} will send HTTP POST requests. @verbatiminclude ../backend.php @end smallexample -The given backend code uses a few helper functions from +The given @code{backend.php} code uses a few helper functions from @code{php/helpers.php}, which should be self-explanatory. @@ -248,12 +248,15 @@ A minimalistic @code{donate.php} implementation is shown below (in PHP): Given this response, the Taler wallet will fetch the contract from @url{/generate-contract.php} and display it to the user. +If the wallet is not present, the HTML body will be shown and the +Taler headers and the 402 status code ought to be ignored by the +browser. @section A helper function to generate the proposed contract We first define a helper function @code{make_contract} that will generate a complete Taler contract as a nested PHP array. The -function takes only the transaction ID and the timestamp as arguments, +function takes only the transaction ID and the timestamp as arguments; all of the other details of the contract are hardcoded in this simple example. @@ -285,10 +288,6 @@ A simple @code{/generate-contract.php} handler may thus look like this: @verbatiminclude ../generate-contract.php @end smallexample -If the wallet is not present, the HTML body will be shown and the -Taler headers and the 402 status code ought to be ignored by the -browser. - @c FIXME: improve example to do this right? Note that in practice the frontend might want to generate a monotonically increasing series of transaction IDs to avoid a chance of collisions. @@ -336,7 +335,7 @@ https://shop.com/fulfillment.php? \ transaction_id=×tamp= @end smallexample -The fulfillment handler will at @code{/fulfillment.php} +The fulfillment handler at @code{/fulfillment.php} will use this information to check if the user has already paid, and if so confirm the donation. If the user has not yet paid, it will instead return another ``402 Payment Required'' @@ -364,7 +363,7 @@ This URL specifies where we expect the wallet to send the payment. @cindex X-Taler-Offer-Url In case that the wallet does not know about this contract already, i.e. because a user shared the URL with another user, this tells the -wallet where to go to retrieve the original offer. +wallet where to go to retrieve a fresh offer. @c FIXME: do implement offer-URL properly for the tutorial! @end table @@ -748,7 +747,14 @@ directly via the fulfillment URI, there is no delivery location. @item repurchase_correlation_id @cindex repurchase correlation ID -FIXME: explain!!! +A string that identifies the product(s), without relying on contract-specific +information like timestamps and transaction IDs. For example, it may be +set to "Charity donation" in our example shop. This field purpose is to +prevent the wallet to pay twice in case the customer visitis a shared fulfillment +URL for a product they already paid for. In particular, if Alice and Bob +both make a donation, and Alice then visits Bob's fulfillment URL, then +Alice will not pay again. This field is needed for how the wallet detects +paid contracts internally, see section @ref{The fulfillment page}. @item merchant @table @var @@ -850,7 +856,7 @@ parameter to @code{executePayment}. @end itemize -@node The Fulfillment page +@node The fulfillment page @section Design considerations for the fulfillment page @cindex fulfillment page @@ -876,11 +882,21 @@ In order to implement property (2), the frontend will firstly check the state to see if the product claimed among the fulfillment URL parameter has been paid; if so, the product is given to the customer. Otherwise, the frontend sets the payment as "pending" in the -state and @emph{executes} it in the wallet. The payment execution is -performed by returning JavaScript code from @code{taler-wallet-lib.js} -that triggers the wallet to send the payment to the pay page. Once -the pay page receives the payment, it sets the state for the payment -as "payed". +state and @emph{executes} it in the wallet. The payment execution is +performed by returning information needed by the wallet to issue the +payment. As seen in section @ref{Initiating the payment process}, +this information must include the contract's hashcode (that the frontend +can compute using the fulfillment URL parameters). +The hashcode is then used by the wallet to check if that contract has +already been paid -- for each paid contract, the wallet keeps the used +coins and retrieves them via the contract's hashcode. In other words, +if the hashcode is known to the wallet, then it retrieves the associated +coins from internal DB, and re-issues the payment with them; otherwise, +it uses new coins to pay, and then stores them in DB using the new hashcode +as index. Once the pay page receives the payment, it sets the state for +the payment as "payed". Finally, the wallet points again the browser +to the fulfillment URL which now delivers the claimed product to the +customer. diff --git a/php/generate-contract.php b/php/generate-contract.php index c94ca8b..20c6331 100644 --- a/php/generate-contract.php +++ b/php/generate-contract.php @@ -5,10 +5,9 @@ include 'backend.php'; include 'error.php'; + $transaction_id = rand(1,90000); // simplified, do not do this! // this variable is the JSON of a contract proposal, // see https://api.taler.net/api-merchant.html#post--contract - // the second parameter is the transaction id - $transaction_id = rand(1,90000); // simplified, do not do this! $proposal = make_contract($transaction_id, new DateTime('now')); // Here the frontend POSTs the proposal to the backend $response = post_to_backend("/contract", $proposal); -- cgit v1.2.3