CAC Bank is an OTP debit with no redirect and no webhook: initiate SMSes a
code to the payer's mobile, and the charge only settles when that code is
confirmed. The payment service already spoke it (passenger uses it); the
freight side had the enum values but none of the flow.
API:
- PaymentClientService.confirmOtp forwards the code to
POST /payments/intents/:id/confirm, mapping 400/404 to BadRequest so a
mistyped code stays retryable instead of surfacing as a gateway failure.
- PaymentService.confirmOtp is keyed by the LOCAL intent id (the invoice's
paymentId) rather than the domain reference, so the right invoice settles
when several share a booking. On success billing settles the invoice.
- payInvoice rejects CAC_BANK without payerAccount before calling the
gateway, and no longer runs the demo auto-settle for a COLLECT_OTP intent
(it is not paid until the payer confirms).
- POST /billing/my-invoices/:id/confirm — ownership-checked, and since
warehouse fee invoices are central invoices it covers those too.
Portal:
- useInvoicePayment owns the whole flow (initiate, redirect-or-OTP, confirm)
and replaces the five near-identical pay mutations at the call sites.
- PaymentMethodModal gains the CAC Bank option, the payer mobile field, and
the OTP step. Click-outside is disabled there so a stray click cannot drop
the payer out of a live OTP window.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Implemented a shared file viewer modal using `useFileViewer` hook to allow inline viewing of documents (images, PDFs, videos, etc.) across the application.
- Updated `ContractClearanceReviewSection`, `ContractRequestDetailPage`, `ContractViewPage`, and booking-related components to utilize the new file viewer for document previews.
- Added "Approve all" button in `ContractClearanceReviewSection` to bulk approve documents.
- Enhanced document action buttons to include view and download options based on file type.
- Introduced `isViewable` utility to determine if a file can be previewed inline.
- Created `FileViewer` component to handle rendering of various file types and added appropriate fallback for unsupported formats.
- Added new fields to the Company entity: licenceNumber, statusDescription, dateRegistered, renewedFrom, renewalDate, renewedTo, region, zone, woreda, kebele, houseNo, and etradePhone.
- Updated onboarding wizard to include a new contact step and fetch company information from eTrade using TIN.
- Created ETradeInfo component to handle fetching and displaying eTrade data.
- Implemented ETradeService to interact with eTrade API and extract relevant company registration data.
- Added new DTOs for fetching eTrade data and handling responses.
- Updated CompanyProfileForm to integrate new fields and handle eTrade data.
- Created hooks for managing eTrade data fetching and error handling.
- Introduced a new step in the onboarding process to select company nationality (Ethiopian or Foreign).
- Updated API and service layers to handle nationality data for companies.
- Added support for uploading multiple business license files for each operational profile.
- Refactored company and forwarder forms to include new license upload step.
- Created a reusable RoleLicenseStep component for managing license file uploads.
- Implemented utility functions for phone number handling.
- Added migrations to update the database schema for nationality and business license files.
- Updated CompanyInfoResponseDto to include company profile data in response.
- Enhanced ResponseExternalProfileDto to include active profile type and onboarding details.
- Added new fields to ExternalProfile entity for active profile type and onboarding status.
- Implemented onboarding wizard dialog in the frontend to guide users through the onboarding process.
- Introduced API endpoints for managing company profiles and onboarding steps.
- Created migrations to add new columns for active mode and onboarding status in the database.
- Added functionality to switch between operational modes (importer/exporter) and create profiles as needed.
- Improved user experience by ensuring onboarding is enforced for new users and those without completed profiles.
- Implement MySignatureCard component for viewing and updating saved signatures.
- Enhance BookingContractPage to utilize saved signatures for contract signing.
- Introduce hooks for fetching and saving user signatures.
- Update ContractView interface to include saved signature details.
- Create signatures service for API interactions related to user signatures.