Render or poll invoice status

This commit is contained in:
ekzyis 2023-09-09 22:52:51 +02:00
parent b2c7f28200
commit a01d4488cc
3 changed files with 56 additions and 24 deletions

View File

@ -39,9 +39,9 @@
</code> </code>
<div class="font-mono mb-1"> <div class="font-mono mb-1">
<div class="mb-1">Payment Required</div> <div class="mb-1">Payment Required</div>
<div id="paid" class="yes" hidden> <div id="status" hidden>
<div>Paid</div> <div id="status-label"></div>
<div id="countdown">Redirecting in 3 ...</div> <div id="countdown" hidden>Redirecting in 3 ...</div>
</div> </div>
</div> </div>
<div id="qr"> <div id="qr">
@ -60,28 +60,54 @@
</div> </div>
</div> </div>
</body> </body>
{{ if .RedirectAfterPayment }}
<script> <script>
const invoiceId = "{{.Invoice.Id}}" const statusElement = document.querySelector("#status")
const paid = document.querySelector("#paid") const label = document.querySelector("#status-label")
const countdown = document.querySelector("#countdown") const status = "{{.Status}}"
const interval = setInterval(async () => { const redirectUrl = "{{.RedirectURL}}"
const body = await fetch(`/api/invoice/${invoiceId}`) function poll() {
.then((r) => r.json()) const invoiceId = "{{.Invoice.Id}}"
.catch(console.error) const countdown = document.querySelector("#countdown")
if (body.ConfirmedAt) { const redirect = () => {
paid.removeAttribute("hidden")
clearInterval(interval) clearInterval(interval)
countdown.removeAttribute("hidden")
let timer = 2 let timer = 2
const redirect = setInterval(() => { const redirect = setInterval(() => {
countdown.textContent = `Redirecting in ${timer--} ...` countdown.textContent = `Redirecting in ${timer--} ...`
if (timer === -1) { if (timer === -1) {
window.location.href = "https://{{.PUBLIC_URL}}/market/{{.MarketId}}"; window.location.href = redirectURL;
} }
}, 1000) }, 1000)
} }
}, 1000) const interval = setInterval(async () => {
const body = await fetch(`/api/invoice/${invoiceId}`)
.then((r) => r.json())
.catch(console.error)
if (body.ConfirmedAt) {
statusElement.removeAttribute("hidden")
statusElement.classList.add("yes")
label.textContent = "Paid"
if (redirectURL) redirect()
} else if (new Date(body.ExpiresAt) <= new Date()) {
statusElement.removeAttribute("hidden")
statusElement.classList.add("no")
label.textContent = "Expired"
if (redirectURL) redirect()
}
}, 1000)
}
if (status) {
console.log(status)
statusElement.removeAttribute("hidden")
label.textContent = status
if (status === "Paid") {
statusElement.classList.add("yes")
}
else if (status === "Expired") {
statusElement.classList.add("no")
}
}
else poll()
</script> </script>
{{ end }}
</html> </html>

View File

@ -118,9 +118,16 @@ func invoice(c echo.Context) error {
if err != nil { if err != nil {
return err return err
} }
status := ""
if invoice.ConfirmedAt.Valid {
status = "Paid"
} else if time.Now().After(invoice.ExpiresAt) {
status = "Expired"
}
data := map[string]any{ data := map[string]any{
"session": c.Get("session"), "session": c.Get("session"),
"Invoice": invoice, "Invoice": invoice,
"Status": status,
"lnurl": invoice.PaymentRequest, "lnurl": invoice.PaymentRequest,
"qr": qr, "qr": qr,
} }

View File

@ -2,6 +2,7 @@ package main
import ( import (
"database/sql" "database/sql"
"fmt"
"math" "math"
"net/http" "net/http"
"strconv" "strconv"
@ -91,14 +92,12 @@ func order(c echo.Context) error {
} }
go lnd.CheckInvoice(invoice.PaymentHash) go lnd.CheckInvoice(invoice.PaymentHash)
data := map[string]any{ data := map[string]any{
"session": c.Get("session"), "session": c.Get("session"),
"ENV": ENV, "ENV": ENV,
"lnurl": invoice.PaymentRequest, "lnurl": invoice.PaymentRequest,
"qr": qr, "qr": qr,
"Invoice": invoice, "Invoice": invoice,
"RedirectAfterPayment": true, "RedirectURL": fmt.Sprintf("https://%s/market/%s", PUBLIC_URL, marketId),
"PUBLIC_URL": PUBLIC_URL,
"MarketId": marketId,
} }
return c.Render(http.StatusPaymentRequired, "invoice.html", data) return c.Render(http.StatusPaymentRequired, "invoice.html", data)
// Step 2: After payment, confirm order if no matching order was found // Step 2: After payment, confirm order if no matching order was found