From 2b04463e4e405fc8e710ece1b53f885dfa9fce38 Mon Sep 17 00:00:00 2001 From: forest Date: Sat, 16 May 2020 22:04:51 -0500 Subject: [PATCH] switch to polling for btcpay payment sessions because btcpay web hooks are super duper slow --- capsulflask/console.py | 7 +++++++ capsulflask/db_model.py | 11 +++++++++++ capsulflask/payment.py | 31 +++++++++++++++++-------------- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/capsulflask/console.py b/capsulflask/console.py index 0b2e89d..2b74875 100644 --- a/capsulflask/console.py +++ b/capsulflask/console.py @@ -15,6 +15,7 @@ from nanoid import generate from capsulflask.metrics import durations as metric_durations from capsulflask.auth import account_required from capsulflask.db import get_model, my_exec_info_message +from capsulflask.payment import poll_btcpay_session from capsulflask import cli bp = Blueprint("console", __name__, url_prefix="/console") @@ -277,6 +278,12 @@ def get_account_balance(vms, payments, as_of): @bp.route("/account-balance") @account_required def account_balance(): + + payment_sessions = get_model().list_payment_sessions_for_account(session['account']) + for payment_session in payment_sessions: + if payment_session['type'] == 'btcpay': + poll_btcpay_session(payment_session['id']) + payments = get_payments() vms = get_vms() balance_1w = get_account_balance(vms, payments, datetime.utcnow() + timedelta(days=7)) diff --git a/capsulflask/db_model.py b/capsulflask/db_model.py index 02a6249..57c86a0 100644 --- a/capsulflask/db_model.py +++ b/capsulflask/db_model.py @@ -164,6 +164,17 @@ class DBModel: ) self.connection.commit() + def list_payment_sessions_for_account(self, email): + self.cursor.execute(""" + SELECT id, type, dollars, created + FROM payment_sessions WHERE email = %s""", + (email, ) + ) + return list(map( + lambda x: dict(id=x[0], type=x[1], dollars=x[2], created=x[3]), + self.cursor.fetchall() + )) + def consume_payment_session(self, payment_type, id, dollars): self.cursor.execute("SELECT email, dollars FROM payment_sessions WHERE id = %s AND type = %s", (id, payment_type)) row = self.cursor.fetchone() diff --git a/capsulflask/payment.py b/capsulflask/payment.py index c3eea4f..8bbb433 100644 --- a/capsulflask/payment.py +++ b/capsulflask/payment.py @@ -77,23 +77,12 @@ def btcpay_payment(): return render_template("btcpay.html", invoice_id=invoice_id) -@bp.route("/btcpay/webhook", methods=("POST",)) -def btcpay_webhook(): - - current_app.logger.info(f"got btcpay webhook") - - # IMPORTANT! there is no signature or credential for the data sent into this webhook :facepalm: - # its just a notification, thats all. - request_data = json.loads(request.data) - invoice_id = request_data['id'] - - current_app.logger.info(f"got btcpay webhook with invoice_id={invoice_id}") - +def poll_btcpay_session(invoice_id): # so you better make sure to get the invoice directly from the horses mouth! invoice = current_app.config['BTCPAY_CLIENT'].get_invoice(invoice_id) if invoice['currency'] != "USD": - abort(400, "invalid currency") + return [400, "invalid currency"] dollars = invoice['price'] @@ -110,7 +99,21 @@ def btcpay_webhook(): elif invoice['status'] == "expired" or invoice['status'] == "invalid": get_model().btcpay_invoice_resolved(invoice_id, False) - return {"msg": "ok"}, 200 + return [200, "ok"] + +@bp.route("/btcpay/webhook", methods=("POST",)) +def btcpay_webhook(): + + current_app.logger.info(f"got btcpay webhook") + + # IMPORTANT! there is no signature or credential for the data sent into this webhook :facepalm: + # its just a notification, thats all. + request_data = json.loads(request.data) + invoice_id = request_data['id'] + + result = poll_btcpay_session(invoice_id) + + abort(result[0], result[1])