gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-merchant-frontend-examples] branch master updated (3


From: gnunet
Subject: [GNUnet-SVN] [taler-merchant-frontend-examples] branch master updated (39074ad -> 51c41de)
Date: Sun, 15 Oct 2017 17:15:32 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a change to branch master
in repository merchant-frontend-examples.

    from 39074ad  style PHP docs
     new fbd4260  clean up tutorials
     new 51c41de  bump version

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .gitignore                               |  11 +
 common/html/js-wallet.html               |  26 ++
 common/texi/api-reference.texi           |  88 +++++
 {python/doc => common/texi}/fdl-1.3.texi |   0
 common/texi/fulfillment-page.texi        |  30 ++
 common/texi/instances.texi               |  24 ++
 common/texi/js-payments.texi             |  69 ++++
 {python/doc => common/texi}/lgpl.texi    |   0
 common/texi/normalized-base-url.texi     |  22 ++
 common/texi/proposals.texi               | 186 +++++++++++
 {python/doc => common/texi}/syntax.texi  |   0
 common/texi/version.texi                 |   4 +
 common/texi/wallet-detection.texi        |  62 ++++
 php/doc/inline-proposals.texi            |  22 ++
 php/doc/tutorial.texi                    | 547 ++-----------------------------
 php/doc/version.texi                     |   4 -
 python/doc/tutorial.texi                 | 242 ++++++++------
 python/doc/version.texi                  |   4 -
 18 files changed, 715 insertions(+), 626 deletions(-)
 create mode 100644 common/html/js-wallet.html
 create mode 100644 common/texi/api-reference.texi
 rename {python/doc => common/texi}/fdl-1.3.texi (100%)
 create mode 100644 common/texi/fulfillment-page.texi
 create mode 100644 common/texi/instances.texi
 create mode 100644 common/texi/js-payments.texi
 rename {python/doc => common/texi}/lgpl.texi (100%)
 create mode 100644 common/texi/normalized-base-url.texi
 create mode 100644 common/texi/proposals.texi
 rename {python/doc => common/texi}/syntax.texi (100%)
 create mode 100644 common/texi/version.texi
 create mode 100644 common/texi/wallet-detection.texi
 create mode 100644 php/doc/inline-proposals.texi
 delete mode 100644 php/doc/version.texi
 delete mode 100644 python/doc/version.texi

diff --git a/.gitignore b/.gitignore
index a1aef6c..e8425a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,14 @@ php/doc/arch.*
 common/graphics/*.png
 common/graphics/*.pdf
 common/graphics/*.jpg
+*~
+python/doc/arch.png
+python/doc/arch_nobo.jpg
+python/doc/arch_nobo.pdf
+python/doc/tutorial.aux
+python/doc/tutorial.cp
+python/doc/tutorial.cps
+python/doc/tutorial.html
+python/doc/tutorial.log
+python/doc/tutorial.pdf
+python/doc/tutorial.toc
diff --git a/common/html/js-wallet.html b/common/html/js-wallet.html
new file mode 100644
index 0000000..1154eba
--- /dev/null
+++ b/common/html/js-wallet.html
@@ -0,0 +1,26 @@
+<html lang="en">
+  <head>
+    <script src="/web-common/taler-wallet-lib.js" 
type="application/javascript">
+    </script>
+  </head>
+  <body>
+    <div id="content">
+    </div>
+    <script type="application/javascript">
+
+      content = document.getElementById("content");
+      p = document.createElement("p");
+
+      function walletInstalled(){
+        p.textContent = "Wallet installed!";
+        content.appendChild(p);
+      }
+      function walletNotInstalled(){
+        p.textContent = "Wallet not found.";
+        content.appendChild(p);
+      }
+      taler.onPresent(wallerInstalled);
+      taler.onAbsent(wallerNotInstalled);
+    </script>
+  </body>
+</html>
diff --git a/common/texi/api-reference.texi b/common/texi/api-reference.texi
new file mode 100644
index 0000000..6e3cd52
--- /dev/null
+++ b/common/texi/api-reference.texi
@@ -0,0 +1,88 @@
address@hidden Reference
address@hidden Reference
+
address@hidden
+* Headers for HTTP 402::                 Headers for the 402 status code and 
their effect on the user agent's operation
+* JavaScript API::                       JavaScript API to communicate with 
the wallet
+* Stylesheet-based presence detection::  Presence detection using CSS style 
sheets and no JavaScript
address@hidden menu
+
address@hidden Headers for HTTP 402
address@hidden Headers for HTTP 402
+The HTTP status code @code{402 Payment Required} can be used by the merchant
+frontend to trigger operations related to payments in the user agent.  The user
+agent associates at most one proposal with every URL via the proposal's
address@hidden field.  The associated proposal is either missing (in
+case it doesn't exist), paid (in case the payment for it was successfully sent
+to the merchant) or unpaid.  If the associated proposal is unpaid,  @code{402
+Payment Required} will cause the user agent to pay for the associated proposal.
+
+The following headers for @code{402 Payment Required} are recognized by Taler 
and further influence the processing:
address@hidden @code
address@hidden X-Taler-Refund-Url
+If this header present, the value of this header must be a URL that the user 
agent can use to request and process refunds.
+
address@hidden X-Taler-Contract-Url
+If there is no associated proposal, the user agent will fetch a proposal from
+this URL and process it.  This typically prompts the user to agree to pay.
+
address@hidden X-Taler-Offer-Url
+If there is no associated proposal and @code{X-Taler-Contract-Url} is not
+specified, the browser will navigate to this URL.
+
address@hidden X-Taler-User-Tipping-Url
+If this header present, the value of this header must be a URL that the user 
agent can use to obtain tips (small, non-binding
+financial rewards) payed from the merchant to the user's wallet.  If this 
field is present, @code{X-Taler-User-Tipping-Exchange}
+and @code{X-Taler-User-Tipping-Amount} must also be present.
+
address@hidden X-Taler-User-Tipping-Exchange
+Exchange base URL for the exchange that the merchant helps withdrawing the tip 
from.
+
address@hidden X-Taler-User-Tipping-Amount
+Amount of tip that the user is receiving, in the standard amount format 
(CURR:X.Y).
+
address@hidden table
+
address@hidden JavaScript API
address@hidden JavaScript API
+
+The following functions are defined in the @code{taler} namespace of the 
@code{taler-wallet-lib} helper library
+available at 
@url{https://git.taler.net/web-common.git/tree/taler-wallet-lib.js}.
+
address@hidden @code
address@hidden onPresent(callback: () => void)
+Add a callback to be called when support for Taler payments is detected.
+
address@hidden onAbsent(callback: () => void)
+Add a callback to be called when support for Taler payments is disabled.
+
address@hidden pay(@{contract_url: string, offer_url: address@hidden)
+Results in the same action as a @code{402 Payment Required} with 
@code{contract_url} in
+the @code{X-Taler-Contract-Url} header and @code{offer_url} in the 
@code{X-Taler-Payment-Url} header.
+
address@hidden refund(refund_url: string)
+Results in the same action as a @code{402 Payment Required} with 
@code{refund_url} in
+the @code{X-Taler-Refund-Url} header.
+
address@hidden table
+
address@hidden Stylesheet-based presence detection
address@hidden Stylesheet-based presence detection
+
+Stylesheet-based presence detection will be applied on all pages that have the
address@hidden attribute of the @code{html} element set @code{true}.
+The default/fallback stylesheet, that will be taken over by the wallet once
+installed, must be included with the id @code{taler-presence-stylesheet}, like
+this:
+
+The following CSS classes can be used:
address@hidden @code
address@hidden taler-installed-hide
+A CSS rule will set the @code{display} property for this class to @code{none} 
once the Taler wallet is installed and enabled.
+If the wallet is not installed, @code{display} will be @code{inherit}.
+
address@hidden taler-installed-show
+A CSS rule will set the @code{display} property for this class to 
@code{inherit} once the Taler wallet is installed and enabled.
+If the wallet is not installed, @code{display} will be @code{none}.
+
address@hidden table
diff --git a/python/doc/fdl-1.3.texi b/common/texi/fdl-1.3.texi
similarity index 100%
rename from python/doc/fdl-1.3.texi
rename to common/texi/fdl-1.3.texi
diff --git a/common/texi/fulfillment-page.texi 
b/common/texi/fulfillment-page.texi
new file mode 100644
index 0000000..5ae9628
--- /dev/null
+++ b/common/texi/fulfillment-page.texi
@@ -0,0 +1,30 @@
address@hidden Section of advanced topics discussing the fulfillment page in 
more depth.
+
address@hidden The fulfillment page
address@hidden The fulfillment page
address@hidden fulfillment page
+
+This section describes some of the design considerations for the fulfillment 
page.
+They are primarily relevant for high-performance setups.
+
+The fulfillment page mechanism is designed to provide the following two 
properties:
+
address@hidden
address@hidden Taler payments @emph{can} be implemented in DB-less frontends.
+
address@hidden Taler payments are replayable, meaning that each purchase is 
associated with
+a URL (the fulfillment URL) that shows the product each time it gets visited 
(and
+of course, only the first time takes the user's money).
address@hidden enumerate
+
+Both properties are gotten "for free" by the way replayable payments are
+implemented. Since @code{pay.php} simply relays payments to the backend,
+if the latter returns "200 OK", then the frontend delivers what is mentioned
+in the backend's response.  Note that along with the "200 OK" response,
+the backend returns the whole proposal associated with the fulfillment
+URL that triggered the payment, so the frontend has all the information
+useful to pick the right product to deliver.
+The "payment" relayed to the backend contains the @emph{order id},
+that allows the backend to perform all the integrity checks on the
+payment.
+This way, the frontend does not need any database to replay payments.
diff --git a/common/texi/instances.texi b/common/texi/instances.texi
new file mode 100644
index 0000000..42f0099
--- /dev/null
+++ b/common/texi/instances.texi
@@ -0,0 +1,24 @@
address@hidden Section from ``advanced topics'' introducing the concept of 
instances
+
address@hidden Instances
address@hidden Instances
address@hidden instances
+
+Taler's design allows a single backend to manage multiple frontends.
+In other words, we might have multiple shops relying on the same backend.
+As of terminology, we call @emph{instance} any of the frontends accounted
+by the same backend.
+
+The backend's RESTful API allows frontends to specify which instance they are.
+However, this specification is optional, and a ``default'' instance will be
+used whenever the frontend does not specify one.
+
+Please note that in this stage of development, the backend's REST call 
@code{/history}
+returns records for @emph{any} instance.  The rationale behind is to allow 
grouping
+``public'' business entities under the same backend.
+
+This way, a single frontend can expose multiple donation buttons for multiple
+receivers, and still operate against one backend. So in this scenario, there 
is no
+harm if the operator of instance `a' sees history entries related to instance 
`b'.
+
+See @code{https://donations.demo.taler.net/}, which uses this functionality.
diff --git a/common/texi/js-payments.texi b/common/texi/js-payments.texi
new file mode 100644
index 0000000..6c88069
--- /dev/null
+++ b/common/texi/js-payments.texi
@@ -0,0 +1,69 @@
address@hidden Section about triggering payments via JavaScript, currently not 
used!
+
address@hidden Payments using JavaScript
address@hidden Triggering payments using JavaScript
address@hidden
+Please note that the following examples are purely instructional and NOT TESTED
+along with the tutorial code.
address@hidden
address@hidden JavaScript
address@hidden
address@hidden Offering contracts
address@hidden
+Offering contracts the JavaScript way doesn't require us to set HTTP
+headers, and so -- in a minimalistic implementation -- the donation button
+should just hit a HTML page that invokes the @code{offerContractFrom} function,
+from the @code{taler-wallet-lib.js} library.
address@hidden
+Thus our homepage can now look as follows
address@hidden
address@hidden
+// ../index-js.html
address@hidden ../index-js.html
address@hidden smallexample
address@hidden
address@hidden is now in charge of calling @code{offerContractFrom}
+passing the contract URL to it, which is @code{"/generate-order.php"} in
+our example.  See below.
+
address@hidden
address@hidden
+// ../donate-js.html
address@hidden ../donate-js.html
address@hidden smallexample
address@hidden
+Please make sure that @code{taler-wallet-lib.js} location is valid.
address@hidden
address@hidden Receiving payments
address@hidden payment
address@hidden
+In the example in section @ref{Initiating the payment process}, the fulfillment
+handler @code{/fulfillment.php} triggers the payment in the wallet by returing
+the three needed values (contract hashcode, pay URL, offer URL) via HTTP 
headers.
address@hidden
+The same action can be accomplished @emph{with} JavaScript, thanks to
address@hidden of @emph{web-common} repository.
+The fulfillment handler needs just to call the function @code{executePayment}, 
feeding it
+with the three needed parameters.  The wallet will then get triggered and 
proceed with the
+payment.  See below a full example:
address@hidden
address@hidden
+// ../fulfillment-js.php
address@hidden ../fulfillment-js.php
address@hidden smallexample
address@hidden
+Note that, in order to use this fulfillment handler for the tutorial, you need 
to
+specify it in the contract's ``fulfillment_url'' field:
address@hidden
address@hidden
address@hidden
+... contract fields ..
address@hidden
+"fulfillment_url": "/fulfillment-js.php?transaction_id=<TRANSACTION_ID>& \
+                   timestamp=<CONTRACTTIMESTAMP>"
+...
address@hidden
address@hidden smallexample
address@hidden
+Additionally, you should also make sure that @code{taler-wallet-lib.js} 
location
+is valid.
diff --git a/python/doc/lgpl.texi b/common/texi/lgpl.texi
similarity index 100%
rename from python/doc/lgpl.texi
rename to common/texi/lgpl.texi
diff --git a/common/texi/normalized-base-url.texi 
b/common/texi/normalized-base-url.texi
new file mode 100644
index 0000000..b06d468
--- /dev/null
+++ b/common/texi/normalized-base-url.texi
@@ -0,0 +1,22 @@
address@hidden Section from ``advanced topics'' about how to normalize base URLs
+
address@hidden Normalized base URLs
address@hidden Normalized base URLs
+
+Exchanges and merchants have a base URL for their service.  This URL @b{must}
+be in a canonical form when it is stored (e.g. in the wallet's database) or
+transmitted (e.g. to a bank page).
+
address@hidden
address@hidden The URL must be absolute.  This implies that the URL has a 
schema.
address@hidden The path component of the URL must end with a slash.
address@hidden The URL must not contain a fragment or query.
address@hidden itemize
+
+When a user enters a URL that is, technically, relative (such as 
"alice.example.com/exchange"), wallets
+*may* transform it into a canonical base URL 
("http://alice.example.com/exchange/";).  Other components *should not* accept
+URLs that are not canonical.
+
+Rationale:  Joining non-canonical URLs with relative URLs (e.g. 
"exchange.example.com" with "reserve/status")
+results in different and slightly unexpected behavior in some URL handling 
libraries.
+Canonical URLs give more predictable results with standard URL joining.
diff --git a/common/texi/proposals.texi b/common/texi/proposals.texi
new file mode 100644
index 0000000..f234c49
--- /dev/null
+++ b/common/texi/proposals.texi
@@ -0,0 +1,186 @@
address@hidden Section describing the format of Taler contracts/proposals in 
detail
+
address@hidden The Taler proposal format
address@hidden The Taler proposal format
address@hidden contract
+
+A Taler proposal can specify many details about the transaction.
+This section describes each of the fields in depth.
+
address@hidden @var
address@hidden amount
address@hidden amount
+Specifies the total amount to be paid to the merchant by the customer.
+The amount is broken up into a @var{value}, a @var{fraction}
+(100.000.000 @var{fraction} units correspond to one @var{value}) and
+the @var{currency}.  For example, @code{EUR 1.50} would be represented
+as the tuple @code{value = 1, fraction = 50000000, currency = "EUR"}.
+
address@hidden max_fee
address@hidden fees
address@hidden maximum deposit fee
+This is the maximum total amount of deposit fees that the merchant is
+willing to pay.  If the deposit fees for the coins exceed this amount,
+the customer has to include it in the payment total.  The fee is
+specified using the same triplet used for @var{amount}.
+
+
address@hidden max_wire_fee
address@hidden fees
address@hidden maximum wire fee
+Maximum wire fee accepted by the merchant (customer share to be
+divided by the 'wire_fee_amortization' factor, and further reduced
+if deposit fees are below 'max_fee').  Default if missing is zero.
+
+
address@hidden wire_fee_amortization
address@hidden fees
address@hidden maximum fee amortization
+Over how many customer transactions does the merchant expect to
+amortize wire fees on average?  If the exchange's wire fee is
+above 'max_wire_fee', the difference is divided by this number
+to compute the expected customer's contribution to the wire fee.
+The customer's contribution may further be reduced by the difference
+between the 'max_fee' and the sum of the actual deposit fees.
+Optional, default value if missing is 1.  0 and negative values are
+invalid and also interpreted as 1.
+
address@hidden pay_url
address@hidden pay_url
+Which URL accepts payments. This is the URL where the wallet will POST
+coins.
+
address@hidden fulfillment_url
address@hidden fulfillment URL
+Which URL should the wallet go to for obtaining the fulfillment,
+for example the HTML or PDF of an article that was bought, or an
+order tracking system for shipments, or a simple human-readable
+Web page indicating the status of the contract.
+
address@hidden order_id
address@hidden order ID
+Alphanumeric identifier, freely definable by the merchant.
+Used by the merchant to uniquely identify the transaction.
+
address@hidden summary
address@hidden summary
+Short, human-readable summary of the contract. To be used when
+displaying the contract in just one line, for example in the
+transaction history of the customer.
+
address@hidden timestamp
+Time at which the offer was generated.
address@hidden FIXME: describe time format in detail here
+
address@hidden pay_deadline
address@hidden payment deadline
+Timestamp of the time by which the merchant wants the exchange
+to definitively wire the money due from this contract.  Once
+this deadline expires, the exchange will aggregate all
+deposits where the contracts are past the @var{refund_deadline}
+and execute one large wire payment for them.  Amounts will be
+rounded down to the wire transfer unit; if the total amount is
+still below the wire transfer unit, it will not be disbursed.
+
address@hidden refund_deadline
address@hidden refund deadline
+Timestamp until which the merchant willing (and able) to give refunds
+for the contract using Taler.  Note that the Taler exchange will hold
+the payment in escrow at least until this deadline.  Until this time,
+the merchant will be able to sign a message to trigger a refund to the
+customer.  After this time, it will no longer be possible to refund
+the customer.  Must be smaller than the @var{pay_deadline}.
+
address@hidden products
address@hidden product description
+Array of products that are being sold to the customer.  Each
+entry contains a tuple with the following values:
+
address@hidden @var
address@hidden description
+Description of the product.
address@hidden quantity
+Quantity of the items to be shipped. May specify a unit (@code{1 kg})
+or just the count.
address@hidden price
+Price for @var{quantity} units of this product shipped to the
+given @var{delivery_location}. Note that usually the sum of all
+of the prices should add up to the total amount of the contract,
+but it may be different due to discounts or because individual
+prices are unavailable.
address@hidden product_id
+Unique ID of the product in the merchant's catalog.  Can generally
+be chosen freely as it only has meaning for the merchant, but
+should be a number in the range @math{[0,2^{51})}.
address@hidden taxes
+Map of applicable taxes to be paid by the merchant.  The label is the
+name of the tax, i.e. @var{VAT}, @var{sales tax} or @var{income tax},
+and the value is the applicable tax amount.  Note that arbitrary
+labels are permitted, as long as they are used to identify the
+applicable tax regime.  Details may be specified by the regulator.
+This is used to declare to the customer which taxes the merchant
+intends to pay, and can be used by the customer as a receipt.
address@hidden FIXME: a receipt not including the item's price?
+The information is also likely to be used by tax audits of the merchant.
address@hidden delivery_date
+Time by which the product is to be delivered to the
address@hidden
address@hidden delivery_location
+This should give a label in the @var{locations} map, specifying
+where the item is to be delivered.
address@hidden table
+Values can be omitted if they are not applicable. For example, if a
+purchase is about a bundle of products that have no individual prices
+or product IDs, the @var{product_id} or @var{price} may not be
+specified in the contract.  Similarly, for virtual products delivered
+directly via the fulfillment URI, there is no delivery location.
+
address@hidden merchant
address@hidden @var
address@hidden address
+This should give a label in the @var{locations} map, specifying
+where the merchant is located.
address@hidden name
+This should give a human-readable name for the merchant's business.
address@hidden jurisdiction
+This should give a label in the @var{locations} map, specifying
+the jurisdiction under which this contract is to be arbitrated.
address@hidden table
+
address@hidden locations
address@hidden location
+Associative map of locations used in the contract. Labels for
+locations in this map can be freely chosen and used whenever
+a location is required in other parts of the contract.  This way,
+if the same location is required many times (such as the business
+address of the customer or the merchant), it only needs to be
+listed (and transmitted) once, and can otherwise be referred to
+via the label.  A non-exhaustive list of location attributes
+is the following:
address@hidden @var
address@hidden country
+Name of the country for delivery, as found on a postal package, i.e. 
``France''.
address@hidden state
+Name of the state for delivery, as found on a postal package, i.e. ``NY''.
address@hidden region
+Name of the region for delivery, as found on a postal package.
address@hidden province
+Name of the province for delivery, as found on a postal package.
address@hidden city
+Name of the city for delivery, as found on a postal package.
address@hidden ZIP code
+ZIP code for delivery, as found on a postal package.
address@hidden street
+Street name for delivery, as found on a postal package.
address@hidden street number
+Street number (number of the house) for delivery, as found on a postal package.
address@hidden name receiver name for delivery, either business or person name.
+
address@hidden table
+
+Note that locations are not required to specify all of these fields,
+and it is also allowed to have additional fields.  Contract renderers
+must render at least the fields listed above, and should render fields
+that they do not understand as a key-value list.
+
address@hidden table
diff --git a/python/doc/syntax.texi b/common/texi/syntax.texi
similarity index 100%
rename from python/doc/syntax.texi
rename to common/texi/syntax.texi
diff --git a/common/texi/version.texi b/common/texi/version.texi
new file mode 100644
index 0000000..f5c01d6
--- /dev/null
+++ b/common/texi/version.texi
@@ -0,0 +1,4 @@
address@hidden UPDATED 15 October November 2017
address@hidden UPDATED-MONTH October 2017
address@hidden EDITION 0.4.0
address@hidden VERSION 0.4.0
diff --git a/common/texi/wallet-detection.texi 
b/common/texi/wallet-detection.texi
new file mode 100644
index 0000000..a4b9a34
--- /dev/null
+++ b/common/texi/wallet-detection.texi
@@ -0,0 +1,62 @@
address@hidden Section on how to detect the Taler wallet
+
address@hidden Detecting the presence of the Taler wallet
address@hidden Detecting the presence of the Taler wallet
address@hidden wallet
+
+Taler offers the way to the frontend developer to detect whether
+a user has the wallet installed in their browser, and take actions
+accordingly.
+
address@hidden The no-JavaScript way
+The follwing example shows all that is needed to perform the detection
+without using JavaScript:
+
address@hidden
+<!DOCTYPE html>
+<html lang="en" data-taler-nojs="true">
+  <head>
+    <title>Tutorial</title>
+    <link rel="stylesheet"
+          type="text/css"
+          href="/web-common/taler-fallback.css"
+          id="taler-presence-stylesheet" />
+  </head>
+  <body>
+    <p class="taler-installed-hide">
+      No wallet found.
+    </p>
+    <p class="taler-installed-show">
+      Wallet found!
+    </p>
+  </body>
+</html>
address@hidden smallexample
+
+The @code{taler-fallback.css} is part of the Taler's @emph{web-common} 
repository,
+available at @code{https://git.taler.net/web-common.git}.  Please adjust the 
@code{href}
+attribute in order to make it work with your Web site.
+
+The detection works by @code{taler-fallback.css} hiding any tag from the
address@hidden class, in case no wallet is installed.  If otherwise
+the wallet is installed, the wallet takes action by hiding any tag from the
address@hidden class and overriding @code{taler-fallback.css} logic
+by showing any tag from the @code{taler-installed-show} class.
+
address@hidden The JavaScript way
+
address@hidden helps the frontend, by providing the way to register two
+callbacks: one to be executed if a wallet is present, the other if it is not.
+See the example below:
+
address@hidden
+// js-wallet.html
address@hidden ../../common/html/js-wallet.html
address@hidden smallexample
+
address@hidden exports the @code{taler} object that
+exposes the @code{onPresent} and the @code{onAbsent} functions needed
+to register the frontend's callbacks.  Thus the function @code{walletInstalled}
+will be executed whenever a wallet is installed, and @code{walletNotInstalled}
+if not.  Note that since now we can use JavaScript we can register
+callbacks that do more than just showing and hiding elements.
diff --git a/php/doc/inline-proposals.texi b/php/doc/inline-proposals.texi
new file mode 100644
index 0000000..3613e9a
--- /dev/null
+++ b/php/doc/inline-proposals.texi
@@ -0,0 +1,22 @@
address@hidden Inlining proposals in HTTP headers
address@hidden Inlining proposals in HTTP headers
address@hidden optimization
address@hidden contract
+
+In the example in @ref{Prompting for payment}, we told the wallet the URL
+from where it should fetch the proposal.  Instead of specifying the proposal
+via an URL, it is also possible to inline short proposals directly.
+
+That may be accomplished by the frontend including the @code{X-Taler-Proposal}
+HTTP header, whenever the requested page is meant to trigger a payment.
+The example shown below may be an alternative version of @code{/donate.php},
+which implements inline contracts.
+
address@hidden
+// ../inline.php
address@hidden ../inline.php
address@hidden smallexample
+
+The wallet will then look for the @code{X-Taler-Proposal} header, and fetch the
+inlined contract if this header is found.  Please note that this feature is not
+yet implemented in the wallet.
diff --git a/php/doc/tutorial.texi b/php/doc/tutorial.texi
index 7b8d31b..686b6d3 100644
--- a/php/doc/tutorial.texi
+++ b/php/doc/tutorial.texi
@@ -1,7 +1,8 @@
 \input texinfo @c -*-texinfo-*-
 @c %**start of header
 @setfilename tutorial.info
address@hidden version.texi
address@hidden ../../common/version.texi
address@hidden ../../common/texi/syntax.texi
 @settitle The GNU Taler tutorial for PHP Web shop developers @value{VERSION}
 
 @c Define a new index for options.
@@ -15,7 +16,7 @@
 This tutorial is about implementing a merchant frontend to run against a
 GNU Taler merchant backend (version @value{VERSION}, @value{UPDATED}),
 
-Copyright @copyright{} 2016 INRIA
+Copyright @copyright{} 2016, 2017 Taler Systems SA
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
@@ -37,7 +38,8 @@ Texts.  A copy of the license is included in the section 
entitled
 @subtitle Version @value{VERSION}
 @subtitle @value{UPDATED}
 @author Marcello Stanisci (@email{marcello.stanisci@@inria.fr})
address@hidden Christian Grothoff (@email{christian.grothoff@@inria.fr})
address@hidden Christian Grothoff (@email{christian.grothoff@@inria.fr}
address@hidden Florian Dold (@email{florian.dold@@inria.fr})
 @page
 @vskip 0pt plus 1filll
 @insertcopying
@@ -432,7 +434,7 @@ transfer.  The Taler exchange may aggregate multiple 
payments from
 transactions into one larger wire transfer.  The @var{refund_deadline}
 and the @var{pay_deadline} values in the contract specify the
 timeframes within which the exchange is permitted to perform such
-aggregations, see @ref{Taler contracts}.
+aggregations, see @ref{The Taler proposal format}.
 
 In this chapter, we will see how a merchant can obtain the
 mapping from transactions to wire transfers and vice versa.
@@ -562,529 +564,24 @@ See below both parts:
 @chapter Advanced topics
 
 @menu
-* Presence detection::          Reacting to the presence of a Taler wallet
-* Taler contracts::             Building Taler contracts
-* Inline proposals::            Snding proposals with the HTTP header
-* The Fulfillment page::        The rationale behind the fulfillment page 
design
-* Normalized base URLs::             Format URLs are expected to be in Taler
+* Detecting the presence of the Taler wallet::  Detecting the presence of the 
Taler wallet
+* The Taler proposal format::                   The Taler proposal format
+* Inlining proposals in HTTP headers::          Inlining proposals in HTTP 
headers
+* Instances::                                   Instances
+* The fulfillment page::                        The fulfillment page
+* Normalized base URLs::                        Normalized base URLs
 @end menu
 
address@hidden FIXME.  Add section about including images (or extra files in 
general)
address@hidden         along with payed content.
address@hidden ../../common/texi/wallet-detection.texi
address@hidden ../../common/texi/proposals.texi
address@hidden inline-proposals.texi
address@hidden ../../common/texi/instances.texi
address@hidden ../../common/texi/fulfillment-page.texi
address@hidden ../../common/texi/normalized-base-url.texi
 
 
address@hidden Presence detection
address@hidden Reacting to the presence of a Taler wallet
address@hidden wallet
-
-Taler offers the way to the frontend developer to detect whether
-a user has the wallet installed in their browser, and take actions
-accordingly.
-
address@hidden The no-JavaScript way
-The follwing example shows all that is needed to perform the detection
-without using JavaScript:
-
address@hidden
-<!DOCTYPE html>
-<html lang="en" data-taler-nojs="true">
-  <head>
-    <title>Tutorial</title>
-    <link rel="stylesheet"
-          type="text/css"
-          href="/web-common/taler-fallback.css"
-          id="taler-presence-stylesheet" />
-  </head>
-  <body>
-    <p class="taler-installed-hide">
-      No wallet found.
-    </p>
-    <p class="taler-installed-show">
-      Wallet found!
-    </p>
-  </body>
-</html>
address@hidden smallexample
-
-The @code{taler-fallback.css} is part of the Taler's @emph{web-common} 
repository,
-available at @code{https://git.taler.net/web-common.git}.  Please adjust the 
@code{href}
-attribute in order to make it work with your Web site.
-
-The detection works by @code{taler-fallback.css} hiding any tag from the
address@hidden class, in case no wallet is installed.  If otherwise
-the wallet is installed, the wallet takes action by hiding any tag from the
address@hidden class and overriding @code{taler-fallback.css} logic
-by showing any tag from the @code{taler-installed-show} class.
-
address@hidden The JavaScript way
-
address@hidden helps the frontend, by providing the way to register two
-callbacks: one to be executed if a wallet is present, the other if it is not.
-See the example below:
-
address@hidden
-<html lang="en">
-  <head>
-    <script src="/web-common/taler-wallet-lib.js" 
type="application/javascript">
-    </script>
-  </head>
-  <body>
-    <div id="content">
-    </div>
-    <script type="application/javascript">
-
-      content = document.getElementById("content");
-      p = document.createElement("p");
-
-      function walletInstalled(){
-        p.textContent = "Wallet installed!";
-        content.appendChild(p);
-      }
-      function walletNotInstalled(){
-        p.textContent = "Wallet not found.";
-        content.appendChild(p);
-      }
-      taler.onPresent(wallerInstalled);
-      taler.onAbsent(wallerNotInstalled);
-    </script>
-  </body>
-</html>
address@hidden smallexample
-
address@hidden exports the @code{taler} object that
-exposes the @code{onPresent} and the @code{onAbsent} functions needed
-to register the frontend's callbacks.  Thus the function @code{walletInstalled}
-will be executed whenever a wallet is installed, and @code{walletNotInstalled}
-if not.  Note that since now we can use JavaScript we can register
-callbacks that do more than just showing and hiding elements.
-
-
address@hidden Taler proposals
address@hidden Building Taler proposals
address@hidden contract
-
-A Taler proposal can specify many details about the transaction.
-This section describes each of the fields in depth.
-
address@hidden @var
address@hidden amount
address@hidden amount
-Specifies the total amount to be paid to the merchant by the customer.
-The amount is broken up into a @var{value}, a @var{fraction}
-(100.000.000 @var{fraction} units correspond to one @var{value}) and
-the @var{currency}.  For example, @code{EUR 1.50} would be represented
-as the tuple @code{value = 1, fraction = 50000000, currency = "EUR"}.
-
address@hidden max_fee
address@hidden fees
address@hidden maximum deposit fee
-This is the maximum total amount of deposit fees that the merchant is
-willing to pay.  If the deposit fees for the coins exceed this amount,
-the customer has to include it in the payment total.  The fee is
-specified using the same triplet used for @var{amount}.
-
-
address@hidden max_wire_fee
address@hidden fees
address@hidden maximum wire fee
-Maximum wire fee accepted by the merchant (customer share to be
-divided by the 'wire_fee_amortization' factor, and further reduced
-if deposit fees are below 'max_fee').  Default if missing is zero.
-
-
address@hidden wire_fee_amortization
address@hidden fees
address@hidden maximum fee amortization
-Over how many customer transactions does the merchant expect to
-amortize wire fees on average?  If the exchange's wire fee is
-above 'max_wire_fee', the difference is divided by this number
-to compute the expected customer's contribution to the wire fee.
-The customer's contribution may further be reduced by the difference
-between the 'max_fee' and the sum of the actual deposit fees.
-Optional, default value if missing is 1.  0 and negative values are
-invalid and also interpreted as 1.
-
address@hidden pay_url
address@hidden pay_url
-Which URL accepts payments. This is the URL where the wallet will POST
-coins.
-
address@hidden fulfillment_url
address@hidden fulfillment URL
-Which URL should the wallet go to for obtaining the fulfillment,
-for example the HTML or PDF of an article that was bought, or an
-order tracking system for shipments, or a simple human-readable
-Web page indicating the status of the contract.
-
address@hidden order_id
address@hidden order ID
-Alphanumeric identifier, freely definable by the merchant.
-Used by the merchant to uniquely identify the transaction.
-
address@hidden summary
address@hidden summary
-Short, human-readable summary of the contract. To be used when
-displaying the contract in just one line, for example in the
-transaction history of the customer.
-
address@hidden timestamp
-Time at which the offer was generated.
address@hidden FIXME: describe time format in detail here
-
address@hidden pay_deadline
address@hidden payment deadline
-Timestamp of the time by which the merchant wants the exchange
-to definitively wire the money due from this contract.  Once
-this deadline expires, the exchange will aggregate all
-deposits where the contracts are past the @var{refund_deadline}
-and execute one large wire payment for them.  Amounts will be
-rounded down to the wire transfer unit; if the total amount is
-still below the wire transfer unit, it will not be disbursed.
-
address@hidden refund_deadline
address@hidden refund deadline
-Timestamp until which the merchant willing (and able) to give refunds
-for the contract using Taler.  Note that the Taler exchange will hold
-the payment in escrow at least until this deadline.  Until this time,
-the merchant will be able to sign a message to trigger a refund to the
-customer.  After this time, it will no longer be possible to refund
-the customer.  Must be smaller than the @var{pay_deadline}.
-
address@hidden products
address@hidden product description
-Array of products that are being sold to the customer.  Each
-entry contains a tuple with the following values:
-
address@hidden @var
address@hidden description
-Description of the product.
address@hidden quantity
-Quantity of the items to be shipped. May specify a unit (@code{1 kg})
-or just the count.
address@hidden price
-Price for @var{quantity} units of this product shipped to the
-given @var{delivery_location}. Note that usually the sum of all
-of the prices should add up to the total amount of the contract,
-but it may be different due to discounts or because individual
-prices are unavailable.
address@hidden product_id
-Unique ID of the product in the merchant's catalog.  Can generally
-be chosen freely as it only has meaning for the merchant, but
-should be a number in the range @math{[0,2^{51})}.
address@hidden taxes
-Map of applicable taxes to be paid by the merchant.  The label is the
-name of the tax, i.e. @var{VAT}, @var{sales tax} or @var{income tax},
-and the value is the applicable tax amount.  Note that arbitrary
-labels are permitted, as long as they are used to identify the
-applicable tax regime.  Details may be specified by the regulator.
-This is used to declare to the customer which taxes the merchant
-intends to pay, and can be used by the customer as a receipt.
address@hidden FIXME: a receipt not including the item's price?
-The information is also likely to be used by tax audits of the merchant.
address@hidden delivery_date
-Time by which the product is to be delivered to the
address@hidden
address@hidden delivery_location
-This should give a label in the @var{locations} map, specifying
-where the item is to be delivered.
address@hidden table
-Values can be omitted if they are not applicable. For example, if a
-purchase is about a bundle of products that have no individual prices
-or product IDs, the @var{product_id} or @var{price} may not be
-specified in the contract.  Similarly, for virtual products delivered
-directly via the fulfillment URI, there is no delivery location.
-
address@hidden merchant
address@hidden @var
address@hidden address
-This should give a label in the @var{locations} map, specifying
-where the merchant is located.
address@hidden name
-This should give a human-readable name for the merchant's business.
address@hidden jurisdiction
-This should give a label in the @var{locations} map, specifying
-the jurisdiction under which this contract is to be arbitrated.
address@hidden table
-
address@hidden locations
address@hidden location
-Associative map of locations used in the contract. Labels for
-locations in this map can be freely chosen and used whenever
-a location is required in other parts of the contract.  This way,
-if the same location is required many times (such as the business
-address of the customer or the merchant), it only needs to be
-listed (and transmitted) once, and can otherwise be referred to
-via the label.  A non-exhaustive list of location attributes
-is the following:
address@hidden @var
address@hidden country
-Name of the country for delivery, as found on a postal package, i.e. 
``France''.
address@hidden state
-Name of the state for delivery, as found on a postal package, i.e. ``NY''.
address@hidden region
-Name of the region for delivery, as found on a postal package.
address@hidden province
-Name of the province for delivery, as found on a postal package.
address@hidden city
-Name of the city for delivery, as found on a postal package.
address@hidden ZIP code
-ZIP code for delivery, as found on a postal package.
address@hidden street
-Street name for delivery, as found on a postal package.
address@hidden street number
-Street number (number of the house) for delivery, as found on a postal package.
address@hidden name receiver name for delivery, either business or person name.
-
address@hidden table
-
-Note that locations are not required to specify all of these fields,
-and it is also allowed to have additional fields.  Contract renderers
-must render at least the fields listed above, and should render fields
-that they do not understand as a key-value list.
-
address@hidden table
-
address@hidden Inline proposals
address@hidden Inlining proposals in HTTP headers
address@hidden optimization
address@hidden contract
-
-In the example in @ref{Prompting for payment}, we told the wallet the URL
-from where it should fetch the proposal.  Instead of specifying the proposal
-via an URL, it is also possible to inline short proposals directly.
-
-That may be accomplished by the frontend including the @code{X-Taler-Proposal}
-HTTP header, whenever the requested page is meant to trigger a payment.
-The example shown below may be an alternative version of @code{/donate.php},
-which implements inline contracts.
-
address@hidden
-// ../inline.php
address@hidden ../inline.php
address@hidden smallexample
-
-The wallet will then look for the @code{X-Taler-Proposal} header, and fetch the
-inlined contract if this header is found.  Please note that this feature is not
-yet implemented in the wallet.
-
address@hidden @node Payments using JavaScript
address@hidden @section Triggering payments using JavaScript
address@hidden 
address@hidden Please note that the following examples are purely instructional 
and NOT TESTED
address@hidden along with the tutorial code.
address@hidden 
address@hidden @cindex JavaScript
address@hidden 
address@hidden @subsection Offering contracts
address@hidden 
address@hidden Offering contracts the JavaScript way doesn't require us to set 
HTTP
address@hidden headers, and so -- in a minimalistic implementation -- the 
donation button
address@hidden should just hit a HTML page that invokes the 
@code{offerContractFrom} function,
address@hidden from the @code{taler-wallet-lib.js} library.
address@hidden 
address@hidden Thus our homepage can now look as follows
address@hidden 
address@hidden @smallexample
address@hidden // ../index-js.html
address@hidden @verbatiminclude ../index-js.html
address@hidden @end smallexample
address@hidden 
address@hidden @code{donate-js.html} is now in charge of calling 
@code{offerContractFrom} 
address@hidden passing the contract URL to it, which is 
@code{"/generate-order.php"} in
address@hidden our example.  See below.
address@hidden 
address@hidden @smallexample
address@hidden // ../donate-js.html
address@hidden @verbatiminclude ../donate-js.html
address@hidden @end smallexample
address@hidden 
address@hidden Please make sure that @code{taler-wallet-lib.js} location is 
valid.
address@hidden 
address@hidden @subsection Receiving payments
address@hidden @cindex payment
address@hidden 
address@hidden In the example in section @ref{Initiating the payment process}, 
the fulfillment
address@hidden handler @code{/fulfillment.php} triggers the payment in the 
wallet by returing
address@hidden the three needed values (contract hashcode, pay URL, offer URL) 
via HTTP headers.
address@hidden 
address@hidden The same action can be accomplished @emph{with} JavaScript, 
thanks to
address@hidden @code{taler-wallet-lib.js} of @emph{web-common} repository.
address@hidden The fulfillment handler needs just to call the function 
@code{executePayment}, feeding it
address@hidden with the three needed parameters.  The wallet will then get 
triggered and proceed with the
address@hidden payment.  See below a full example:
address@hidden 
address@hidden @smallexample
address@hidden // ../fulfillment-js.php
address@hidden @verbatiminclude ../fulfillment-js.php
address@hidden @end smallexample
address@hidden 
address@hidden Note that, in order to use this fulfillment handler for the 
tutorial, you need to
address@hidden specify it in the contract's ``fulfillment_url'' field:
address@hidden 
address@hidden @smallexample
address@hidden @{
address@hidden ... contract fields ..
address@hidden 
address@hidden "fulfillment_url": 
"/fulfillment-js.php?transaction_id=<TRANSACTION_ID>& \
address@hidden                    timestamp=<CONTRACTTIMESTAMP>"
address@hidden ...
address@hidden @}
address@hidden @end smallexample
address@hidden 
address@hidden Additionally, you should also make sure that 
@code{taler-wallet-lib.js} location
address@hidden is valid.
-
address@hidden The fulfillment page
address@hidden Design considerations for the fulfillment page
address@hidden fulfillment page
-
-The fulfillment page mechanism is designed to provide the following two 
properties:
-
address@hidden
address@hidden Taler payments @emph{can} be implemented in DB-less frontends.
-
address@hidden Taler payments are replayable, meaning that each purchase is 
associated with
-a URL (the fulfillment URL) that shows the product each time it gets visited 
(and
-of course, only the first time takes the user's money).
address@hidden enumerate
-
-Both properties are gotten "for free" by the way replayable payments are
-implemented. Since @code{pay.php} simply relays payments to the backend,
-if the latter returns "200 OK", then the frontend delivers what is mentioned
-in the backend's response.  Note that along with the "200 OK" response,
-the backend returns the whole proposal associated with the fulfillment
-URL that triggered the payment, so the frontend has all the information
-useful to pick the right product to deliver.
-The "payment" relayed to the backend contains the @emph{order id},
-that allows the backend to perform all the integrity checks on the
-payment.
-This way, the frontend doesn't need any database to replay payments.
-
address@hidden Instances
address@hidden Instances
address@hidden instances
-
-Taler's design allows a single backend to manage multiple frontends.
-In other words, we might have multiple shops relying on the same backend.
-As of terminology, we call @emph{instance} any of the frontends accounted
-by the same backend.
-
-The backend's RESTful API allows frontends to specify which instance they are.
-However, this specification is optional, and a ``default'' instance will be
-used whenever the frontend does not specify one.
-
-Please note that in this stage of development, the backend's REST call 
@code{/history}
-returns records for @emph{any} instance.  The rationale behind is to allow 
grouping
-``public'' business entities under the same backend.
-
-This way, a single frontend can expose multiple donation buttons for multiple
-receivers, and still operate against one backend. So in this scenario, there 
is no
-harm if the operator of instance `a' sees history entries related to instance 
`b'.
-
-See @code{https://donations.demo.taler.net/}, which uses this functionality.
-
address@hidden Normalized base URLs
address@hidden Normalized base URLs
-
-Exchanges and merchants have a base URL for their service.  This URL @b{must}
-be in a canonical form when it is stored (e.g. in the wallet's database) or
-transmitted (e.g. to a bank page).
-
address@hidden
address@hidden The URL must be absolute.  This implies that the URL has a 
schema.
address@hidden The path component of the URL must end with a slash.
address@hidden The URL must not contain a fragment or query.
address@hidden itemize
-
-When a user enters a URL that is, technically, relative (such as 
"alice.example.com/exchange"), wallets
-*may* transform it into a canonical base URL 
("http://alice.example.com/exchange/";).  Other components *should not* accept
-URLs that are not canonical.
-
-Rationale:  Joining non-canonical URLs with relative URLs (e.g. 
"exchange.example.com" with "reserve/status") 
-results in different and slightly unexpected behavior in some URL handling 
libraries.
-Canonical URLs give more predictable results with standard URL joining.
-
-
address@hidden The following section is copied from the Python manual,
address@hidden changes should be done there and then copied back here.
address@hidden Reference
address@hidden Reference
-
address@hidden
-* Headers for HTTP 402::                 Headers for the 402 status code and 
their effect on the user agent's operation
-* JavaScript API::                       JavaScript API to communicate with 
the wallet
-* Stylesheet-based presence detection::  Presence detection using CSS style 
sheets and no JavaScript
address@hidden menu
-
address@hidden Headers for HTTP 402
address@hidden Headers for HTTP 402
-The HTTP status code @code{402 Payment Required} can be used by the merchant
-frontend to trigger operations related to payments in the user agent.  The user
-agent associates at most one proposal with every URL via the proposal's
address@hidden field.  The associated proposal is either missing (in
-case it doesn't exist), paid (in case the payment for it was successfully sent
-to the merchant) or unpaid.  If the associated proposal is unpaid,  @code{402
-Payment Required} will cause the user agent to pay for the associated proposal.
-
-The following headers for @code{402 Payment Required} are recognized by Taler 
and further influence the processing:
address@hidden @code
address@hidden X-Taler-Refund-Url
-If this header present, the value of this header must be a URL that the user 
agent can use to request and process refunds.
-
address@hidden X-Taler-Contract-Url
-If there is no associated proposal, the user agent will fetch a proposal from
-this URL and process it.  This typically prompts the user to agree to pay.
-
address@hidden X-Taler-Offer-Url
-If there is no associated proposal and @code{X-Taler-Contract-Url} is not
-specified, the browser will navigate to this URL.
-
address@hidden table
-
address@hidden JavaScript API
address@hidden JavaScript API
-
-The following functions are defined in the @code{taler} namespace of the 
@code{taler-wallet-lib} helper library
-available at 
@url{https://git.taler.net/web-common.git/tree/taler-wallet-lib.js}.
-
address@hidden @code
address@hidden onPresent(callback: () => void)
-Add a callback to be called when support for Taler payments is detected.
-
address@hidden onAbsent(callback: () => void)
-Add a callback to be called when support for Taler payments is disabled.
-
address@hidden pay(@{contract_url: string, offer_url: address@hidden)
-Results in the same action as a @code{402 Payment Required} with 
@code{contract_url} in
-the @code{X-Taler-Contract-Url} header and @code{offer_url} in the 
@code{X-Taler-Payment-Url} header.
-
address@hidden refund(refund_url: string)
-Results in the same action as a @code{402 Payment Required} with 
@code{refund_url} in
-the @code{X-Taler-Refund-Url} header.
-
address@hidden table
-
address@hidden Stylesheet-based presence detection
address@hidden Stylesheet-based presence detection
-
-Stylesheet-based presence detection will be applied on all pages that have the
address@hidden attribute of the @code{html} element set @code{true}.
-The default/fallback stylesheet, that will be taken over by the wallet once
-installed, must be included with the id @code{taler-presence-stylesheet}, like
-this:
-
-The following CSS classes can be used:
address@hidden @code
address@hidden taler-installed-hide
-A CSS rule will set the @code{display} property for this class to @code{none} 
once the Taler wallet is installed and enabled.
-If the wallet is not installed, @code{display} will be @code{inherit}.
-
address@hidden taler-installed-show
-A CSS rule will set the @code{display} property for this class to 
@code{inherit} once the Taler wallet is installed and enabled.
-If the wallet is not installed, @code{display} will be @code{none}.
-
address@hidden table
-
address@hidden ************ Reference chapter ***********
address@hidden ../../common/texi/api-reference.texi
 
 @c **********************************************************
 @c *******************  Appendices  *************************
@@ -1094,13 +591,13 @@ If the wallet is not installed, @code{display} will be 
@code{none}.
 @unnumbered GNU-LGPL
 @cindex license
 @cindex LGPL
address@hidden lgpl.texi
address@hidden ../../common/texi/lgpl.texi
 
 @node GNU-FDL
 @unnumbered GNU-FDL
 @cindex license
 @cindex GNU Free Documentation License
address@hidden fdl-1.3.texi
address@hidden ../../common/texi/fdl-1.3.texi
 
 @node Concept Index
 @unnumbered Concept Index
diff --git a/php/doc/version.texi b/php/doc/version.texi
deleted file mode 100644
index 530e1dc..0000000
--- a/php/doc/version.texi
+++ /dev/null
@@ -1,4 +0,0 @@
address@hidden UPDATED 11 November 2016
address@hidden UPDATED-MONTH November 2016
address@hidden EDITION 0.2.0
address@hidden VERSION 0.2.0
diff --git a/python/doc/tutorial.texi b/python/doc/tutorial.texi
index 3d11468..f849201 100644
--- a/python/doc/tutorial.texi
+++ b/python/doc/tutorial.texi
@@ -1,8 +1,8 @@
 \input texinfo @c -*-texinfo-*-
 @c %**start of header
 @setfilename tutorial.info
address@hidden version.texi
address@hidden syntax.texi
address@hidden ../../version.texi
address@hidden ../../common/texi/syntax.texi
 @settitle The GNU Taler tutorial for Python Web shop developers @value{VERSION}
 
 @c Define a new index for options.
@@ -16,7 +16,7 @@
 This tutorial is about implementing a merchant frontend to run against a
 GNU Taler merchant backend (version @value{VERSION}, @value{UPDATED}),
 
-Copyright @copyright{} 2016, 2017 INRIA
+Copyright @copyright{} 2016, 2017 Taler Systems SA
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
@@ -57,6 +57,7 @@ Texts.  A copy of the license is included in the section 
entitled
 @menu
 * Introduction::                                  What this tutorial is about
 * Setting up a simple donation page::             How to set up a donation page
+* Back-office-integration::                       How to integrate with the 
back office
 * Advanced topics::                               Detailed solutions to 
specific issues
 * Reference::                                     Merchant integration 
reference
 
@@ -252,7 +253,7 @@ If the wallet is not present, the error message ``No wallet
 installed!'' will be shown and the Taler ``X-Taler-Contract-Url''
 header and the 402 status code ought to be ignored by the browser.
 
address@hidden A helper function to generate the order 
address@hidden A helper function to generate the order
 
 We make distinction between @emph{three} different stages of what it
 informally called "contract".
@@ -369,7 +370,7 @@ def fulfillment():
     # make the payment, assuming the user already accepted the
     # proposal.
     response = flask.Response(status=402)
-    
+
     # At this URL, the wallet may request a regeneration of the proposal.
     response.headers["X-Taler-Contract-Url"] = make_url("/generate-proposal")
     # This URL will be visited in case the user has opened
@@ -471,122 +472,177 @@ should be able to point your browser at 
@code{http://localhost:5000/}
 and make a donation.
 
 
address@hidden Advanced topics
address@hidden Advanced topics
 
address@hidden
-* Normalized base URLs::             Format URLs are expected to be in Taler
address@hidden menu
 
address@hidden Normalized base URLs
address@hidden Normalized base URLs
 
-Exchanges and merchants have a base URL for their service.  This URL @b{must}
-be in a canonical form when it is stored (e.g. in the wallet's database) or
-transmitted (e.g. to a bank page).
address@hidden Back-office-integration
address@hidden Integration with the back office
+
+This chapter shows how to implement the back office Web interface.
+
+We will use the term @emph{transaction} to refer to the business
+transaction that a merchant has with a customer (and the related
+communication with the Taler exchange for payment), and the term
address@hidden transfer} to refer to the exchange settling its accounts
+with the merchant.
+
+However, from the frontend's perspective, any transaction is denoted
+by the @emph{order id} contained in the proposal that led to the
+transaction.
+
+Given that Taler deals with microtransactions, not every customer
+payment processed with Taler will necessarily correspond to a wire
+transfer.  The Taler exchange may aggregate multiple payments from
+transactions into one larger wire transfer.  The @var{refund_deadline}
+and the @var{pay_deadline} values in the contract specify the
+timeframes within which the exchange is permitted to perform such
+aggregations, see @ref{The Taler proposal format}.
+
+In this chapter, we will see how a merchant can obtain the
+mapping from transactions to wire transfers and vice versa.
+Additionally, we will describe how to obtain a list of all
+transactions known to the backend.
+
address@hidden Entry page
+
+Given this charge, the back office's main tasks are:
 
 @itemize
address@hidden The URL must be absolute.  This implies that the URL has a 
schema.
address@hidden The path component of the URL must end with a slash.
address@hidden The URL must not contain a fragment or query.
address@hidden
+Allow the back office operator to specify a order id, and display the
+corresponding wire transfer identifiers.
address@hidden
+Allow the back office operator to specify a wire transfer ID, and
+display all of the corresponding order ids.
address@hidden
+Allow the back office operator to obtain a list of all transactions.
 @end itemize
 
-When a user enters a URL that is, technically, relative (such as 
"alice.example.com/exchange"), wallets
-*may* transform it into a canonical base URL 
("http://alice.example.com/exchange/";).  Other components *should not* accept
-URLs that are not canonical.
+We implement these with a simple HTML form. For simplicity, we have
+one single page for gathering input data for both tracking directions:
 
-Rationale:  Joining non-canonical URLs with relative URLs (e.g. 
"exchange.example.com" with "reserve/status") 
-results in different and slightly unexpected behavior in some URL handling 
libraries.
-Canonical URLs give more predictable results with standard URL joining.
address@hidden
+TBD.
address@hidden smallexample
 
address@hidden Reference
address@hidden Reference
+The imported script @code{history.js} is responsible for dynamically
+get the list of known transactions.  See below.
 
address@hidden
-* Headers for HTTP 402::                 Headers for the 402 status code and 
their effect on the user agent's operation
-* JavaScript API::                       JavaScript API to communicate with 
the wallet
-* Stylesheet-based presence detection::  Presence detection using CSS style 
sheets and no JavaScript
address@hidden menu
address@hidden Tracking a transaction
 
address@hidden Headers for HTTP 402
address@hidden Headers for HTTP 402
-The HTTP status code @code{402 Payment Required} can be used by the merchant
-frontend to trigger operations related to payments in the user agent.  The user
-agent associates at most one proposal with every URL via the proposal's
address@hidden field.  The associated proposal is either missing (in
-case it doesn't exist), paid (in case the payment for it was successfully sent
-to the merchant) or unpaid.  If the associated proposal is unpaid,  @code{402
-Payment Required} will cause the user agent to pay for the associated proposal.
+The TBD is now responsible for taking
+all the URL query parameter and use them on the @code{/track/transaction}
+request to the backend, see 
@url{http://api.taler.net/api-merchant.html#get--track-transaction}.
+The parameters are the @emph{order_id} and the @emph{instance} (see 
@ref{Instances})
+of this merchant.
+Note that the backend may then request this information from the
+exchange, or retrieve it from its own cache if it has already obtained
+it.  The backend will also check signatures from the exchange, persist
+the information obtained, and complain if the exchange ever changes
+its facts in an inconsistent manner.
 
-The following headers for @code{402 Payment Required} are recognized by Taler 
and further influence the processing:
address@hidden @code
address@hidden X-Taler-Refund-Url
-If this header present, the value of this header must be a URL that the user 
agent can use to request and process refunds.
address@hidden
+TBD.
address@hidden smallexample
+
+If the backend returned an HTTP status code @code{202} (Accepted),
+this means that the exchange simply did not yet perform the wire
+transfer. This is usually the case before @var{pay_deadline}, as the
+exchange is waiting for additional opportunities to aggregate transactions.
+In this case, we tell the user when to retry this operation later.
+
+In the @code{foreach} loop, we construct the list of all the
+wire transfers which paid back transaction @emph{order_id}.  For
+simplicity, the list will report only two values: the wire transfer
+identifier and the date when the transfer occurred. Nonetheless,
+the data returned by the backend contains more information that
+can be shown to the user.
+
address@hidden Tracking a wire transfer
+
+To track a wire transfer, the frontend just needs to forward the request
+it got from the Web form, to the backend.
+Again, the backend may request missing information from the exchange,
+verify signatures, persist the result and complain if there are
+inconsistencies.
+
+In the case that the backend detects inconsistencies, an HTTP status
+code of @code{402} is returned.  In this case, we report this
+situation to the user, who should now report this situation to the
+exchange's auditors as the exchange is misbehaving.
+
+In the usual case where everything went fine, we first output the
+amount that was supposed to have been transfered under the given
address@hidden, and when it was performed (according to the exchange).
+Finally, in the @code{foreach} loop, we construct the list of the
+order ids paid by the wire transfer:
+
address@hidden
+TBD.
address@hidden smallexample
 
address@hidden X-Taler-Contract-Url
-If there is no associated proposal, the user agent will fetch a proposal from
-this URL and process it.  This typically prompts the user to agree to pay.
 
address@hidden X-Taler-Offer-Url
-If there is no associated proposal and @code{X-Taler-Contract-Url} is not
-specified, the browser will navigate to this URL.
address@hidden History
address@hidden Listing all transactions
 
address@hidden X-Taler-User-Tipping-Url
-If this header present, the value of this header must be a URL that the user 
agent can use to obtain tips (small, non-binding
-financial rewards) payed from the merchant to the user's wallet.  If this 
field is present, @code{X-Taler-User-Tipping-Exchange}
-and @code{X-Taler-User-Tipping-Amount} must also be present.
+In order to track transactions, order ids are needed as input.
+To that purpose, the frontend needs to make a HTTP GET request to
address@hidden/history}, which is offered by the backend.
 
address@hidden X-Taler-User-Tipping-Exchange
-Exchange base URL for the exchange that the merchant helps withdrawing the tip 
from.
+The returned data lists the transactions from the youngest back to
+the oldest.
 
address@hidden X-Taler-User-Tipping-Amount
-Amount of tip that the user is receiving, in the standard amount format 
(CURR:X.Y).
+The @code{/history} API is actually more rich, as it offers the way
+to skim results based on time or on index, but that goes beyond the
+scope of this tutorial.
 
address@hidden table
+Our example frontend implements this feature by orchestrating two
+parts:
 
address@hidden JavaScript API
address@hidden JavaScript API
address@hidden
address@hidden A JavaScript function, imported within @code{backoffice.html},
+      that issues the HTTP GET to TBD
+      and modifies the current page by adding a table showing the result.
address@hidden The TBD, which is in charge of serving the request
+      coming from the JavaScript. Its task is to relay that request to the
+      backend, and echo the result back.
address@hidden itemize
 
-The following functions are defined in the @code{taler} namespace of the 
@code{taler-wallet-lib} helper library
-available at 
@url{https://git.taler.net/web-common.git/tree/taler-wallet-lib.js}.
+See below both parts:
 
address@hidden @code
address@hidden onPresent(callback: () => void)
-Add a callback to be called when support for Taler payments is detected.
address@hidden
+TBD
address@hidden smallexample
 
address@hidden onAbsent(callback: () => void)
-Add a callback to be called when support for Taler payments is disabled.
address@hidden
+TBD
address@hidden smallexample
 
address@hidden pay(@{contract_url: string, offer_url: address@hidden)
-Results in the same action as a @code{402 Payment Required} with 
@code{contract_url} in
-the @code{X-Taler-Contract-Url} header and @code{offer_url} in the 
@code{X-Taler-Payment-Url} header.
 
address@hidden refund(refund_url: string)
-Results in the same action as a @code{402 Payment Required} with 
@code{refund_url} in
-the @code{X-Taler-Refund-Url} header.
 
address@hidden table
address@hidden Advanced topics
address@hidden Advanced topics
 
address@hidden Stylesheet-based presence detection
address@hidden Stylesheet-based presence detection
address@hidden
+* Detecting the presence of the Taler wallet::  Detecting the presence of the 
Taler wallet
+* The Taler proposal format::                   The Taler proposal format
address@hidden * Inline proposals::                            Sending 
proposals with the HTTP header
+* Instances::                                   Instances
+* The fulfillment page::                        The fulfillment page
+* Normalized base URLs::                        Normalized base URLs
address@hidden menu
 
-Stylesheet-based presence detection will be applied on all pages that have the
address@hidden attribute of the @code{html} element set @code{true}.
-The default/fallback stylesheet, that will be taken over by the wallet once
-installed, must be included with the id @code{taler-presence-stylesheet}, like
-this:
address@hidden ../../common/texi/wallet-detection.texi
address@hidden ../../common/texi/proposals.texi
address@hidden @include inline-proposals.texi  -- not yet written for Python!
address@hidden ../../common/texi/instances.texi
address@hidden ../../common/texi/fulfillment-page.texi
address@hidden ../../common/texi/normalized-base-url.texi
 
-The following CSS classes can be used:
address@hidden @code
address@hidden taler-installed-hide
-A CSS rule will set the @code{display} property for this class to @code{none} 
once the Taler wallet is installed and enabled.
-If the wallet is not installed, @code{display} will be @code{inherit}.
 
address@hidden taler-installed-show
-A CSS rule will set the @code{display} property for this class to 
@code{inherit} once the Taler wallet is installed and enabled.
-If the wallet is not installed, @code{display} will be @code{none}.
 
address@hidden table
address@hidden ************ Reference chapter ***********
address@hidden ../../common/texi/api-reference.texi
 
 
 
@@ -598,13 +654,13 @@ If the wallet is not installed, @code{display} will be 
@code{none}.
 @unnumbered GNU-LGPL
 @cindex license
 @cindex LGPL
address@hidden lgpl.texi
address@hidden ../../common/texi/lgpl.texi
 
 @node GNU-FDL
 @unnumbered GNU-FDL
 @cindex license
 @cindex GNU Free Documentation License
address@hidden fdl-1.3.texi
address@hidden ../../common/texi/fdl-1.3.texi
 
 @node Concept Index
 @unnumbered Concept Index
diff --git a/python/doc/version.texi b/python/doc/version.texi
deleted file mode 100644
index 1d4e9ed..0000000
--- a/python/doc/version.texi
+++ /dev/null
@@ -1,4 +0,0 @@
address@hidden UPDATED 22 February 2016
address@hidden UPDATED-MONTH February 2017
address@hidden EDITION 0.0.1
address@hidden VERSION 0.0.1

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]