fix exceptions related to btcpay HTTP calls. better cleanup of expired
btcpay invoices.
This commit is contained in:
		@ -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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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()
 | 
			
		||||
 | 
			
		||||
@ -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])
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user