summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-10-15 17:13:58 +0200
committerChristian Grothoff <christian@grothoff.org>2017-10-15 17:13:58 +0200
commitfbd4260ef9d26c017462de0c61a1148886e77c65 (patch)
tree7bca90b340fde36bea81520718e15ce779efe9e5
parent39074ad2b66370599396fbb1e4a1835ec7c9d5fe (diff)
downloadmerchant-frontend-examples-fbd4260ef9d26c017462de0c61a1148886e77c65.tar.gz
merchant-frontend-examples-fbd4260ef9d26c017462de0c61a1148886e77c65.tar.bz2
merchant-frontend-examples-fbd4260ef9d26c017462de0c61a1148886e77c65.zip
clean up tutorials
-rw-r--r--.gitignore11
-rw-r--r--common/html/js-wallet.html26
-rw-r--r--common/texi/api-reference.texi88
-rw-r--r--common/texi/fdl-1.3.texi (renamed from python/doc/fdl-1.3.texi)0
-rw-r--r--common/texi/fulfillment-page.texi30
-rw-r--r--common/texi/instances.texi24
-rw-r--r--common/texi/js-payments.texi69
-rw-r--r--common/texi/lgpl.texi (renamed from python/doc/lgpl.texi)0
-rw-r--r--common/texi/normalized-base-url.texi22
-rw-r--r--common/texi/proposals.texi186
-rw-r--r--common/texi/syntax.texi (renamed from python/doc/syntax.texi)0
-rw-r--r--common/texi/wallet-detection.texi62
-rw-r--r--php/doc/inline-proposals.texi22
-rw-r--r--php/doc/tutorial.texi545
-rw-r--r--python/doc/tutorial.texi240
15 files changed, 709 insertions, 616 deletions
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 @@
+@node Reference
+@chapter Reference
+
+@menu
+* 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
+@end menu
+
+@node Headers for HTTP 402
+@section 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
+@code{fulfillment_url} 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:
+@table @code
+@item 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.
+
+@item 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.
+
+@item 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.
+
+@item 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.
+
+@item X-Taler-User-Tipping-Exchange
+Exchange base URL for the exchange that the merchant helps withdrawing the tip from.
+
+@item X-Taler-User-Tipping-Amount
+Amount of tip that the user is receiving, in the standard amount format (CURR:X.Y).
+
+@end table
+
+@node JavaScript API
+@section 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}.
+
+@table @code
+@item onPresent(callback: () => void)
+Add a callback to be called when support for Taler payments is detected.
+
+@item onAbsent(callback: () => void)
+Add a callback to be called when support for Taler payments is disabled.
+
+@item pay(@{contract_url: string, offer_url: string@})
+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.
+
+@item 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.
+
+@end table
+
+@node Stylesheet-based presence detection
+@section Stylesheet-based presence detection
+
+Stylesheet-based presence detection will be applied on all pages that have the
+@code{data-taler-nojs} 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:
+@table @code
+@item 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}.
+
+@item 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}.
+
+@end table
diff --git a/python/doc/fdl-1.3.texi b/common/texi/fdl-1.3.texi
index 8805f1a..8805f1a 100644
--- a/python/doc/fdl-1.3.texi
+++ b/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 @@
+@c Section of advanced topics discussing the fulfillment page in more depth.
+
+@node The fulfillment page
+@section The fulfillment page
+@cindex 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:
+
+@enumerate
+@item Taler payments @emph{can} be implemented in DB-less frontends.
+
+@item 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).
+@end 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 @@
+@c Section from ``advanced topics'' introducing the concept of instances
+
+@node Instances
+@section Instances
+@cindex 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 @@
+@c Section about triggering payments via JavaScript, currently not used!
+
+@node Payments using JavaScript
+@section Triggering payments using JavaScript
+@c
+Please note that the following examples are purely instructional and NOT TESTED
+along with the tutorial code.
+@c
+@cindex JavaScript
+@c
+@subsection Offering contracts
+@c
+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.
+@c
+Thus our homepage can now look as follows
+@c
+@smallexample
+// ../index-js.html
+@verbatiminclude ../index-js.html
+@end smallexample
+@c
+@code{donate-js.html} 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.
+
+@c
+@smallexample
+// ../donate-js.html
+@verbatiminclude ../donate-js.html
+@end smallexample
+@c
+Please make sure that @code{taler-wallet-lib.js} location is valid.
+@c
+@subsection Receiving payments
+@cindex payment
+@c
+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.
+@c
+The same action can be accomplished @emph{with} JavaScript, thanks to
+@code{taler-wallet-lib.js} 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:
+@c
+@smallexample
+// ../fulfillment-js.php
+@verbatiminclude ../fulfillment-js.php
+@end smallexample
+@c
+Note that, in order to use this fulfillment handler for the tutorial, you need to
+specify it in the contract's ``fulfillment_url'' field:
+@c
+@smallexample
+@{
+... contract fields ..
+@c
+"fulfillment_url": "/fulfillment-js.php?transaction_id=<TRANSACTION_ID>& \
+ timestamp=<CONTRACTTIMESTAMP>"
+...
+@}
+@end smallexample
+@c
+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
index ab03d6c..ab03d6c 100644
--- a/python/doc/lgpl.texi
+++ b/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 @@
+@c Section from ``advanced topics'' about how to normalize base URLs
+
+@node Normalized base URLs
+@section 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).
+
+@itemize
+@item The URL must be absolute. This implies that the URL has a schema.
+@item The path component of the URL must end with a slash.
+@item The URL must not contain a fragment or query.
+@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.
+
+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 @@
+@c Section describing the format of Taler contracts/proposals in detail
+
+@node The Taler proposal format
+@section The Taler proposal format
+@cindex contract
+
+A Taler proposal can specify many details about the transaction.
+This section describes each of the fields in depth.
+
+@table @var
+@item amount
+@cindex 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"}.
+
+@item max_fee
+@cindex fees
+@cindex 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}.
+
+
+@item max_wire_fee
+@cindex fees
+@cindex 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.
+
+
+@item wire_fee_amortization
+@cindex fees
+@cindex 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.
+
+@item pay_url
+@cindex pay_url
+Which URL accepts payments. This is the URL where the wallet will POST
+coins.
+
+@item fulfillment_url
+@cindex 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.
+
+@item order_id
+@cindex order ID
+Alphanumeric identifier, freely definable by the merchant.
+Used by the merchant to uniquely identify the transaction.
+
+@item summary
+@cindex 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.
+
+@item timestamp
+Time at which the offer was generated.
+@c FIXME: describe time format in detail here
+
+@item pay_deadline
+@cindex 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.
+
+@item refund_deadline
+@cindex 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}.
+
+@item products
+@cindex product description
+Array of products that are being sold to the customer. Each
+entry contains a tuple with the following values:
+
+@table @var
+@item description
+Description of the product.
+@item quantity
+Quantity of the items to be shipped. May specify a unit (@code{1 kg})
+or just the count.
+@item 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.
+@item 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})}.
+@item 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.
+@c FIXME: a receipt not including the item's price?
+The information is also likely to be used by tax audits of the merchant.
+@item delivery_date
+Time by which the product is to be delivered to the
+@var{delivery_location}.
+@item delivery_location
+This should give a label in the @var{locations} map, specifying
+where the item is to be delivered.
+@end 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.
+
+@item merchant
+@table @var
+@item address
+This should give a label in the @var{locations} map, specifying
+where the merchant is located.
+@item name
+This should give a human-readable name for the merchant's business.
+@item jurisdiction
+This should give a label in the @var{locations} map, specifying
+the jurisdiction under which this contract is to be arbitrated.
+@end table
+
+@item locations
+@cindex 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:
+@table @var
+@item country
+Name of the country for delivery, as found on a postal package, i.e. ``France''.
+@item state
+Name of the state for delivery, as found on a postal package, i.e. ``NY''.
+@item region
+Name of the region for delivery, as found on a postal package.
+@item province
+Name of the province for delivery, as found on a postal package.
+@item city
+Name of the city for delivery, as found on a postal package.
+@item ZIP code
+ZIP code for delivery, as found on a postal package.
+@item street
+Street name for delivery, as found on a postal package.
+@item street number
+Street number (number of the house) for delivery, as found on a postal package.
+@item name receiver name for delivery, either business or person name.
+
+@end 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.
+
+@end table
diff --git a/python/doc/syntax.texi b/common/texi/syntax.texi
index 8bb37b3..8bb37b3 100644
--- a/python/doc/syntax.texi
+++ b/common/texi/syntax.texi
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 @@
+@c Section on how to detect the Taler wallet
+
+@node Detecting the presence of the Taler wallet
+@section Detecting the presence of the Taler wallet
+@cindex 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.
+
+@subsection The no-JavaScript way
+The follwing example shows all that is needed to perform the detection
+without using JavaScript:
+
+@smallexample
+<!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>
+@end 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
+@code{taler-installed-show} class, in case no wallet is installed. If otherwise
+the wallet is installed, the wallet takes action by hiding any tag from the
+@code{taler-installed-hide} class and overriding @code{taler-fallback.css} logic
+by showing any tag from the @code{taler-installed-show} class.
+
+@subsection The JavaScript way
+
+@code{taler-wallet-lib.js} 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:
+
+@smallexample
+// js-wallet.html
+@verbatiminclude ../../common/html/js-wallet.html
+@end smallexample
+
+@code{taler-wallet-lib.js} 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 @@
+@node Inlining proposals in HTTP headers
+@section Inlining proposals in HTTP headers
+@cindex optimization
+@cindex 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.
+
+@smallexample
+// ../inline.php
+@verbatiminclude ../inline.php
+@end 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..27ef83a 100644
--- a/php/doc/tutorial.texi
+++ b/php/doc/tutorial.texi
@@ -2,6 +2,7 @@
@c %**start of header
@setfilename tutorial.info
@include version.texi
+@include ../../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})
-@author Christian Grothoff (@email{christian.grothoff@@inria.fr})
+@author Christian Grothoff (@email{christian.grothoff@@inria.fr}
+@author 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
-@c FIXME. Add section about including images (or extra files in general)
-@c along with payed content.
+@include ../../common/texi/wallet-detection.texi
+@include ../../common/texi/proposals.texi
+@include inline-proposals.texi
+@include ../../common/texi/instances.texi
+@include ../../common/texi/fulfillment-page.texi
+@include ../../common/texi/normalized-base-url.texi
-@node Presence detection
-@section Reacting to the presence of a Taler wallet
-@cindex 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.
-
-@subsection The no-JavaScript way
-The follwing example shows all that is needed to perform the detection
-without using JavaScript:
-
-@smallexample
-<!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>
-@end 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
-@code{taler-installed-show} class, in case no wallet is installed. If otherwise
-the wallet is installed, the wallet takes action by hiding any tag from the
-@code{taler-installed-hide} class and overriding @code{taler-fallback.css} logic
-by showing any tag from the @code{taler-installed-show} class.
-
-@subsection The JavaScript way
-
-@code{taler-wallet-lib.js} 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:
-
-@smallexample
-<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>
-@end smallexample
-
-@code{taler-wallet-lib.js} 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.
-
-
-@node Taler proposals
-@section Building Taler proposals
-@cindex contract
-
-A Taler proposal can specify many details about the transaction.
-This section describes each of the fields in depth.
-
-@table @var
-@item amount
-@cindex 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"}.
-
-@item max_fee
-@cindex fees
-@cindex 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}.
-
-
-@item max_wire_fee
-@cindex fees
-@cindex 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.
-
-
-@item wire_fee_amortization
-@cindex fees
-@cindex 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.
-
-@item pay_url
-@cindex pay_url
-Which URL accepts payments. This is the URL where the wallet will POST
-coins.
-
-@item fulfillment_url
-@cindex 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.
-
-@item order_id
-@cindex order ID
-Alphanumeric identifier, freely definable by the merchant.
-Used by the merchant to uniquely identify the transaction.
-
-@item summary
-@cindex 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.
-
-@item timestamp
-Time at which the offer was generated.
-@c FIXME: describe time format in detail here
-
-@item pay_deadline
-@cindex 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.
-
-@item refund_deadline
-@cindex 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}.
-
-@item products
-@cindex product description
-Array of products that are being sold to the customer. Each
-entry contains a tuple with the following values:
-
-@table @var
-@item description
-Description of the product.
-@item quantity
-Quantity of the items to be shipped. May specify a unit (@code{1 kg})
-or just the count.
-@item 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.
-@item 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})}.
-@item 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.
-@c FIXME: a receipt not including the item's price?
-The information is also likely to be used by tax audits of the merchant.
-@item delivery_date
-Time by which the product is to be delivered to the
-@var{delivery_location}.
-@item delivery_location
-This should give a label in the @var{locations} map, specifying
-where the item is to be delivered.
-@end 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.
-
-@item merchant
-@table @var
-@item address
-This should give a label in the @var{locations} map, specifying
-where the merchant is located.
-@item name
-This should give a human-readable name for the merchant's business.
-@item jurisdiction
-This should give a label in the @var{locations} map, specifying
-the jurisdiction under which this contract is to be arbitrated.
-@end table
-
-@item locations
-@cindex 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:
-@table @var
-@item country
-Name of the country for delivery, as found on a postal package, i.e. ``France''.
-@item state
-Name of the state for delivery, as found on a postal package, i.e. ``NY''.
-@item region
-Name of the region for delivery, as found on a postal package.
-@item province
-Name of the province for delivery, as found on a postal package.
-@item city
-Name of the city for delivery, as found on a postal package.
-@item ZIP code
-ZIP code for delivery, as found on a postal package.
-@item street
-Street name for delivery, as found on a postal package.
-@item street number
-Street number (number of the house) for delivery, as found on a postal package.
-@item name receiver name for delivery, either business or person name.
-
-@end 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.
-
-@end table
-
-@node Inline proposals
-@section Inlining proposals in HTTP headers
-@cindex optimization
-@cindex 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.
-
-@smallexample
-// ../inline.php
-@verbatiminclude ../inline.php
-@end 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.
-
-@c @node Payments using JavaScript
-@c @section Triggering payments using JavaScript
-@c
-@c Please note that the following examples are purely instructional and NOT TESTED
-@c along with the tutorial code.
-@c
-@c @cindex JavaScript
-@c
-@c @subsection Offering contracts
-@c
-@c Offering contracts the JavaScript way doesn't require us to set HTTP
-@c headers, and so -- in a minimalistic implementation -- the donation button
-@c should just hit a HTML page that invokes the @code{offerContractFrom} function,
-@c from the @code{taler-wallet-lib.js} library.
-@c
-@c Thus our homepage can now look as follows
-@c
-@c @smallexample
-@c // ../index-js.html
-@c @verbatiminclude ../index-js.html
-@c @end smallexample
-@c
-@c @code{donate-js.html} is now in charge of calling @code{offerContractFrom}
-@c passing the contract URL to it, which is @code{"/generate-order.php"} in
-@c our example. See below.
-@c
-@c @smallexample
-@c // ../donate-js.html
-@c @verbatiminclude ../donate-js.html
-@c @end smallexample
-@c
-@c Please make sure that @code{taler-wallet-lib.js} location is valid.
-@c
-@c @subsection Receiving payments
-@c @cindex payment
-@c
-@c In the example in section @ref{Initiating the payment process}, the fulfillment
-@c handler @code{/fulfillment.php} triggers the payment in the wallet by returing
-@c the three needed values (contract hashcode, pay URL, offer URL) via HTTP headers.
-@c
-@c The same action can be accomplished @emph{with} JavaScript, thanks to
-@c @code{taler-wallet-lib.js} of @emph{web-common} repository.
-@c The fulfillment handler needs just to call the function @code{executePayment}, feeding it
-@c with the three needed parameters. The wallet will then get triggered and proceed with the
-@c payment. See below a full example:
-@c
-@c @smallexample
-@c // ../fulfillment-js.php
-@c @verbatiminclude ../fulfillment-js.php
-@c @end smallexample
-@c
-@c Note that, in order to use this fulfillment handler for the tutorial, you need to
-@c specify it in the contract's ``fulfillment_url'' field:
-@c
-@c @smallexample
-@c @{
-@c ... contract fields ..
-@c
-@c "fulfillment_url": "/fulfillment-js.php?transaction_id=<TRANSACTION_ID>& \
-@c timestamp=<CONTRACTTIMESTAMP>"
-@c ...
-@c @}
-@c @end smallexample
-@c
-@c Additionally, you should also make sure that @code{taler-wallet-lib.js} location
-@c is valid.
-
-@node The fulfillment page
-@section Design considerations for the fulfillment page
-@cindex fulfillment page
-
-The fulfillment page mechanism is designed to provide the following two properties:
-
-@enumerate
-@item Taler payments @emph{can} be implemented in DB-less frontends.
-
-@item 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).
-@end 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.
-
-@node Instances
-@section Instances
-@cindex 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.
-
-@node Normalized base URLs
-@section 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).
-
-@itemize
-@item The URL must be absolute. This implies that the URL has a schema.
-@item The path component of the URL must end with a slash.
-@item The URL must not contain a fragment or query.
-@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.
-
-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.
-
-
-@c The following section is copied from the Python manual,
-@c changes should be done there and then copied back here.
-@node Reference
-@chapter Reference
-
-@menu
-* 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
-@end menu
-
-@node Headers for HTTP 402
-@section 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
-@code{fulfillment_url} 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:
-@table @code
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@end table
-
-@node JavaScript API
-@section 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}.
-
-@table @code
-@item onPresent(callback: () => void)
-Add a callback to be called when support for Taler payments is detected.
-
-@item onAbsent(callback: () => void)
-Add a callback to be called when support for Taler payments is disabled.
-
-@item pay(@{contract_url: string, offer_url: string@})
-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.
-
-@item 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.
-
-@end table
-
-@node Stylesheet-based presence detection
-@section Stylesheet-based presence detection
-
-Stylesheet-based presence detection will be applied on all pages that have the
-@code{data-taler-nojs} 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:
-@table @code
-@item 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}.
-
-@item 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}.
-
-@end table
-
+@c ************ Reference chapter ***********
+@include ../../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
-@include lgpl.texi
+@include ../../common/texi/lgpl.texi
@node GNU-FDL
@unnumbered GNU-FDL
@cindex license
@cindex GNU Free Documentation License
-@include fdl-1.3.texi
+@include ../../common/texi/fdl-1.3.texi
@node Concept Index
@unnumbered Concept Index
diff --git a/python/doc/tutorial.texi b/python/doc/tutorial.texi
index 3d11468..d4b66dc 100644
--- a/python/doc/tutorial.texi
+++ b/python/doc/tutorial.texi
@@ -2,7 +2,7 @@
@c %**start of header
@setfilename tutorial.info
@include version.texi
-@include syntax.texi
+@include ../../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.
-@section A helper function to generate the order
+@section 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.
-@node Advanced topics
-@chapter Advanced topics
-@menu
-* Normalized base URLs:: Format URLs are expected to be in Taler
-@end menu
-@node Normalized base URLs
-@section 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).
+@node Back-office-integration
+@chapter 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
+@emph{wire 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.
+
+@section Entry page
+
+Given this charge, the back office's main tasks are:
@itemize
-@item The URL must be absolute. This implies that the URL has a schema.
-@item The path component of the URL must end with a slash.
-@item The URL must not contain a fragment or query.
+@item
+Allow the back office operator to specify a order id, and display the
+corresponding wire transfer identifiers.
+@item
+Allow the back office operator to specify a wire transfer ID, and
+display all of the corresponding order ids.
+@item
+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.
+@smallexample
+TBD.
+@end smallexample
-@node Reference
-@chapter Reference
+The imported script @code{history.js} is responsible for dynamically
+get the list of known transactions. See below.
-@menu
-* 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
-@end menu
+@section Tracking a transaction
-@node Headers for HTTP 402
-@section 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
-@code{fulfillment_url} 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:
-@table @code
-@item 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.
+@smallexample
+TBD.
+@end 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.
+
+@section 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
+@code{wtid}, 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:
+
+@smallexample
+TBD.
+@end smallexample
-@item 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.
-@item 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.
+@node History
+@section Listing all transactions
-@item 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
+@code{/history}, which is offered by the backend.
-@item 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.
-@item 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.
-@end table
+Our example frontend implements this feature by orchestrating two
+parts:
-@node JavaScript API
-@section JavaScript API
+@itemize
+@item 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.
+@item 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.
+@end 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:
-@table @code
-@item onPresent(callback: () => void)
-Add a callback to be called when support for Taler payments is detected.
+@smallexample
+TBD
+@end smallexample
-@item onAbsent(callback: () => void)
-Add a callback to be called when support for Taler payments is disabled.
+@smallexample
+TBD
+@end smallexample
-@item pay(@{contract_url: string, offer_url: string@})
-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.
-@item 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.
-@end table
+@node Advanced topics
+@chapter Advanced topics
-@node Stylesheet-based presence detection
-@section Stylesheet-based presence detection
+@menu
+* Detecting the presence of the Taler wallet:: Detecting the presence of the Taler wallet
+* The Taler proposal format:: The Taler proposal format
+@c * Inline proposals:: Sending proposals with the HTTP header
+* Instances:: Instances
+* The fulfillment page:: The fulfillment page
+* Normalized base URLs:: Normalized base URLs
+@end menu
-Stylesheet-based presence detection will be applied on all pages that have the
-@code{data-taler-nojs} 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:
+@include ../../common/texi/wallet-detection.texi
+@include ../../common/texi/proposals.texi
+@c @include inline-proposals.texi -- not yet written for Python!
+@include ../../common/texi/instances.texi
+@include ../../common/texi/fulfillment-page.texi
+@include ../../common/texi/normalized-base-url.texi
-The following CSS classes can be used:
-@table @code
-@item 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}.
-@item 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}.
-@end table
+@c ************ Reference chapter ***********
+@include ../../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
-@include lgpl.texi
+@include ../../common/texi/lgpl.texi
@node GNU-FDL
@unnumbered GNU-FDL
@cindex license
@cindex GNU Free Documentation License
-@include fdl-1.3.texi
+@include ../../common/texi/fdl-1.3.texi
@node Concept Index
@unnumbered Concept Index