summaryrefslogtreecommitdiff
path: root/talerdonations/donations
diff options
context:
space:
mode:
Diffstat (limited to 'talerdonations/donations')
-rw-r--r--talerdonations/donations/donations.py86
1 files changed, 79 insertions, 7 deletions
diff --git a/talerdonations/donations/donations.py b/talerdonations/donations/donations.py
index 6d560e6..fd60b3f 100644
--- a/talerdonations/donations/donations.py
+++ b/talerdonations/donations/donations.py
@@ -1,3 +1,4 @@
+##
# This file is part of GNU TALER.
# Copyright (C) 2014-2016 INRIA
#
@@ -14,6 +15,7 @@
#
# @author Florian Dold
# @author Marcello Stanisci
+# @brief Implementation of a donations site.
from urllib.parse import urljoin, parse_qsl
import logging
@@ -41,6 +43,12 @@ APIKEY = TC["frontends"]["backend_apikey"].value_string(required=True)
app.config.from_object(__name__)
+
+##
+# Extend the templating language with a function
+# that fetches values from the environment.
+#
+# @return the environment-reading function.
@app.context_processor
def utility_processor():
def env(name, default=None):
@@ -48,11 +56,23 @@ def utility_processor():
return dict(env=env)
+##
+# Return a error response to the client.
+#
+# @param abort_status_code status code to return along the response.
+# @param params _kw_ arguments to passed verbatim to the templating engine.
def err_abort(abort_status_code, **params):
t = flask.render_template("templates/error.html", **params)
flask.abort(flask.make_response(t, abort_status_code))
+##
+# Issue a GET request to the backend.
+#
+# @param endpoint the backend endpoint where to issue the request.
+# @param params (dict type of) URL parameters to append to the request.
+# @return the JSON response from the backend, or a error response
+# if something unexpected happens.
def backend_get(endpoint, params):
headers = {"Authorization": "ApiKey " + APIKEY}
try:
@@ -69,6 +89,14 @@ def backend_get(endpoint, params):
return response_json
+##
+# POST a request to the backend, and return a error
+# response if any error occurs.
+#
+# @param endpoint the backend endpoint where to POST
+# this request.
+# @param json the POST's body.
+# @return the backend response (JSON format).
def backend_post(endpoint, json):
headers = {"Authorization": "ApiKey " + APIKEY}
try:
@@ -86,29 +114,54 @@ def backend_post(endpoint, json):
return response_json
+
+##
+# Inspect GET arguments in the look for a parameter.
+#
+# @param name the parameter name to lookup.
+# @return the parameter value, or a error page if not found.
def expect_parameter(name):
val = flask.request.args.get(name)
if not val:
return err_abort(400, "parameter '{}' required".format(name))
return val
-
+##
+# "Fallback" exception handler to capture all the unmanaged errors.
+#
+# @param e the Exception object, currently unused.
+# @return flask-native response object carrying the error message
+# (and execution stack!).
@app.errorhandler(Exception)
def internal_error(e):
return flask.render_template("templates/error.html",
message="Internal error",
stack=traceback.format_exc())
-
+##
+# Serve the main index page.
+#
+# @return response object of the index page.
@app.route("/")
def index():
return flask.render_template("templates/index.html", merchant_currency=CURRENCY)
+##
+# Serve the "/javascript" page.
+#
+# @return response object for the /javascript page.
@app.route("/javascript")
def javascript_licensing():
return flask.render_template("templates/javascript.html")
+
+##
+# Serve the "/checkout" page. This page lets the
+# user pick the payment method they want to use,
+# and finally confirm the donation.
+#
+# @return response object for the /checkout page.
@app.route("/checkout", methods=["GET"])
def checkout():
amount = expect_parameter("donation_amount")
@@ -122,11 +175,24 @@ def checkout():
merchant_currency=CURRENCY)
+##
+# Serve the page advising the user about the impossibility
+# of further processing the payment method they chose.
+#
+# @return response object about the mentioned impossibility.
@app.route("/provider-not-supported")
def provider_not_supported():
return flask.render_template( "templates/provider-not-supported.html")
+
+##
+# POST the donation request to the backend. In particular,
+# it uses the "POST /order" API.
+#
+# @return response object that will redirect the browser to
+# the fulfillment URL, where all the pay-logic will
+# happen.
@app.route("/donate")
def donate():
donation_receiver = expect_parameter("donation_receiver")
@@ -148,14 +214,20 @@ def donate():
return flask.redirect(flask.url_for("fulfillment", receiver=donation_receiver, order_id=order_id))
+
+##
+# Serve the fulfillment page.
+#
+# @param receiver the donation receiver name, that should
+# correspond to a merchant instance.
+# @return after the wallet sent the payment, the final HTML "congrats"
+# page is returned; otherwise, the browser will be redirected
+# to a page that accepts the payment.
@app.route("/donation/<receiver>")
def fulfillment(receiver):
order_id = expect_parameter("order_id")
- pay_params = dict(
- instance=receiver,
- order_id=order_id,
- )
-
+ pay_params = dict(instance=receiver,
+ order_id=order_id)
pay_status = backend_get("check-payment", pay_params)
if pay_status.get("payment_redirect_url"):