Adds manual payment request functionality
Enables users to request manual payments from the Castle and provides admin functions to approve or reject these requests. Introduces the `manual_payment_requests` table and related CRUD operations. Adds API endpoints for creating, retrieving, approving, and rejecting manual payment requests. Updates the UI to allow users to request payments and for admins to review pending requests.
This commit is contained in:
parent
3a26d963dc
commit
c2d9b39f29
5 changed files with 520 additions and 11 deletions
|
|
@ -57,7 +57,14 @@ window.app = Vue.createApp({
|
|||
reference: '',
|
||||
currency: null,
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
manualPaymentDialog: {
|
||||
show: false,
|
||||
amount: null,
|
||||
description: '',
|
||||
loading: false
|
||||
},
|
||||
manualPaymentRequests: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -104,6 +111,9 @@ window.app = Vue.createApp({
|
|||
})
|
||||
})
|
||||
return options
|
||||
},
|
||||
pendingManualPaymentRequests() {
|
||||
return this.manualPaymentRequests.filter(r => r.status === 'pending')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -422,13 +432,101 @@ window.app = Vue.createApp({
|
|||
}, 2000)
|
||||
},
|
||||
showManualPaymentOption() {
|
||||
// TODO: Show manual payment request dialog
|
||||
// This is for when user wants to pay their debt manually
|
||||
// For now, just notify them to contact castle
|
||||
this.$q.notify({
|
||||
type: 'info',
|
||||
message: 'Manual payment feature coming soon!',
|
||||
message: 'Please contact Castle directly to arrange manual payment.',
|
||||
timeout: 3000
|
||||
})
|
||||
},
|
||||
showManualPaymentDialog() {
|
||||
// This is for when Castle owes user and they want to request manual payment
|
||||
this.manualPaymentDialog.amount = Math.abs(this.balance.balance)
|
||||
this.manualPaymentDialog.description = ''
|
||||
this.manualPaymentDialog.show = true
|
||||
},
|
||||
async submitManualPaymentRequest() {
|
||||
this.manualPaymentDialog.loading = true
|
||||
try {
|
||||
await LNbits.api.request(
|
||||
'POST',
|
||||
'/castle/api/v1/manual-payment-request',
|
||||
this.g.user.wallets[0].inkey,
|
||||
{
|
||||
amount: this.manualPaymentDialog.amount,
|
||||
description: this.manualPaymentDialog.description
|
||||
}
|
||||
)
|
||||
this.$q.notify({
|
||||
type: 'positive',
|
||||
message: 'Manual payment request submitted successfully!'
|
||||
})
|
||||
this.manualPaymentDialog.show = false
|
||||
this.manualPaymentDialog.amount = null
|
||||
this.manualPaymentDialog.description = ''
|
||||
await this.loadManualPaymentRequests()
|
||||
} catch (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
} finally {
|
||||
this.manualPaymentDialog.loading = false
|
||||
}
|
||||
},
|
||||
async loadManualPaymentRequests() {
|
||||
try {
|
||||
// If super user, load all requests; otherwise load user's own requests
|
||||
const endpoint = this.isSuperUser
|
||||
? '/castle/api/v1/manual-payment-requests/all'
|
||||
: '/castle/api/v1/manual-payment-requests'
|
||||
const key = this.isSuperUser
|
||||
? this.g.user.wallets[0].adminkey
|
||||
: this.g.user.wallets[0].inkey
|
||||
|
||||
const response = await LNbits.api.request(
|
||||
'GET',
|
||||
endpoint,
|
||||
key,
|
||||
this.isSuperUser ? {status: 'pending'} : {}
|
||||
)
|
||||
this.manualPaymentRequests = response.data
|
||||
} catch (error) {
|
||||
console.error('Error loading manual payment requests:', error)
|
||||
}
|
||||
},
|
||||
async approveManualPaymentRequest(requestId) {
|
||||
try {
|
||||
await LNbits.api.request(
|
||||
'POST',
|
||||
`/castle/api/v1/manual-payment-requests/${requestId}/approve`,
|
||||
this.g.user.wallets[0].adminkey
|
||||
)
|
||||
this.$q.notify({
|
||||
type: 'positive',
|
||||
message: 'Manual payment request approved!'
|
||||
})
|
||||
await this.loadManualPaymentRequests()
|
||||
await this.loadBalance()
|
||||
await this.loadTransactions()
|
||||
} catch (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
}
|
||||
},
|
||||
async rejectManualPaymentRequest(requestId) {
|
||||
try {
|
||||
await LNbits.api.request(
|
||||
'POST',
|
||||
`/castle/api/v1/manual-payment-requests/${requestId}/reject`,
|
||||
this.g.user.wallets[0].adminkey
|
||||
)
|
||||
this.$q.notify({
|
||||
type: 'warning',
|
||||
message: 'Manual payment request rejected'
|
||||
})
|
||||
await this.loadManualPaymentRequests()
|
||||
} catch (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
}
|
||||
},
|
||||
copyToClipboard(text) {
|
||||
navigator.clipboard.writeText(text)
|
||||
this.$q.notify({
|
||||
|
|
@ -558,6 +656,7 @@ window.app = Vue.createApp({
|
|||
await this.loadTransactions()
|
||||
await this.loadAccounts()
|
||||
await this.loadCurrencies()
|
||||
await this.loadManualPaymentRequests()
|
||||
// Load users if super user (for receivable dialog)
|
||||
if (this.isSuperUser) {
|
||||
await this.loadUsers()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue