From 236d75653c746025a63d43c84650fee924619abb Mon Sep 17 00:00:00 2001
From: Jvery
Date: Wed, 9 Apr 2025 14:27:51 +0300
Subject: [PATCH 1/6] Enhance TabbedCheckout component to handle underpaid
invoices and improve status display logic. Added computed property for
display status and updated UI to reflect changes in invoice status, including
new messaging for underpaid and waiting confirmation states.
---
components/TabbedCheckout.vue | 28 +++++------
pages/i/_id.vue | 94 ++++++++++++++++++++++-------------
2 files changed, 73 insertions(+), 49 deletions(-)
diff --git a/components/TabbedCheckout.vue b/components/TabbedCheckout.vue
index 0ef44c4..48d4bf8 100644
--- a/components/TabbedCheckout.vue
+++ b/components/TabbedCheckout.vue
@@ -54,6 +54,8 @@
{{
expiringSoon
? "Invoice expiring soon..."
+ : underpaid
+ ? "Invoice underpaid..."
: "Awaiting payment..."
}}
@@ -475,20 +477,14 @@
-
Amount
-
- {{ itemv.amount }}
- {{ itemv.symbol.toUpperCase() }}
-
+
+
+
{{ itemv.symbol.toUpperCase() }}
+
- {{ texts[status].icon }}
+ {{ texts[displayStatus].icon }}
- {{ texts[status].text }}
+ {{ texts[displayStatus].text }}
@@ -79,7 +76,7 @@ export default {
showSnackbar: false,
showPartial: false,
showDialog: true,
- status: "pending",
+ redirected: false,
invoice: {},
store: {},
loading: true,
@@ -93,13 +90,21 @@ export default {
icon: "mdi-close",
text: "This invoice has been marked as invalid",
},
- paid: {
- icon: "mdi-check",
- text: "This invoice has been paid",
+ waiting_confirmation: {
+ icon: "mdi-clock-outline",
+ text: "Payment received, awaiting confirmation...",
+ },
+ underpaid: {
+ icon: "mdi-alert-circle-outline",
+ text: "Invoice underpaid. Please send the remaining amount.",
+ },
+ pending: {
+ icon: "",
+ text: "Awaiting payment...",
},
confirmed: {
icon: "mdi-check",
- text: "This invoice has been paid",
+ text: "Payment received, awaiting confirmations...",
},
complete: {
icon: "mdi-check",
@@ -121,12 +126,29 @@ export default {
hasEthPaymentMethod() {
return (
this.selectedPaymentMethod?.payment_url?.startsWith("ethereum:") &&
- this.status === "pending"
+ this.displayStatus === "pending"
)
},
poweredByStyle() {
return this.$route.query.modal ? { "white--text": true } : {}
},
+ displayStatus() {
+ if (!this.invoice || !this.invoice.status) return 'pending'
+ if (this.invoice.status === 'pending' && this.invoice.exception_status === 'paid_partial') return 'underpaid'
+ if (this.invoice.status === 'paid') return 'waiting_confirmation'
+ return this.invoice.status
+ },
+ isFinalStatus() {
+ return ['complete', 'expired', 'invalid', 'refunded'].includes(this.displayStatus)
+ }
+ },
+ watch: {
+ displayStatus(newStatus) {
+ if (!this.redirected && this.isFinalStatus && this.invoice.redirect_url) {
+ this.redirected = true
+ this.$utils.redirectTo(this.invoice.redirect_url)
+ }
+ }
},
beforeCreate() {
this.$vuetify.theme.dark = false // dark theme unsupported here
@@ -136,7 +158,6 @@ export default {
.get(`/invoices/${this.$route.params.id}`)
.then((resp) => {
this.invoice = resp.data
- this.status = resp.data.status
window.parent.postMessage("loaded", "*")
this.$axios
.get(`/stores/${resp.data.store_id}`)
@@ -177,24 +198,30 @@ export default {
this.websocket = new WebSocket(url)
this.websocket.onmessage = (event) => {
const data = JSON.parse(event.data)
- const status = data.status
- if (
- status === "pending" &&
- this.invoice.sent_amount !== data.sent_amount
- ) {
- // received partial payment
- this.invoice.exception_status = data.exception_status
- this.invoice.sent_amount = data.sent_amount
- this.invoice.paid_currency = data.paid_currency
- this.invoice.payment_id = data.payment_id
+ const oldStatus = this.invoice.status
+ const oldSentAmount = this.invoice.sent_amount
+
+ // Update invoice data
+ this.invoice.status = data.status
+ this.invoice.exception_status = data.exception_status
+ this.invoice.sent_amount = data.sent_amount
+ this.invoice.paid_currency = data.paid_currency
+ this.invoice.payment_id = data.payment_id
+
+ // Show partial payment notification if needed
+ if (data.status === 'pending' &&
+ data.exception_status === 'paid_partial' &&
+ oldSentAmount !== data.sent_amount) {
this.$bus.$emit("showDetails")
this.showPartial = true
}
- if (this.invoice.status !== status) {
+
+ // Notify parent window of status change
+ if (oldStatus !== data.status) {
window.parent.postMessage(
{
invoice_id: this.invoice.id,
- status,
+ status: data.status,
exception_status: data.exception_status,
sent_amount: data.sent_amount,
paid_currency: data.paid_currency,
@@ -203,13 +230,6 @@ export default {
"*"
)
}
- if (
- ["paid", "confirmed", "complete"].includes(status) &&
- this.invoice.redirect_url
- ) {
- this.$utils.redirectTo(this.invoice.redirect_url)
- }
- this.status = status
}
},
colorClass(icon) {
@@ -226,6 +246,10 @@ export default {
? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "")
: baseURL
},
+ getIconColor(icon) {
+ if (["mdi-check", "mdi-cash-refund"].includes(icon)) return "green"
+ return "red"
+ },
},
}
From 66a3fb049fe4c64e3cafe228ec72bdc589646e24 Mon Sep 17 00:00:00 2001
From: Jvery
Date: Wed, 9 Apr 2025 15:53:08 +0300
Subject: [PATCH 2/6] Update TabbedCheckout component to display currency
symbol in amount title and change invoice status from 'waiting_confirmation'
to 'confirmed'.
---
components/TabbedCheckout.vue | 3 +--
pages/i/_id.vue | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/components/TabbedCheckout.vue b/components/TabbedCheckout.vue
index 48d4bf8..2166b1b 100644
--- a/components/TabbedCheckout.vue
+++ b/components/TabbedCheckout.vue
@@ -479,11 +479,10 @@
-
{{ itemv.symbol.toUpperCase() }}
diff --git a/pages/i/_id.vue b/pages/i/_id.vue
index 1ebc067..4b63c2a 100644
--- a/pages/i/_id.vue
+++ b/pages/i/_id.vue
@@ -135,7 +135,7 @@ export default {
displayStatus() {
if (!this.invoice || !this.invoice.status) return 'pending'
if (this.invoice.status === 'pending' && this.invoice.exception_status === 'paid_partial') return 'underpaid'
- if (this.invoice.status === 'paid') return 'waiting_confirmation'
+ if (this.invoice.status === 'paid') return 'confirmed'
return this.invoice.status
},
isFinalStatus() {
From 000d016e09d169b3af2c7fd45f9a48e3947481b6 Mon Sep 17 00:00:00 2001
From: Jvery
Date: Wed, 9 Apr 2025 16:09:37 +0300
Subject: [PATCH 3/6] Enhance success circle UI in _id.vue with confirming
state animation. Added rotation animation for confirming status and updated
class binding for visual feedback.
---
pages/i/_id.vue | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/pages/i/_id.vue b/pages/i/_id.vue
index 4b63c2a..b63252f 100644
--- a/pages/i/_id.vue
+++ b/pages/i/_id.vue
@@ -38,7 +38,7 @@
Date: Wed, 9 Apr 2025 16:23:33 +0300
Subject: [PATCH 4/6] Refactor icon display logic in _id.vue to conditionally
render based on displayStatus. Introduced new .icon-static class for improved
styling and layout consistency.
---
pages/i/_id.vue | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/pages/i/_id.vue b/pages/i/_id.vue
index b63252f..b098f4d 100644
--- a/pages/i/_id.vue
+++ b/pages/i/_id.vue
@@ -42,8 +42,9 @@
class="d-flex justify-center success-circle success-icon"
>
{{ texts[displayStatus].icon }}
@@ -334,6 +335,14 @@ $dialog-max-height: 100%;
border-width: 2px;
border-style: solid;
position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.icon-static {
+ position: relative;
+ z-index: 1;
}
.success-circle.confirming {
From f27900173e1a001c9af74c13a67585999e52cb7d Mon Sep 17 00:00:00 2001
From: Jvery
Date: Tue, 6 Jan 2026 18:30:03 +0200
Subject: [PATCH 5/6] Fix status mapping and border color inheritance in
invoice page
- Change displayStatus to return 'waiting_confirmation' for 'paid' status
- Update animation condition to check for 'waiting_confirmation'
- Add border-color: currentColor for proper color inheritance from Vuetify classes
---
pages/i/_id.vue | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/pages/i/_id.vue b/pages/i/_id.vue
index b098f4d..5a9b320 100644
--- a/pages/i/_id.vue
+++ b/pages/i/_id.vue
@@ -38,11 +38,11 @@
@@ -136,7 +136,7 @@ export default {
displayStatus() {
if (!this.invoice || !this.invoice.status) return 'pending'
if (this.invoice.status === 'pending' && this.invoice.exception_status === 'paid_partial') return 'underpaid'
- if (this.invoice.status === 'paid') return 'confirmed'
+ if (this.invoice.status === 'paid') return 'waiting_confirmation'
return this.invoice.status
},
isFinalStatus() {
@@ -334,6 +334,7 @@ $dialog-max-height: 100%;
margin: 0 auto;
border-width: 2px;
border-style: solid;
+ border-color: currentColor;
position: relative;
display: flex;
align-items: center;
From 7363a7e0e42ded892c35e45afd954e426b26639d Mon Sep 17 00:00:00 2001
From: Jvery
Date: Tue, 6 Jan 2026 22:05:56 +0200
Subject: [PATCH 6/6] Show waiting confirmation screen when invoice is paid
---
pages/i/_id.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pages/i/_id.vue b/pages/i/_id.vue
index 5a9b320..58f64b2 100644
--- a/pages/i/_id.vue
+++ b/pages/i/_id.vue
@@ -26,7 +26,7 @@