improve BTCPay server down detection and handling

This commit is contained in:
forest 2022-02-22 14:04:38 -06:00
parent 2f9d941796
commit 32cb14f979
6 changed files with 52 additions and 20 deletions

View File

@ -19,7 +19,7 @@ from apscheduler.schedulers.background import BackgroundScheduler
from capsulflask.shared import my_exec_info_message from capsulflask.shared import my_exec_info_message
from capsulflask import hub_model, spoke_model, cli from capsulflask import hub_model, spoke_model, cli
from capsulflask.btcpay import client as btcpay from capsulflask.payment import try_reconnnect_btcpay
from capsulflask.http_client import MyHTTPClient from capsulflask.http_client import MyHTTPClient
class StdoutMockFlaskMail: class StdoutMockFlaskMail:
@ -142,17 +142,8 @@ else:
app.config['HTTP_CLIENT'] = MyHTTPClient(timeout_seconds=int(app.config['INTERNAL_HTTP_TIMEOUT_SECONDS'])) app.config['HTTP_CLIENT'] = MyHTTPClient(timeout_seconds=int(app.config['INTERNAL_HTTP_TIMEOUT_SECONDS']))
app.config['BTCPAY_ENABLED'] = False
if app.config['BTCPAY_URL'] != "": if app.config['BTCPAY_URL'] != "":
try: try_reconnnect_btcpay()
response = requests.get(app.config['BTCPAY_URL'])
if response.status_code == 200:
app.config['BTCPAY_CLIENT'] = btcpay.Client(api_uri=app.config['BTCPAY_URL'], pem=app.config['BTCPAY_PRIVATE_KEY'])
app.config['BTCPAY_ENABLED'] = True
else:
app.logger.warn(f"Can't reach BTCPAY_URL {app.config['BTCPAY_URL']}: Response status code: {response.status_code}. Capsul will work fine except cryptocurrency payments will not work.")
except:
app.logger.warn("unable to create btcpay client. Capsul will work fine except cryptocurrency payments will not work. The error was: " + my_exec_info_message(sys.exc_info()))
# only start the scheduler and attempt to migrate the database if we are running the app. # only start the scheduler and attempt to migrate the database if we are running the app.
# otherwise we are running a CLI command. # otherwise we are running a CLI command.

View File

@ -423,7 +423,8 @@ def account_balance():
has_vms=len(vms_billed)>0, has_vms=len(vms_billed)>0,
vms_billed=vms_billed, vms_billed=vms_billed,
warning_text=warning_text, warning_text=warning_text,
btcpay_enabled=current_app.config["BTCPAY_ENABLED"], btcpay_enabled=current_app.config["BTCPAY_URL"] != "",
btcpay_is_working="BTCPAY_CLIENT" in current_app.config,
payments=list(map( payments=list(map(
lambda x: dict( lambda x: dict(
dollars=x["dollars"], dollars=x["dollars"],

View File

@ -22,6 +22,7 @@ from werkzeug.exceptions import abort
from capsulflask.auth import account_required from capsulflask.auth import account_required
from capsulflask.db import get_model from capsulflask.db import get_model
from capsulflask.btcpay import client as btcpay
from capsulflask.shared import my_exec_info_message, get_account_balance, average_number_of_days_in_a_month from capsulflask.shared import my_exec_info_message, get_account_balance, average_number_of_days_in_a_month
bp = Blueprint("payment", __name__, url_prefix="/payment") bp = Blueprint("payment", __name__, url_prefix="/payment")
@ -53,9 +54,13 @@ def validate_dollars(min: float, max: float):
def btcpay_payment(): def btcpay_payment():
errors = list() errors = list()
if not current_app.config['BTCPAY_ENABLED']: if current_app.config['BTCPAY_URL'] == "":
flash("BTCPay is not enabled on this server") flash("BTCPay is not enabled on this server")
return redirect(url_for("console.account_balance")) return redirect(url_for("console.account_balance"))
elif 'BTCPAY_CLIENT' not in current_app.config:
if not try_reconnnect_btcpay():
flash("can't contact the BTCPay server right now")
return redirect(url_for("console.account_balance"))
if request.method == "POST": if request.method == "POST":
dollars, errors = validate_dollars(0.01, 1000.0) dollars, errors = validate_dollars(0.01, 1000.0)
@ -93,7 +98,11 @@ def btcpay_payment():
def poll_btcpay_session(invoice_id): def poll_btcpay_session(invoice_id):
if 'BTCPAY_CLIENT' not in current_app.config:
if not try_reconnnect_btcpay():
return [503, "can't contact btcpay server"]
invoice = None invoice = None
try: try:
invoice = current_app.config['BTCPAY_CLIENT'].get_invoice(invoice_id) invoice = current_app.config['BTCPAY_CLIENT'].get_invoice(invoice_id)
@ -130,6 +139,20 @@ def poll_btcpay_session(invoice_id):
return [200, "ok"] return [200, "ok"]
def try_reconnnect_btcpay():
try:
response = requests.get(current_app.config['BTCPAY_URL'])
if response.status_code == 200:
current_app.config['BTCPAY_CLIENT'] = btcpay.Client(api_uri=current_app.config['BTCPAY_URL'], pem=current_app.config['BTCPAY_PRIVATE_KEY'])
return True
else:
current_app.logger.warn(f"Can't reach BTCPAY_URL {current_app.config['BTCPAY_URL']}: Response status code: {response.status_code}. Capsul will work fine except cryptocurrency payments will not work.")
return False
except:
current_app.logger.warn("unable to create btcpay client. Capsul will work fine except cryptocurrency payments will not work. The error was: " + my_exec_info_message(sys.exc_info()))
return False
@bp.route("/btcpay/webhook", methods=("POST",)) @bp.route("/btcpay/webhook", methods=("POST",))
def btcpay_webhook(): def btcpay_webhook():

View File

@ -50,6 +50,19 @@ a:hover, a:active, a:visited {
border-color: rgb(8, 173, 137); border-color: rgb(8, 173, 137);
} }
.error {
color: rgb(173, 74, 8);
font-weight: bold;
border: 1px dashed rgb(173, 74, 8);
border-radius: 0.5em;
padding: 1em;
}
.disabled {
color: #585a5c;
}
.display-none { .display-none {
display: none; display: none;
} }

View File

@ -47,7 +47,15 @@
<ul><li>notice: stripe will load nonfree javascript </li></ul> <ul><li>notice: stripe will load nonfree javascript </li></ul>
</li> </li>
{% if btcpay_enabled %} {% if btcpay_enabled %}
<li><a href="/payment/btcpay">Add funds with Bitcoin/Litecoin/Monero (btcpay)</a></li> {% if btcpay_is_working %}
<li><a href="/payment/btcpay">Add funds with Bitcoin/Litecoin/Monero (btcpay)</a></li>
{% else %}
<li>
<span class="disabled">Add funds with Bitcoin/Litecoin/Monero (btcpay)</span>
<span class="error"> ERROR: the BTCPay server cannot be reached</span>
</li>
{% endif %}
{% endif %} {% endif %}
<li>Cash: email <a href="mailto:treasurer@cyberia.club">treasurer@cyberia.club</a></li> <li>Cash: email <a href="mailto:treasurer@cyberia.club">treasurer@cyberia.club</a></li>

View File

@ -20,11 +20,7 @@
type="text" type="text"
/> />
</span> </span>
<input type="submit" value="Pay with BtcPay"></button> <input type="submit" value="Pay with BtcPay"></input>
</div>
<div class="row">
<div>
<p>Our BTCPay Server instance is finally back online 🥳</p>
</div> </div>
</form> </form>
</div> </div>