Merge pull request #1074 from Tria-plc/fixes

Fixes
This commit is contained in:
Nathnael Wondisha
2026-08-02 21:10:50 +03:00
committed by GitHub
5 changed files with 39 additions and 18 deletions

View File

@@ -1130,20 +1130,20 @@ export class BillingService {
// An OTP intent (CAC Bank) is NOT paid yet — the payer still has to enter the
// code — so the demo shortcut must never fire for it. Same for CBE_BILL: its
// bill must stay open until CBE actually settles it via /cbe/payment.
if (
!result.immediateSuccess &&
result.response.clientAction?.type !== "COLLECT_OTP" &&
opts.method !== "CBE_BILL"
) {
await this.payment.handlePaymentEvent({
eventType: "payment.succeeded",
eventId: `demo-${result.intentId}`,
referenceId: invoice.sourceId,
intentId: result.intentId,
providerTxnId: result.providerTxnId,
paidAt: (result.paidAt ?? new Date()).toISOString(),
});
}
// if (
// !result.immediateSuccess &&
// result.response.clientAction?.type !== "COLLECT_OTP" &&
// opts.method !== "CBE_BILL"
// ) {
// await this.payment.handlePaymentEvent({
// eventType: "payment.succeeded",
// eventId: `demo-${result.intentId}`,
// referenceId: invoice.sourceId,
// intentId: result.intentId,
// providerTxnId: result.providerTxnId,
// paidAt: (result.paidAt ?? new Date()).toISOString(),
// });
// }
if (result.immediateSuccess) {
await this.settleByPaymentId(

View File

@@ -232,10 +232,15 @@ export class PaymentService {
referenceType: PaymentReferenceType.SHIPMENT,
referenceId: input.referenceId,
orderRef: input.orderRef,
// amountMinor: input.amountMinor,
// CBE_BILL must carry the REAL amount: /cbe/payment verifies what the customer was
// debited against the intent amount, so the 1-birr dev shortcut would break it.
amountMinor: isCbeBill ? input.amountMinor : 1,
// debited against the intent amount, so the dev shortcut would break it.
// CAC bank rejects amounts below 10 (DJF bounds 10100,000), so its dev
// shortcut floor is 10, not 1.
amountMinor: isCbeBill
? input.amountMinor
: input.method === ProviderMethod.CAC_BANK
? 10
: 1,
currency: input.currency,
provider: input.method as ProviderMethod,
platform: input.platform,

View File

@@ -197,6 +197,7 @@ export default function CompanyProfileForm({
companyEmail: "",
companyPhone: "",
companyAddress: "",
etradePhone: "",
tinNumber: "",
vatNumber: "",
ownerPassportNumber: "",
@@ -279,6 +280,14 @@ export default function CompanyProfileForm({
// setting region/zone/woreda/kebele/houseNo above is enough — no need to
// compose it here. companyPhone is derived below (identity → eTrade →
// account), not set directly here.
// etradePhone is the raw number eTrade returned for this TIN — kept as its
// own field (distinct from companyPhone, which prefers the Fayda-verified
// owner's phone) so the backend's "matches eTrade's current record" check
// always compares against what eTrade actually said, not the owner's phone.
setValue(
"etradePhone",
data.managerPhone || data.regularPhone || data.mobilePhone,
);
setEtradeOwner({
name: data.managerName,
@@ -303,6 +312,7 @@ export default function CompanyProfileForm({
setValue("woreda", "");
setValue("kebele", "");
setValue("houseNo", "");
setValue("etradePhone", "");
setEtradeOwner(null);
};

View File

@@ -70,7 +70,7 @@ export function stepPayload(
woreda: d.woreda,
kebele: d.kebele,
houseNo: d.houseNo,
etradePhone: d.companyPhone,
etradePhone: d.etradePhone,
};
case "personnel":
return {
@@ -101,6 +101,7 @@ export function toFormValues(p: ProfileResponse): FormData {
companyEmail: p.companyEmail ?? "",
companyPhone: p.companyPhone ?? "",
companyAddress: p.companyAddress ?? "",
etradePhone: p.etradePhone ?? "",
tinNumber: tin,
vatNumber: p.vatNumber ?? "",
ownerPassportNumber: p.identity?.owner.passportNumber ?? "",

View File

@@ -21,6 +21,10 @@ export const onboardingSchema = z.object({
// Derived from the eTrade address parts (kebele/woreda/zone/region); no
// standalone input — the granular fields live in the registration section.
companyAddress: z.string().optional(),
// Raw phone from the eTrade lookup itself — kept separate from companyPhone
// (which shows the Fayda-verified owner's phone once verified) so the two
// can diverge without the backend's eTrade-authenticity check misfiring.
etradePhone: z.string().optional(),
tinNumber: z.string().regex(/^\d{10}$/, "TIN must be exactly 10 digits"),
vatNumber: z
.string()
@@ -124,6 +128,7 @@ export const stepFields: Record<CompanyStep, (keyof FormData)[]> = {
"companyEmail",
"companyPhone",
"companyAddress",
"etradePhone",
"tinNumber",
"vatNumber",
"ownerPassportNumber",