switch to polling for btcpay payment sessions because btcpay web hooks
are super duper slow
This commit is contained in:
		@ -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)) 
 | 
			
		||||
 | 
			
		||||
@ -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()
 | 
			
		||||
 | 
			
		||||
@ -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])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user