171 lines
3.9 KiB
TypeScript
171 lines
3.9 KiB
TypeScript
// stores/payment.ts
|
|
import { defineStore } from 'pinia'
|
|
|
|
// Define a type for the store's state
|
|
export interface PaymentState {
|
|
payment: {
|
|
id: string | null
|
|
amount: number
|
|
description: string
|
|
patientName: string
|
|
qrCode: string
|
|
status: 'pending' | 'success' | 'failed' | 'expired'
|
|
expiryTime: string | null
|
|
}
|
|
loket: {
|
|
id: number | null
|
|
name: string
|
|
ipAddress: string
|
|
location: string
|
|
isActive: boolean
|
|
}
|
|
loading: boolean
|
|
error: string | null
|
|
}
|
|
|
|
export const usePaymentStore = defineStore('payment', {
|
|
state: (): PaymentState => ({
|
|
payment: {
|
|
id: null,
|
|
amount: 0,
|
|
description: '',
|
|
patientName: '',
|
|
qrCode: '',
|
|
status: 'pending',
|
|
expiryTime: null,
|
|
},
|
|
loket: {
|
|
id: null,
|
|
name: '',
|
|
ipAddress: '',
|
|
location: '',
|
|
isActive: false,
|
|
},
|
|
loading: false,
|
|
error: null,
|
|
}),
|
|
|
|
getters: {
|
|
isSystemReady: (state) => {
|
|
return state.loket.id && state.loket.isActive
|
|
},
|
|
paymentExpired: (state) => {
|
|
if (!state.payment.expiryTime) return false
|
|
return new Date() > new Date(state.payment.expiryTime)
|
|
},
|
|
},
|
|
|
|
actions: {
|
|
setLoading(loading: boolean) {
|
|
this.loading = loading
|
|
},
|
|
|
|
setError(error: string | null) {
|
|
this.error = error
|
|
},
|
|
|
|
clearError() {
|
|
this.error = null
|
|
},
|
|
|
|
setPaymentData(data: Partial<PaymentState['payment']>) {
|
|
this.payment = { ...this.payment, ...data }
|
|
},
|
|
|
|
setLoketInfo(data: Partial<PaymentState['loket']>) {
|
|
this.loket = { ...this.loket, ...data }
|
|
},
|
|
|
|
resetPayment() {
|
|
this.payment = {
|
|
id: null,
|
|
amount: 0,
|
|
description: '',
|
|
patientName: '',
|
|
qrCode: '',
|
|
status: 'pending',
|
|
expiryTime: null,
|
|
}
|
|
},
|
|
|
|
// Actions for API calls
|
|
async fetchLoketInfo() {
|
|
try {
|
|
this.setLoading(true)
|
|
this.clearError()
|
|
|
|
const { data } = await $fetch('/api/loket/info', {
|
|
headers: {
|
|
'X-Client-IP': await this.getClientIP(),
|
|
},
|
|
})
|
|
|
|
this.setLoketInfo(data)
|
|
return data
|
|
} catch (error: any) {
|
|
const errorMessage = error.data?.message || 'Gagal mengambil info loket'
|
|
this.setError(errorMessage)
|
|
throw error
|
|
} finally {
|
|
this.setLoading(false)
|
|
}
|
|
},
|
|
|
|
async generatePayment(paymentData: {
|
|
patient_name: string
|
|
amount: number
|
|
description: string
|
|
loket_id: number
|
|
loket_ip: string
|
|
}) {
|
|
try {
|
|
this.setLoading(true)
|
|
this.clearError()
|
|
|
|
const { data } = await $fetch('/api/payment/generate', {
|
|
method: 'POST',
|
|
body: paymentData,
|
|
headers: {
|
|
'X-Client-IP': await this.getClientIP(),
|
|
},
|
|
})
|
|
|
|
this.setPaymentData(data)
|
|
return data
|
|
} catch (error: any) {
|
|
const errorMessage = error.data?.message || 'Gagal generate pembayaran'
|
|
this.setError(errorMessage)
|
|
throw error
|
|
} finally {
|
|
this.setLoading(false)
|
|
}
|
|
},
|
|
|
|
async checkPaymentStatus(paymentId: string) {
|
|
try {
|
|
const { data } = await $fetch(`/api/payment/status/${paymentId}`)
|
|
this.setPaymentData({ status: data.status })
|
|
return data
|
|
} catch (error) {
|
|
console.error('Error checking payment status:', error)
|
|
throw error
|
|
}
|
|
},
|
|
|
|
// Helper method to get client IP
|
|
async getClientIP(): Promise<string> {
|
|
if (process.client) {
|
|
try {
|
|
const response = await fetch('https://api.ipify.org?format=json')
|
|
const data = await response.json()
|
|
return data.ip
|
|
} catch {
|
|
return window.location.hostname === 'localhost'
|
|
? '127.0.0.1'
|
|
: window.location.hostname
|
|
}
|
|
}
|
|
return 'server-side'
|
|
},
|
|
},
|
|
}) |