merchant-frontend-examples

ZZZ: Inactive/Deprecated
Log | Files | Refs

commit 2697174736178664fdd836045f100936c92e3b34
parent 39c6032057132422a16cad8431b6180c37a3d891
Author: Marcello Stanisci <marcello.stanisci@inria.fr>
Date:   Tue, 28 Mar 2017 18:17:26 +0200

further fixes to python tutorial and example

Diffstat:
Mcommon/graphics/arch_nobo.dot | 1-
Mcommon/graphics/arch_nobo.jpg | 0
Mcommon/graphics/arch_nobo.pdf | 0
Mpython/doc/tutorial.texi | 33++++++++++++++++++++-------------
4 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/common/graphics/arch_nobo.dot b/common/graphics/arch_nobo.dot @@ -1,7 +1,6 @@ digraph G { user[label="Customer browser"]; - admin[label="Shop admin"]; subgraph cluster_0 { Frontend; Backend; diff --git a/common/graphics/arch_nobo.jpg b/common/graphics/arch_nobo.jpg Binary files differ. diff --git a/common/graphics/arch_nobo.pdf b/common/graphics/arch_nobo.pdf Binary files differ. diff --git a/python/doc/tutorial.texi b/python/doc/tutorial.texi @@ -150,8 +150,8 @@ for example to donate 1.0 KUDOS to the charity operating the shop. All the code samples shown below in the tutorial can be found at @url{https://git.taler.net/merchant-frontend-examples.git/tree/python/example/}. Each sample is part of a functional frontend. -The language is Python, and the Web is served by Flask. -@c FIXME: add reference to Flask. +The language is Python, and the Web is served by +Flask@footnote{http://flask.pocoo.org}. @c NOTE: include explaining wallet installation to Web developer here! @@ -165,7 +165,7 @@ installed in the browser. @cindex currency For many critical operations, the frontend needs to communicate with a Taler backend. Assuming that you do not yet have a backend -configured@footnote{FIXME: reference to manual for backend installation}, +configured@footnote{https://docs.taler.net/current/merchant-backend/manual.html}, you can use the public backend provided by the Taler project for testing. This public backend has been set-up at @code{http://backend.test.taler.net/} specifically for testing @@ -174,7 +174,7 @@ go into the ``Tutorial'' account at the Taler ``bank'' running at @code{https://bank.test.taler.net/public-accounts}. In our example, backend and currency are specified by setting two -global variables, as shown below. +global variables, as shown below from @code{python/example/example.py}: @smallexample .. @@ -187,8 +187,9 @@ BACKEND_URL = "http://backend.test.taler.net/" @section Talking to the backend @cindex backend -The frontend needs to issue HTTP POST requests to the backend; -this can be done using the `requests` library: +The frontend needs to issue HTTP POST requests to the backend; this can be +done using the @emph{requests}@footnote{https://docs.taler.net/current/merchant-backend/manual.html} +library: @smallexample import flask @@ -203,7 +204,6 @@ r = requests.post(urljoin(BACKEND_URL, 'proposal'), json=dict(order=order)) if r.status_code != 200: logger.error("failed to POST to '%s'", url) return r.text, r.status_code - @end smallexample @@ -212,7 +212,7 @@ if r.status_code != 200: @cindex button Our goal is to trigger a Taler payment once the customer has clicked on a donation button. We will use a button that issues an HTTP GET -to the frontend @code{/donate.php} URL. For this, the HTML would be as +to the frontend @code{/donate} URL. For this, the HTML would be as follows: @smallexample @@ -263,8 +263,10 @@ from pytaler import amount def generate_proposal(): DONATION = amounts.string_to_amount("0.1:%s" % CURRENCY) MAX_FEE = amounts.string_to_amount("0.05:%s" % CURRENCY) + ORDER_ID = "tutorial-%X-%s" % (randint(0, 0xFFFFFFFF), datetime.today().strftime("%H_%M_%S")) order = dict( nonce=flask.request.args.get("nonce"), + order_id=ORDER_ID, amount=DONATION, max_fee=MAX_FEE, products=[ @@ -275,7 +277,7 @@ def generate_proposal(): price=DONATION, ), ], - fulfillment_url=make_url("/fulfillment"), + fulfillment_url=make_url("/fulfillment", ("order_id", ORDER_ID)), pay_url=make_url("/pay"), merchant=dict( address="nowhere", @@ -296,7 +298,7 @@ def generate_proposal(): @c CHECK ** with Florian, consider inlining... The function @code{amounts.string_to_amount()} is defined by the -`pytaler` library, and its used to convert amount given as strings +@emph{pytaler} library, and it is used to convert amounts given as strings (in the form @code{"1.2:EUR"}) to amount as `dict` (in the form @code{@{value:1, fraction:20000000, currency:"EUR"@}}). @cindex signature @@ -310,7 +312,7 @@ frontend that can eventually relay it to the wallet. The @code{make_url} function is used to ``attach'' paths to the shop's base URL. For example, if the shop is run at @code{https://shop.com}, -then @code{make_url("/path")} would result in @code{https://shop.com/path}. +then @code{make_url("/path", ("a", 5))} would result in @code{https://shop.com/path?a=5}. @section Initiating the payment process @@ -339,16 +341,21 @@ def fulfillment(): # Ask the state whether the user has paid or not paid = flask.session.get("paid", False) if paid: - return "Thank you!" + # Please note that flask.session["order_id"] takes its value + # from the response the _backend_ gave for /pay. This way, the fulfillment + # page only shows what the wallet paid for. + return "Thank you! Your order id is: <b>%s</b>." % flask.session["order_id"]" # At this point, the user did not pay yet, so we set some # appropriate HTTP headers that will instruct the wallet to # 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") response.headers["X-Taler-Contract-Query"] = "fulfillment_url" - # To this URL the wallet can send the coins. + # This is the URL which receives the payment. response.headers["X-Taler-Pay-Url"] = make_url("/pay") # This URL will be visited in case the user has opened # on someone else's fulfillment URL. As a result, the