From e6021324f7711cf72db89a419370c7c88d485b47 Mon Sep 17 00:00:00 2001 From: forest Date: Sat, 18 Jul 2020 10:16:17 -0500 Subject: [PATCH] fix exceptions related to btcpay HTTP calls. better cleanup of expired btcpay invoices. --- capsulflask/cli.py | 13 ++++++++++++- capsulflask/db_model.py | 4 ++++ capsulflask/payment.py | 20 ++++++++++++++++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/capsulflask/cli.py b/capsulflask/cli.py index 2bad017..1962b01 100644 --- a/capsulflask/cli.py +++ b/capsulflask/cli.py @@ -1,6 +1,7 @@ import os import re +import sys from datetime import datetime, timedelta import click @@ -86,7 +87,16 @@ def clean_up_unresolved_btcpay_invoices(): unresolved_btcpay_invoices = get_model().get_unresolved_btcpay_invoices() for unresolved_invoice in unresolved_btcpay_invoices: invoice_id = unresolved_invoice['id'] - btcpay_invoice = current_app.config['BTCPAY_CLIENT'].get_invoice(invoice_id) + btcpay_invoice = None + try: + btcpay_invoice = current_app.config['BTCPAY_CLIENT'].get_invoice(invoice_id) + except: + current_app.logger.error(f""" + error was thrown when contacting btcpay server for invoice {invoice_id}: + {my_exec_info_message(sys.exc_info())}""" + ) + continue + days = float((datetime.now() - unresolved_invoice['created']).total_seconds())/float(60*60*24) if btcpay_invoice['status'] == "complete": @@ -102,6 +112,7 @@ def clean_up_unresolved_btcpay_invoices(): f"btcpay server invoice status: {btcpay_invoice['status']}" ) get_model().btcpay_invoice_resolved(invoice_id, False) + get_model().delete_payment_session("btcpay", invoice_id) delete_at_account_balance_dollars = -10 diff --git a/capsulflask/db_model.py b/capsulflask/db_model.py index 2f793fb..9017977 100644 --- a/capsulflask/db_model.py +++ b/capsulflask/db_model.py @@ -218,6 +218,10 @@ class DBModel: else: return None + def delete_payment_session(self, payment_type, id): + self.cursor.execute( "DELETE FROM payment_sessions WHERE id = %s AND type = %s", (id, payment_type) ) + self.connection.commit() + def btcpay_invoice_resolved(self, id, completed): self.cursor.execute("SELECT email, payment_id FROM unresolved_btcpay_invoices WHERE id = %s ", (id,)) row = self.cursor.fetchone() diff --git a/capsulflask/payment.py b/capsulflask/payment.py index feed458..1ec147f 100644 --- a/capsulflask/payment.py +++ b/capsulflask/payment.py @@ -3,6 +3,7 @@ import json import time import decimal import re +import sys from time import sleep from flask import Blueprint @@ -19,7 +20,7 @@ from werkzeug.exceptions import abort from capsulflask.auth import account_required -from capsulflask.db import get_model +from capsulflask.db import get_model, my_exec_info_message bp = Blueprint("payment", __name__, url_prefix="/payment") @@ -80,15 +81,24 @@ def btcpay_payment(): 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) + + invoice = None + try: + invoice = current_app.config['BTCPAY_CLIENT'].get_invoice(invoice_id) + except: + current_app.logger.error(f""" + error was thrown when contacting btcpay server: + {my_exec_info_message(sys.exc_info())}""" + ) + return [503, "error was thrown when contacting btcpay server"] + if invoice['currency'] != "USD": return [400, "invalid currency"] dollars = invoice['price'] - current_app.logger.info(f"got btcpay webhook with invoice_id={invoice_id}, status={invoice['status']} dollars={dollars}") + current_app.logger.info(f"poll_btcpay_session invoice_id={invoice_id}, status={invoice['status']} dollars={dollars}") if invoice['status'] == "paid" or invoice['status'] == "confirmed" or invoice['status'] == "complete": success_account = get_model().consume_payment_session("btcpay", invoice_id, dollars) @@ -100,6 +110,7 @@ def poll_btcpay_session(invoice_id): get_model().btcpay_invoice_resolved(invoice_id, True) elif invoice['status'] == "expired" or invoice['status'] == "invalid": get_model().btcpay_invoice_resolved(invoice_id, False) + get_model().delete_payment_session("btcpay", invoice_id) return [200, "ok"] @@ -113,6 +124,7 @@ def btcpay_webhook(): request_data = json.loads(request.data) invoice_id = request_data['id'] + # so you better make sure to get the invoice directly from the horses mouth! result = poll_btcpay_session(invoice_id) abort(result[0], result[1])