summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-08-08 13:02:11 +0530
committerFlorian Dold <florian.dold@gmail.com>2020-08-08 13:02:11 +0530
commitd429ea577fc5af028b0d5f3ed309fc96155e8240 (patch)
tree900d10f080e4e5eae444757310182895bab1859f
parent8574d8848a67680fc65b6e7cc0969cd83e8ba9fc (diff)
downloadtaler-merchant-demos-d429ea577fc5af028b0d5f3ed309fc96155e8240.tar.gz
taler-merchant-demos-d429ea577fc5af028b0d5f3ed309fc96155e8240.tar.bz2
taler-merchant-demos-d429ea577fc5af028b0d5f3ed309fc96155e8240.zip
switch to merchant backend based payment flow
-rwxr-xr-xsetup.py1
-rw-r--r--talermerchantdemos/blog/blog.py59
-rw-r--r--talermerchantdemos/blog/templates/base.html3
-rw-r--r--talermerchantdemos/blog/templates/cc-payment.html5
-rw-r--r--talermerchantdemos/blog/templates/request_payment.html69
-rw-r--r--talermerchantdemos/donations/donations.py77
-rw-r--r--talermerchantdemos/donations/templates/request_payment.html69
7 files changed, 24 insertions, 259 deletions
diff --git a/setup.py b/setup.py
index 0fb1be3..9075450 100755
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,6 @@ setup(name='talermerchantdemos',
install_requires=["Flask>=0.10",
"beautifulsoup4",
"jsmin",
- "qrcode",
"lxml",
"requests",
"cachelib",
diff --git a/talermerchantdemos/blog/blog.py b/talermerchantdemos/blog/blog.py
index 4b1545f..1e25555 100644
--- a/talermerchantdemos/blog/blog.py
+++ b/talermerchantdemos/blog/blog.py
@@ -1,5 +1,5 @@
##
-# This file is part of GNU TALER.
+# This file is part of GNU taler.
# Copyright (C) 2014-2017 INRIA
#
# TALER is free software; you can redistribute it and/or modify it under the
@@ -22,8 +22,6 @@ import logging
import os
import traceback
import uuid
-import qrcode
-import qrcode.image.svg
import base64
import flask
import lxml.etree
@@ -150,26 +148,8 @@ def refund(order_id):
order_id=order_id, reason="Demo reimbursement", refund=ARTICLE_AMOUNT
)
resp = backend_post(BACKEND_URL, "refund", refund_spec)
- try:
- # delete from paid article cache
- paid_articles_cache.delete(session_id + "-" + article_name)
- taler_refund_uri = resp["taler_refund_uri"]
- qrcode_svg = get_qrcode_svg(taler_refund_uri)
- content = flask.render_template(
- "templates/show_refund.html",
- article_name=article_name,
- taler_refund_uri=taler_refund_uri,
- qrcode_svg=qrcode_svg,
- )
- headers = {"Taler": taler_refund_uri}
- return flask.Response(content, status=402, headers=headers)
- except KeyError:
- err_abort(
- 500,
- message="Response from backend incomplete",
- json=resp,
- stack=traceback.format_exc(),
- )
+ paid_articles_cache.delete(session_id + "-" + article_name)
+ return flask.redirect(pay_status["order_status_url"])
##
@@ -206,23 +186,6 @@ def render_article(article_name, data, order_id):
)
-def get_qrcode_svg(data):
- factory = qrcode.image.svg.SvgImage
- img = qrcode.make(data, image_factory=factory)
- return lxml.etree.tostring(img.get_image()).decode("utf-8")
-
-
-##
-# This endpoint is used by the payment request page
-# to check if the payment has been completed via the QR code.
-@app.route("/check-status/<order_id>/<session_id>")
-def check_status(order_id, session_id):
- pay_status = backend_get(
- BACKEND_URL, f"private/orders/{order_id}/", dict(session_id=session_id)
- )
- return flask.jsonify(paid=pay_status["paid"])
-
-
##
# Trigger a article purchase. The logic follows the main steps:
#
@@ -313,18 +276,4 @@ def article(article_name, data=None):
##
# Redirect the browser to a page where the wallet can
# run the payment protocol.
- taler_pay_uri = pay_status["taler_pay_uri"]
- qrcode_svg = get_qrcode_svg(taler_pay_uri)
- check_status_url_enc = urllib.parse.quote(
- flask.url_for("check_status", order_id=order_id, session_id=session_id)
- )
- content = flask.render_template(
- "templates/request_payment.html",
- article_name=article_name,
- taler_pay_uri=taler_pay_uri,
- qrcode_svg=qrcode_svg,
- check_status_url_enc=check_status_url_enc,
- )
- headers = {"Taler": taler_pay_uri}
- resp = flask.Response(content, status=402, headers=headers)
- return resp
+ return flask.redirect(pay_status["order_status_url"])
diff --git a/talermerchantdemos/blog/templates/base.html b/talermerchantdemos/blog/templates/base.html
index 4507d9e..3d7d0f0 100644
--- a/talermerchantdemos/blog/templates/base.html
+++ b/talermerchantdemos/blog/templates/base.html
@@ -15,7 +15,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-->
-<html data-taler-nojs="true">
+<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -23,7 +23,6 @@
<title>Taler Essay Shop Demo</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='pure.css') }}" />
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='demo.css') }}" />
- <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='taler-fallback.css') }}" id="taler-presence-stylesheet" />
<style>
.warn {
background-color: #aa393977;
diff --git a/talermerchantdemos/blog/templates/cc-payment.html b/talermerchantdemos/blog/templates/cc-payment.html
deleted file mode 100644
index b23b751..0000000
--- a/talermerchantdemos/blog/templates/cc-payment.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends "templates/base.html" %}
-
-{% block main %}
-Credit card payment declined.
-{% endblock main %}
diff --git a/talermerchantdemos/blog/templates/request_payment.html b/talermerchantdemos/blog/templates/request_payment.html
deleted file mode 100644
index 6e050d0..0000000
--- a/talermerchantdemos/blog/templates/request_payment.html
+++ /dev/null
@@ -1,69 +0,0 @@
-{% extends "templates/base.html" %}
-
-
-{% block meta %}
-<noscript>
- <meta http-equiv="refresh" content="1">
-</noscript>
-{% endblock meta %}
-
-
-{% block scripts %}
-<script>
- let checkUrl = decodeURIComponent("{{ check_status_url_enc }}");
- let delayMs = 500;
- function check() {
- let req = new XMLHttpRequest();
- req.onreadystatechange = function () {
- if (req.readyState === XMLHttpRequest.DONE) {
- if (req.status === 200) {
- try {
- let resp = JSON.parse(req.responseText);
- if (resp.paid) {
- document.location.reload(true);
- }
- } catch (e) {
- console.error("could not parse response:", e);
- }
- }
- setTimeout(check, delayMs);
- }
- };
- req.onerror = function () {
- setTimeout(check, delayMs);
- }
- req.open("GET", checkUrl);
- req.send();
- }
-
- setTimeout(check, delayMs);
-</script>
-{% endblock scripts %}
-
-
-{% block main %}
-
-<h1>Payment Required</h1>
-
-<div class="taler-installed-hide">
- <p>
- Looks like your browser doesn't support GNU Taler payments. You can try
- installing a <a href="https://taler.net/en/wallet.html">wallet browser extension</a>.
- </p>
-</div>
-
-<div>
-
- <p>
- You can use this QR code to pay with your mobile wallet:
- </p>
-
- {{ qrcode_svg | safe }}
-
- <p>
- Click <a href="{{ taler_pay_uri }}">this link</a> to open your system's Taler wallet if it exists.
- </p>
-
-</div>
-
-{% endblock main %}
diff --git a/talermerchantdemos/donations/donations.py b/talermerchantdemos/donations/donations.py
index c011189..f77bec1 100644
--- a/talermerchantdemos/donations/donations.py
+++ b/talermerchantdemos/donations/donations.py
@@ -22,8 +22,6 @@ import logging
import flask
import lxml.etree
import os
-import qrcode
-import qrcode.image.svg
import time
import traceback
import urllib
@@ -37,7 +35,7 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
app = flask.Flask(__name__, template_folder=BASE_DIR)
app.debug = True
-app.secret_key = base64.b64encode(os.urandom(64)).decode('utf-8')
+app.secret_key = base64.b64encode(os.urandom(64)).decode("utf-8")
TC = TalerConfig.from_env()
BACKEND_BASE_URL = TC["frontends"]["backend"].value_string(required=True)
@@ -81,6 +79,7 @@ def backend_instanced_get(instance, endpoint, params):
backend_url = urljoin(BACKEND_BASE_URL, f"instances/{instance}/")
return backend_get(backend_url, endpoint, params)
+
##
# POST a request to the backend, and return a error
# response if any error occurs.
@@ -93,6 +92,7 @@ def backend_instanced_post(instance, endpoint, json):
backend_url = urljoin(BACKEND_BASE_URL, f"instances/{instance}/")
return backend_post(backend_url, endpoint, json)
+
##
# Inspect GET arguments in the look for a parameter.
#
@@ -114,9 +114,7 @@ def expect_parameter(name):
@app.errorhandler(Exception)
def internal_error(e):
return flask.render_template(
- "templates/error.html",
- message="Internal error",
- stack=traceback.format_exc()
+ "templates/error.html", message="Internal error", stack=traceback.format_exc()
)
@@ -126,9 +124,7 @@ def internal_error(e):
# @return response object of the index page.
@app.route("/")
def index():
- return flask.render_template(
- "templates/index.html", merchant_currency=CURRENCY
- )
+ return flask.render_template("templates/index.html", merchant_currency=CURRENCY)
##
@@ -156,7 +152,7 @@ def checkout():
donation_amount=amount,
donation_receiver=donation_receiver,
donation_donor=donation_donor,
- merchant_currency=CURRENCY
+ merchant_currency=CURRENCY,
)
@@ -189,47 +185,26 @@ def donate():
"fulfillment",
timestamp=str(time.time()),
receiver=donation_receiver,
- _external=True
+ _external=True,
)
order = dict(
amount=donation_amount,
extra=dict(
- donor=donation_donor,
- receiver=donation_receiver,
- amount=donation_amount
+ donor=donation_donor, receiver=donation_receiver, amount=donation_amount
),
fulfillment_url=fulfillment_url,
summary="Donation to {}".format(donation_receiver),
- refund_deadline=dict(t_ms=1000*int(time.time() + 10 * 30)),
- wire_transfer_deadline=dict(t_ms=1000*int(time.time() + 15 * 30))
+ refund_deadline=dict(t_ms=1000 * int(time.time() + 10 * 30)),
+ wire_transfer_deadline=dict(t_ms=1000 * int(time.time() + 15 * 30)),
+ )
+ order_resp = backend_instanced_post(
+ donation_receiver, "private/orders", dict(order=order)
)
- order_resp = backend_instanced_post(donation_receiver, "private/orders", dict(order=order))
order_id = order_resp["order_id"]
return flask.redirect(
- flask.url_for(
- "fulfillment", receiver=donation_receiver, order_id=order_id
- )
+ flask.url_for("fulfillment", receiver=donation_receiver, order_id=order_id)
)
-##
-# This endpoint is used by the payment request page
-# to check if the payment has been completed via the QR code.
-@app.route("/check-status/<instance>/<order_id>")
-def check_status(instance, order_id):
- pay_params = dict(order_id=order_id)
- pay_status = backend_instanced_get(
- instance,
- f"private/orders/{order_id}",
- params=dict()
- )
- return flask.jsonify(paid=pay_status["paid"])
-
-
-def get_qrcode_svg(data):
- factory = qrcode.image.svg.SvgImage
- img = qrcode.make(data, image_factory=factory)
- return lxml.etree.tostring(img.get_image()).decode("utf-8")
-
##
# Serve the fulfillment page.
@@ -244,11 +219,10 @@ def fulfillment(receiver):
order_id = expect_parameter("order_id")
pay_params = dict(order_id=order_id)
pay_status = backend_instanced_get(
- receiver,
- f"private/orders/{order_id}",
- params=dict()
+ receiver, f"private/orders/{order_id}", params=dict()
)
- if pay_status.get("paid"):
+ order_status = pay_status.get("order_status")
+ if order_status == "paid":
extra = pay_status["contract_terms"]["extra"]
return flask.render_template(
"templates/fulfillment.html",
@@ -256,19 +230,6 @@ def fulfillment(receiver):
donation_amount=extra["amount"],
donation_donor=extra["donor"],
order_id=order_id,
- currency=CURRENCY
+ currency=CURRENCY,
)
- taler_pay_uri = pay_status["taler_pay_uri"]
- qrcode_svg = get_qrcode_svg(taler_pay_uri)
- check_status_url_enc = urllib.parse.quote(
- flask.url_for("check_status", instance=receiver, order_id=order_id)
- )
- content = flask.render_template(
- "templates/request_payment.html",
- taler_pay_uri=taler_pay_uri,
- qrcode_svg=qrcode_svg,
- check_status_url_enc=check_status_url_enc
- )
- headers = {"Taler": taler_pay_uri}
- resp = flask.Response(content, status=402, headers=headers)
- return resp
+ return flask.redirect(pay_status["order_status_url"])
diff --git a/talermerchantdemos/donations/templates/request_payment.html b/talermerchantdemos/donations/templates/request_payment.html
deleted file mode 100644
index 6e050d0..0000000
--- a/talermerchantdemos/donations/templates/request_payment.html
+++ /dev/null
@@ -1,69 +0,0 @@
-{% extends "templates/base.html" %}
-
-
-{% block meta %}
-<noscript>
- <meta http-equiv="refresh" content="1">
-</noscript>
-{% endblock meta %}
-
-
-{% block scripts %}
-<script>
- let checkUrl = decodeURIComponent("{{ check_status_url_enc }}");
- let delayMs = 500;
- function check() {
- let req = new XMLHttpRequest();
- req.onreadystatechange = function () {
- if (req.readyState === XMLHttpRequest.DONE) {
- if (req.status === 200) {
- try {
- let resp = JSON.parse(req.responseText);
- if (resp.paid) {
- document.location.reload(true);
- }
- } catch (e) {
- console.error("could not parse response:", e);
- }
- }
- setTimeout(check, delayMs);
- }
- };
- req.onerror = function () {
- setTimeout(check, delayMs);
- }
- req.open("GET", checkUrl);
- req.send();
- }
-
- setTimeout(check, delayMs);
-</script>
-{% endblock scripts %}
-
-
-{% block main %}
-
-<h1>Payment Required</h1>
-
-<div class="taler-installed-hide">
- <p>
- Looks like your browser doesn't support GNU Taler payments. You can try
- installing a <a href="https://taler.net/en/wallet.html">wallet browser extension</a>.
- </p>
-</div>
-
-<div>
-
- <p>
- You can use this QR code to pay with your mobile wallet:
- </p>
-
- {{ qrcode_svg | safe }}
-
- <p>
- Click <a href="{{ taler_pay_uri }}">this link</a> to open your system's Taler wallet if it exists.
- </p>
-
-</div>
-
-{% endblock main %}