fix payment customer and dashboard settings
Build & Deploy / Build & Push Docker Image (push) Successful in 12m39s
Test / Type Check (all packages) (push) Successful in 5m8s
Build & Deploy / Deploy to VPS (push) Successful in 7s
Test / API Unit Tests (push) Failing after 4m24s
Test / Homepage Unit Tests (push) Successful in 3m27s
Test / Storefront Unit Tests (push) Successful in 4m48s
Test / Admin Unit Tests (push) Successful in 3m0s
Test / Dashboard Unit Tests (push) Successful in 4m18s
Test / API Integration Tests (push) Failing after 4m34s
Build & Deploy / Build & Push Docker Image (push) Successful in 12m39s
Test / Type Check (all packages) (push) Successful in 5m8s
Build & Deploy / Deploy to VPS (push) Successful in 7s
Test / API Unit Tests (push) Failing after 4m24s
Test / Homepage Unit Tests (push) Successful in 3m27s
Test / Storefront Unit Tests (push) Successful in 4m48s
Test / Admin Unit Tests (push) Successful in 3m0s
Test / Dashboard Unit Tests (push) Successful in 4m18s
Test / API Integration Tests (push) Failing after 4m34s
This commit is contained in:
@@ -19,7 +19,9 @@ async function applyAmanpayWebhook(event: any) {
|
||||
const payment = await repo.findByAmanpay(transactionId)
|
||||
if (payment && payment.status !== 'SUCCEEDED') {
|
||||
await repo.markPaymentSucceeded(payment.id)
|
||||
await repo.incrementReservationPaid(payment.reservationId, payment.amount)
|
||||
if (payment.type === 'CHARGE') {
|
||||
await repo.incrementReservationPaid(payment.reservationId, payment.amount)
|
||||
}
|
||||
}
|
||||
} else if (status === 'FAILED') {
|
||||
await repo.markPaymentFailed({ amanpayTransactionId: transactionId })
|
||||
@@ -33,7 +35,9 @@ async function applyPaypalWebhook(event: any) {
|
||||
const payment = await repo.findByPaypal(captureId)
|
||||
if (payment && payment.status !== 'SUCCEEDED') {
|
||||
await repo.markPaymentSucceeded(payment.id)
|
||||
await repo.incrementReservationPaid(payment.reservationId, payment.amount)
|
||||
if (payment.type === 'CHARGE') {
|
||||
await repo.incrementReservationPaid(payment.reservationId, payment.amount)
|
||||
}
|
||||
}
|
||||
} else if (eventType === 'PAYMENT.CAPTURE.DENIED') {
|
||||
await repo.markPaymentFailed({ paypalCaptureId: event.resource?.id })
|
||||
@@ -65,9 +69,23 @@ export async function initCharge(reservationId: string, companyId: string, body:
|
||||
currency: 'MAD'; successUrl: string; failureUrl: string
|
||||
}) {
|
||||
const reservation = await repo.findReservationOrThrow(reservationId, companyId)
|
||||
if (reservation.paymentStatus === 'PAID') throw new ConflictError('Reservation is already fully paid')
|
||||
const rentalPayments = (reservation as any).rentalPayments ?? []
|
||||
const invoicePaid = rentalPayments.reduce((total: number, payment: any) => {
|
||||
if (payment.type !== 'CHARGE' || payment.status !== 'SUCCEEDED') return total
|
||||
return total + payment.amount
|
||||
}, 0)
|
||||
const depositCollected = rentalPayments.reduce((total: number, payment: any) => {
|
||||
if (payment.type !== 'DEPOSIT' || payment.status !== 'SUCCEEDED') return total
|
||||
return total + payment.amount
|
||||
}, 0)
|
||||
const chargeRemaining = Math.max(reservation.totalAmount - invoicePaid, 0)
|
||||
const depositRemaining = Math.max(reservation.depositAmount - depositCollected, 0)
|
||||
const amount = body.type === 'DEPOSIT' ? depositRemaining : chargeRemaining
|
||||
|
||||
if (amount <= 0) {
|
||||
throw new ConflictError(body.type === 'DEPOSIT' ? 'Security deposit is already fully collected' : 'Reservation is already fully paid')
|
||||
}
|
||||
|
||||
const amount = body.type === 'DEPOSIT' ? reservation.depositAmount : reservation.totalAmount
|
||||
const description = `${body.type === 'DEPOSIT' ? 'Deposit' : 'Rental'}: ${reservation.vehicle.make} ${reservation.vehicle.model}`
|
||||
const orderId = `${reservationId}-${body.type}-${Date.now()}`
|
||||
const webhookBase = process.env.API_URL ?? 'http://localhost:4000'
|
||||
@@ -103,7 +121,9 @@ export async function capturePaypal(reservationId: string, companyId: string, pa
|
||||
const capture = await paypal.captureOrder(paypalOrderId) as Record<string, any>
|
||||
const captureId = capture.purchase_units?.[0]?.payments?.captures?.[0]?.id ?? paypalOrderId
|
||||
const updated = await repo.updatePaypalCapture(payment.id, captureId)
|
||||
await repo.incrementReservationPaid(payment.reservationId, payment.amount)
|
||||
if (payment.type === 'CHARGE') {
|
||||
await repo.incrementReservationPaid(payment.reservationId, payment.amount)
|
||||
}
|
||||
return updated
|
||||
}
|
||||
|
||||
@@ -111,13 +131,31 @@ export async function recordManualPayment(reservationId: string, companyId: stri
|
||||
amount: number; currency: string; type: string; paymentMethod: string
|
||||
}) {
|
||||
const reservation = await repo.findReservation(reservationId, companyId)
|
||||
const remaining = Math.max(reservation.totalAmount - reservation.paidAmount, 0)
|
||||
if (remaining <= 0) throw new ConflictError('Reservation is already fully paid')
|
||||
if (body.amount > remaining) throw new ValidationError('Payment amount exceeds remaining balance')
|
||||
const rentalPayments = (reservation as any).rentalPayments ?? []
|
||||
const invoicePaid = rentalPayments.reduce((total: number, payment: any) => {
|
||||
if (payment.type !== 'CHARGE' || payment.status !== 'SUCCEEDED') return total
|
||||
return total + payment.amount
|
||||
}, 0)
|
||||
const depositCollected = rentalPayments.reduce((total: number, payment: any) => {
|
||||
if (payment.type !== 'DEPOSIT' || payment.status !== 'SUCCEEDED') return total
|
||||
return total + payment.amount
|
||||
}, 0)
|
||||
const chargeRemaining = Math.max(reservation.totalAmount - invoicePaid, 0)
|
||||
const depositRemaining = Math.max(reservation.depositAmount - depositCollected, 0)
|
||||
const remaining = body.type === 'DEPOSIT' ? depositRemaining : chargeRemaining
|
||||
|
||||
const payment = await repo.createPayment({ companyId, reservationId, amount: body.amount, currency: body.currency, status: 'SUCCEEDED', type: body.type, paymentProvider: body.paymentMethod === 'PAYPAL' ? 'PAYPAL' : 'AMANPAY', paymentMethod: body.paymentMethod, paidAt: new Date() })
|
||||
const newPaidAmount = reservation.paidAmount + body.amount
|
||||
await repo.setReservationPaidAmount(reservationId, newPaidAmount, newPaidAmount >= reservation.totalAmount ? 'PAID' : 'PARTIAL')
|
||||
if (remaining <= 0) {
|
||||
throw new ConflictError(body.type === 'DEPOSIT' ? 'Security deposit is already fully collected' : 'Reservation is already fully paid')
|
||||
}
|
||||
if (body.amount > remaining) {
|
||||
throw new ValidationError(body.type === 'DEPOSIT' ? 'Payment amount exceeds deposit outstanding' : 'Payment amount exceeds remaining balance')
|
||||
}
|
||||
|
||||
const payment = await repo.createPayment({ companyId, reservationId, amount: body.amount, currency: body.currency, status: 'SUCCEEDED', type: body.type, paymentProvider: 'MANUAL', paymentMethod: body.paymentMethod, paidAt: new Date() })
|
||||
if (body.type === 'CHARGE') {
|
||||
const newPaidAmount = invoicePaid + body.amount
|
||||
await repo.setReservationPaidAmount(reservationId, newPaidAmount, newPaidAmount >= reservation.totalAmount ? 'PAID' : 'PARTIAL')
|
||||
}
|
||||
return payment
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user