diff --git a/lnbits/extensions/withdraw/crud.py b/lnbits/extensions/withdraw/crud.py
index 18a057f3..9d55d245 100644
--- a/lnbits/extensions/withdraw/crud.py
+++ b/lnbits/extensions/withdraw/crud.py
@@ -25,9 +25,10 @@ async def create_withdraw_link(
unique_hash,
k1,
open_time,
- usescsv
+ usescsv,
+ webhook_url
)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
link_id,
@@ -42,6 +43,7 @@ async def create_withdraw_link(
urlsafe_short_hash(),
int(datetime.now().timestamp()) + data.wait_time,
usescsv,
+ data.webhook_url
),
)
link = await get_withdraw_link(link_id, 0)
diff --git a/lnbits/extensions/withdraw/lnurl.py b/lnbits/extensions/withdraw/lnurl.py
index 801fa62f..603e7dad 100644
--- a/lnbits/extensions/withdraw/lnurl.py
+++ b/lnbits/extensions/withdraw/lnurl.py
@@ -1,4 +1,7 @@
import json
+import traceback
+import httpx
+
from datetime import datetime
from http import HTTPStatus
@@ -103,17 +106,35 @@ async def api_lnurl_callback(
await update_withdraw_link(link.id, **changes)
payment_request = pr
-
- await pay_invoice(
+
+ payment_hash = await pay_invoice(
wallet_id=link.wallet,
payment_request=payment_request,
max_sat=link.max_withdrawable,
extra={"tag": "withdraw"},
)
+
+ if link.webhook_url:
+ async with httpx.AsyncClient() as client:
+ try:
+ r = await client.post(
+ link.webhook_url,
+ json={
+ "payment_hash": payment_hash,
+ "payment_request": payment_request,
+ "lnurlw": link.id,
+ },
+ timeout=40,
+ )
+ except Exception as exc:
+ # webhook fails shouldn't cause the lnurlw to fail since invoice is already paid
+ print("Caught exception when dispatching webhook url:", exc)
+
return {"status": "OK"}
except Exception as e:
await update_withdraw_link(link.id, **changesback)
+ print(traceback.format_exc())
return {"status": "ERROR", "reason": "Link not working"}
diff --git a/lnbits/extensions/withdraw/migrations.py b/lnbits/extensions/withdraw/migrations.py
index 1a13aa6d..5c527e79 100644
--- a/lnbits/extensions/withdraw/migrations.py
+++ b/lnbits/extensions/withdraw/migrations.py
@@ -108,3 +108,9 @@ async def m003_make_hash_check(db):
);
"""
)
+
+async def m004_webhook_url(db):
+ """
+ Adds webhook_url
+ """
+ await db.execute("ALTER TABLE withdraw.withdraw_link ADD COLUMN webhook_url TEXT;")
\ No newline at end of file
diff --git a/lnbits/extensions/withdraw/models.py b/lnbits/extensions/withdraw/models.py
index a03c7db8..c3ca7c45 100644
--- a/lnbits/extensions/withdraw/models.py
+++ b/lnbits/extensions/withdraw/models.py
@@ -15,6 +15,7 @@ class CreateWithdrawData(BaseModel):
uses: int = Query(..., ge=1)
wait_time: int = Query(..., ge=1)
is_unique: bool
+ webhook_url: str = Query(None)
class WithdrawLink(BaseModel):
@@ -32,6 +33,7 @@ class WithdrawLink(BaseModel):
used: int = Query(0)
usescsv: str = Query(None)
number: int = Query(0)
+ webhook_url: str = Query(None)
@property
def is_spent(self) -> bool:
diff --git a/lnbits/extensions/withdraw/static/js/index.js b/lnbits/extensions/withdraw/static/js/index.js
index 91ff6446..e54005c6 100644
--- a/lnbits/extensions/withdraw/static/js/index.js
+++ b/lnbits/extensions/withdraw/static/js/index.js
@@ -179,7 +179,8 @@ new Vue({
'max_withdrawable',
'uses',
'wait_time',
- 'is_unique'
+ 'is_unique',
+ 'webhook_url'
)
)
.then(function (response) {
diff --git a/lnbits/extensions/withdraw/templates/withdraw/_api_docs.html b/lnbits/extensions/withdraw/templates/withdraw/_api_docs.html
index c1172bcd..76068fcb 100644
--- a/lnbits/extensions/withdraw/templates/withdraw/_api_docs.html
+++ b/lnbits/extensions/withdraw/templates/withdraw/_api_docs.html
@@ -70,7 +70,8 @@
{"title": <string>, "min_withdrawable": <integer>,
"max_withdrawable": <integer>, "uses": <integer>,
- "wait_time": <integer>, "is_unique": <boolean>}