~forest/capsul-flask

e6021324f7711cf72db89a419370c7c88d485b47 — forest 19 days ago 2f60e27 master
fix exceptions related to btcpay HTTP calls. better cleanup of expired
btcpay invoices.
3 files changed, 32 insertions(+), 5 deletions(-)

M capsulflask/cli.py
M capsulflask/db_model.py
M capsulflask/payment.py
M capsulflask/cli.py => capsulflask/cli.py +12 -1
@@ 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


M capsulflask/db_model.py => capsulflask/db_model.py +4 -0
@@ 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()

M capsulflask/payment.py => capsulflask/payment.py +16 -4
@@ 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])