BTCPay wired: store + shared wallet + webhook(secret-in-URL) + LAN->public link rewrite + idempotent settle; money-flow verified

This commit is contained in:
drjones
2026-10-01 22:40:17 -07:00
parent 7ea1064e3e
commit 0dffe11884
2 changed files with 7 additions and 2 deletions

View File

@@ -27,6 +27,7 @@
}, },
"btcpay": { "btcpay": {
"url": "https://btcpay.thetempleofdoom.com", "url": "https://btcpay.thetempleofdoom.com",
"api_url": "https://10.30.20.140",
"store_id": "SET_ME", "store_id": "SET_ME",
"api_key": "SET_ME", "api_key": "SET_ME",
"webhook_secret": "SET_ME" "webhook_secret": "SET_ME"

View File

@@ -559,7 +559,8 @@ def create_invoice(user, plan):
if not b.get("store_id"): if not b.get("store_id"):
return None, "Payments temporarily offline." return None, "Payments temporarily offline."
try: try:
r = http.post(f"{b['url']}/api/v1/stores/{b['store_id']}/invoices", api_host = b.get("api_url") or b["url"] # LAN IP for API calls (CF 1010)
r = http.post(f"{api_host}/api/v1/stores/{b['store_id']}/invoices",
headers={"Authorization": f"token {b['api_key']}"}, headers={"Authorization": f"token {b['api_key']}"},
json={"amount": str(p["usd"]), "currency": "USD", json={"amount": str(p["usd"]), "currency": "USD",
"metadata": {"userId": user["id"], "credits": p["credits"], "metadata": {"userId": user["id"], "credits": p["credits"],
@@ -568,6 +569,9 @@ def create_invoice(user, plan):
timeout=20, verify=False) timeout=20, verify=False)
r.raise_for_status() r.raise_for_status()
inv = r.json() inv = r.json()
link = inv.get("checkoutLink") or (inv.get("checkout") or {}).get("link") or ""
if link and link.startswith(api_host): # mirrors request Host -> rewrite
inv["checkoutLink"] = b["url"] + link[len(api_host):]
except Exception as e: except Exception as e:
return None, f"Invoice error: {e}" return None, f"Invoice error: {e}"
c = db() c = db()
@@ -589,7 +593,7 @@ def handle_webhook(body, header_sig_ok):
if not p: if not p:
c.close() c.close()
return True return True
if etype == "InvoiceSettled": if etype == "InvoiceSettled" and p["status"] != "settled": # idempotent: replays no-op
c.execute("UPDATE payments SET status='settled', settled_at=CURRENT_TIMESTAMP WHERE invoice_id=?", (invoice_id,)) c.execute("UPDATE payments SET status='settled', settled_at=CURRENT_TIMESTAMP WHERE invoice_id=?", (invoice_id,))
if p["amount_usd"] >= 50: # HOARD = $50/mo unlimited: 30 days from settle if p["amount_usd"] >= 50: # HOARD = $50/mo unlimited: 30 days from settle
import datetime import datetime