switch to polling for btcpay payment sessions because btcpay web hooks

are super duper slow
This commit is contained in:
forest 2020-05-16 22:04:51 -05:00
parent 155b0d579a
commit 2b04463e4e
3 changed files with 35 additions and 14 deletions

View File

@ -15,6 +15,7 @@ from nanoid import generate
from capsulflask.metrics import durations as metric_durations from capsulflask.metrics import durations as metric_durations
from capsulflask.auth import account_required from capsulflask.auth import account_required
from capsulflask.db import get_model, my_exec_info_message from capsulflask.db import get_model, my_exec_info_message
from capsulflask.payment import poll_btcpay_session
from capsulflask import cli from capsulflask import cli
bp = Blueprint("console", __name__, url_prefix="/console") bp = Blueprint("console", __name__, url_prefix="/console")
@ -277,6 +278,12 @@ def get_account_balance(vms, payments, as_of):
@bp.route("/account-balance") @bp.route("/account-balance")
@account_required @account_required
def account_balance(): 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() payments = get_payments()
vms = get_vms() vms = get_vms()
balance_1w = get_account_balance(vms, payments, datetime.utcnow() + timedelta(days=7)) balance_1w = get_account_balance(vms, payments, datetime.utcnow() + timedelta(days=7))

View File

@ -164,6 +164,17 @@ class DBModel:
) )
self.connection.commit() 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): 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)) self.cursor.execute("SELECT email, dollars FROM payment_sessions WHERE id = %s AND type = %s", (id, payment_type))
row = self.cursor.fetchone() row = self.cursor.fetchone()

View File

@ -77,23 +77,12 @@ def btcpay_payment():
return render_template("btcpay.html", invoice_id=invoice_id) return render_template("btcpay.html", invoice_id=invoice_id)
@bp.route("/btcpay/webhook", methods=("POST",)) def poll_btcpay_session(invoice_id):
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}")
# so you better make sure to get the invoice directly from the horses mouth! # 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 = current_app.config['BTCPAY_CLIENT'].get_invoice(invoice_id)
if invoice['currency'] != "USD": if invoice['currency'] != "USD":
abort(400, "invalid currency") return [400, "invalid currency"]
dollars = invoice['price'] dollars = invoice['price']
@ -110,7 +99,21 @@ def btcpay_webhook():
elif invoice['status'] == "expired" or invoice['status'] == "invalid": elif invoice['status'] == "expired" or invoice['status'] == "invalid":
get_model().btcpay_invoice_resolved(invoice_id, False) 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])