mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-07 21:15:41 +00:00
Merge branch 'staging' into dev
This commit is contained in:
@@ -68,6 +68,7 @@ const METHOD_OPTIONS: { value: PaymentMethod; label: string }[] = [
|
||||
{ value: "card", label: "Card" },
|
||||
{ value: "dmoney", label: "D-Money" },
|
||||
{ value: "cac-bank", label: "CAC Bank" },
|
||||
{ value: "cbe-bill", label: "CBE Bill" },
|
||||
];
|
||||
|
||||
const STATUS_COLORS: Record<string, string> = {
|
||||
|
||||
@@ -19,7 +19,8 @@ export type PaymentMethod =
|
||||
| "waafi"
|
||||
| "card"
|
||||
| "dmoney"
|
||||
| "cac-bank";
|
||||
| "cac-bank"
|
||||
| "cbe-bill";
|
||||
|
||||
export interface PaymentRow {
|
||||
id: string;
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Divider,
|
||||
Group,
|
||||
Loader,
|
||||
Modal,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Stack,
|
||||
@@ -69,6 +70,12 @@ export default function InvoiceDetailPage() {
|
||||
} = useQuery(api.invoices.get.queryOptions({ input: { id } }));
|
||||
|
||||
const [payModalOpen, setPayModalOpen] = useState(false);
|
||||
// CBE bill payment: the bill reference to pay at any CBE channel (no redirect).
|
||||
const [billAction, setBillAction] = useState<{
|
||||
billReference?: string;
|
||||
instructions?: string;
|
||||
expiresAt?: string;
|
||||
} | null>(null);
|
||||
|
||||
// Ownership-checked: POST /billing/my-invoices/:id/pay only ever charges
|
||||
// one of the signed-in customer's own invoices (unlike the admin-facing
|
||||
@@ -377,6 +384,62 @@ export default function InvoiceDetailPage() {
|
||||
pay.pay(id, method, payerAccount)
|
||||
}
|
||||
/>
|
||||
|
||||
{/* CBE bill payment — show the bill number; settlement arrives via CBE, not the browser */}
|
||||
<Modal
|
||||
opened={!!billAction}
|
||||
onClose={() => setBillAction(null)}
|
||||
centered
|
||||
radius={18}
|
||||
size={440}
|
||||
title={<Text fw={800}>Pay at CBE</Text>}
|
||||
>
|
||||
<Stack gap="sm">
|
||||
<Text fz="sm" c={MUTED}>
|
||||
{billAction?.instructions ??
|
||||
"Pay this bill at any CBE branch, the CBE Birr app, mobile banking or USSD."}
|
||||
</Text>
|
||||
<Group
|
||||
justify="space-between"
|
||||
px={16}
|
||||
py={13}
|
||||
style={{ borderRadius: 12, border: `1px solid ${BORDER}` }}
|
||||
>
|
||||
<Text ff="monospace" fz={24} fw={800} c={INK} style={{ letterSpacing: 3 }}>
|
||||
{billAction?.billReference}
|
||||
</Text>
|
||||
<Button
|
||||
variant="light"
|
||||
size="xs"
|
||||
onClick={() => {
|
||||
if (billAction?.billReference) {
|
||||
navigator.clipboard?.writeText(billAction.billReference);
|
||||
toast.success("Bill number copied");
|
||||
}
|
||||
}}
|
||||
>
|
||||
Copy
|
||||
</Button>
|
||||
</Group>
|
||||
<Text fz="sm" c={MUTED}>
|
||||
Amount due:{" "}
|
||||
<Text span fw={700} c={INK}>
|
||||
{formatCurrency(amountDue, invoice.currency)}
|
||||
</Text>
|
||||
</Text>
|
||||
{billAction?.expiresAt && (
|
||||
<Text fz="sm" c={MUTED}>
|
||||
Pay before:{" "}
|
||||
<Text span fw={700} c={INK}>
|
||||
{fmtDate(billAction.expiresAt)}
|
||||
</Text>
|
||||
</Text>
|
||||
)}
|
||||
<Text fz="xs" c={MUTED}>
|
||||
The invoice updates automatically once CBE confirms your payment.
|
||||
</Text>
|
||||
</Stack>
|
||||
</Modal>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -26,7 +26,7 @@ interface ProviderOption {
|
||||
accent: string;
|
||||
}
|
||||
|
||||
// Only Telebirr, Waafi and CAC Bank are enabled for now.
|
||||
// Only Telebirr, Waafi and CBE bill payment are enabled for now.
|
||||
const PROVIDERS: ProviderOption[] = [
|
||||
{
|
||||
method: "TELEBIRR",
|
||||
@@ -51,6 +51,14 @@ const PROVIDERS: ProviderOption[] = [
|
||||
currencies: ["USD"],
|
||||
accent: "#8A5A17",
|
||||
},
|
||||
{
|
||||
method: "CBE_BILL",
|
||||
label: "CBE bill payment",
|
||||
description: "Pay at any CBE branch, app or USSD · ETB",
|
||||
logo: "/assets/edr-logo.png",
|
||||
currencies: ["ETB"],
|
||||
accent: "#5B2D8C",
|
||||
},
|
||||
];
|
||||
|
||||
/** Providers that debit against an SMS OTP instead of redirecting to a page. */
|
||||
|
||||
@@ -12,7 +12,8 @@ export type PaymentMethod =
|
||||
| "WAAFI"
|
||||
| "CARD"
|
||||
| "DMONEY"
|
||||
| "CAC_BANK";
|
||||
| "CAC_BANK"
|
||||
| "CBE_BILL";
|
||||
|
||||
export type PaymentPlatform = "web" | "mobile";
|
||||
|
||||
@@ -26,13 +27,17 @@ export interface InitiatePaymentPayload {
|
||||
}
|
||||
|
||||
export interface ClientAction {
|
||||
type: "REDIRECT" | "LAUNCH_APP" | "COLLECT_OTP";
|
||||
type: "REDIRECT" | "LAUNCH_APP" | "COLLECT_OTP" | "SHOW_BILL_REFERENCE";
|
||||
url?: string;
|
||||
appId?: string;
|
||||
receiveCode?: string;
|
||||
shortCode?: string;
|
||||
providerOrderId?: string;
|
||||
message?: string;
|
||||
/** SHOW_BILL_REFERENCE (CBE bill payment) */
|
||||
billReference?: string;
|
||||
instructions?: string;
|
||||
expiresAt?: string;
|
||||
}
|
||||
|
||||
export interface InitiateResponse {
|
||||
|
||||
Reference in New Issue
Block a user