Files
edr-platform/apps/edr-freight-web/portal/src/services/payments.service.ts
2026-07-31 07:50:10 +00:00

113 lines
2.9 KiB
TypeScript

import { URL_CONSTANTS } from "@/constants/URLS";
import { API_BASE_URL } from "@/constants/apiConfig";
import { client } from "../utils/api";
const P = URL_CONSTANTS.PAYMENTS;
/** Payment methods supported by the central payment microservice. */
export type PaymentMethod =
| "TELEBIRR"
| "CBE_BIRR"
| "EBIRR"
| "WAAFI"
| "CARD"
| "DMONEY"
| "CAC_BANK"
| "CBE_BILL";
export type PaymentPlatform = "web" | "mobile";
export interface InitiatePaymentPayload {
invoiceId: string;
method: PaymentMethod;
platform?: PaymentPlatform;
payerAccount?: string;
returnUrl?: string;
failureUrl?: string;
}
export interface ClientAction {
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 {
intentId: string;
status: string;
clientAction?: ClientAction;
merchantOrderId?: string;
}
export interface IntentStatus extends InitiateResponse {
paidAt?: string;
failureCode?: string;
failureMessage?: string;
}
/**
* Builds the absolute URL for the public browser-checkout page, which
* (re)initiates the payment and auto-redirects to the provider's checkout.
* Used as the "pay" step after a successful `initiate`.
*/
function buildCheckoutUrl(payload: {
bookingId: string;
method: PaymentMethod;
platform?: PaymentPlatform;
}): string {
const base = API_BASE_URL.replace(/\/$/, "");
const params = new URLSearchParams({
bookingId: payload.bookingId,
method: payload.method,
platform: payload.platform ?? "web",
});
return `${base}${P.CHECKOUT}?${params.toString()}`;
}
/**
* Checkout fallback keyed by invoice id — matches `GET /payments/checkout`,
* which reads `invoiceId` (billing is invoice-centric; there is no
* `bookingId` param on that route).
*/
function buildCheckoutUrlForInvoice(payload: {
invoiceId: string;
method: PaymentMethod;
platform?: PaymentPlatform;
}): string {
const base = API_BASE_URL.replace(/\/$/, "");
const params = new URLSearchParams({
invoiceId: payload.invoiceId,
method: payload.method,
platform: payload.platform ?? "web",
});
return `${base}${P.CHECKOUT}?${params.toString()}`;
}
export const paymentsService = {
initiate: async (
payload: InitiatePaymentPayload,
): Promise<InitiateResponse> => {
const { data } = await client.post(P.INITIATE, {
platform: "web",
...payload,
});
return data.data ?? data;
},
getIntent: async (bookingId: string): Promise<IntentStatus> => {
const { data } = await client.get(P.INTENT(bookingId));
return data.data ?? data;
},
checkoutUrl: buildCheckoutUrl,
checkoutUrlForInvoice: buildCheckoutUrlForInvoice,
};