feat(billing): add PAYMENT_PROCESSING invoice status on payment success redirect (all except CBE bill)

This commit is contained in:
Marshal
2026-08-05 12:59:37 +00:00
parent 26837d5a7d
commit b7dcc1bf0a
20 changed files with 160 additions and 3 deletions

View File

@@ -194,6 +194,8 @@ export const URL_CONSTANTS = {
PAYMENTS: {
INITIATE: "/api/payments/initiate",
INTENT: (bookingId: string) => `/api/payments/intents/${bookingId}`,
REDIRECT_SUCCESS: (bookingId: string) =>
`/api/payments/redirect-success/${bookingId}`,
CHECKOUT: "/api/payments/checkout",
},

View File

@@ -21,6 +21,7 @@ const STATUS_STYLE: Record<
[Freight.InvoiceStatus.Draft]: { label: "Draft", bg: "#EEF2F6", fg: "#64748B" },
[Freight.InvoiceStatus.Issued]: { label: "Due", bg: "#FEF3E2", fg: "#B45309" },
[Freight.InvoiceStatus.Pending]: { label: "Due", bg: "#FEF3E2", fg: "#B45309" },
[Freight.InvoiceStatus.PaymentProcessing]: { label: "Payment processing", bg: "#EAF1FB", fg: "#2563EB" },
[Freight.InvoiceStatus.PartiallyPaid]: { label: "Partially paid", bg: "#FEF9E7", fg: "#A16207" },
[Freight.InvoiceStatus.Paid]: { label: "Paid", bg: "#E6F7EF", fg: "#0A6F4D" },
[Freight.InvoiceStatus.Overdue]: { label: "Overdue", bg: "#FDECEC", fg: "#C0392B" },

View File

@@ -41,6 +41,7 @@ const INVOICE_STATUS_LABELS: Record<string, string> = {
DRAFT: "Draft",
ISSUED: "Issued",
PENDING: "Due",
PAYMENT_PROCESSING: "Payment processing",
PARTIALLY_PAID: "Partially paid",
PAID: "Paid",
OVERDUE: "Overdue",

View File

@@ -120,6 +120,7 @@ const PAYMENT_COLORS: Record<string, string> = {
// Backend emits the long form on some flows; keep the short alias too.
VERIFICATION_IN_PROGRESS: "yellow",
PAYMENT_VERIFICATION_IN_PROGRESS: "yellow",
PAYMENT_PROCESSING: "yellow",
OVERDUE: "red",
REFUNDED: "blue",
CANCELLED: "gray",
@@ -132,6 +133,7 @@ const PAYMENT_LABELS: Record<string, string> = {
PNR_GENERATED: "PNR generated",
VERIFICATION_IN_PROGRESS: "Verifying",
PAYMENT_VERIFICATION_IN_PROGRESS: "Verifying",
PAYMENT_PROCESSING: "Payment processing",
OVERDUE: "Overdue",
REFUNDED: "Refunded",
CANCELLED: "Cancelled",

View File

@@ -8,10 +8,22 @@ import {
ThemeIcon,
} from "@mantine/core";
import { CheckCircle2, FileText, Home } from "lucide-react";
import { useNavigate } from "react-router-dom";
import { useEffect } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
import { paymentsService } from "@/services/payments.service";
export default function PaymentSuccessPage() {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const bookingId = searchParams.get("bookingId");
// Fire-and-forget ack: payment → processing, invoice → PAYMENT_PROCESSING.
// The provider webhook remains the source of truth for the final PAID state.
useEffect(() => {
if (bookingId) {
paymentsService.acknowledgeSuccessRedirect(bookingId).catch(() => {});
}
}, [bookingId]);
return (
<Box

View File

@@ -107,6 +107,11 @@ export const paymentsService = {
return data.data ?? data;
},
/** Success-redirect ack: payment → processing, invoice → PAYMENT_PROCESSING. */
acknowledgeSuccessRedirect: async (bookingId: string): Promise<void> => {
await client.post(P.REDIRECT_SUCCESS(bookingId));
},
checkoutUrl: buildCheckoutUrl,
checkoutUrlForInvoice: buildCheckoutUrlForInvoice,
};