Commit Graph

102 Commits

Author SHA1 Message Date
Stephanos A.
3a78605893 Merge pull request #1177 from Tria-plc/alpha
Alpha
2026-08-08 11:18:49 +03:00
Abubeker Yasin
f51ee7cf59 feat: (payment) add telebirr mini-app in-app payment flow 2026-08-07 13:48:58 +03:00
Nathnael
d4917bc6ec feat(auth): regate payment, booking and wagon reads
Payment summary/all moved off bookings:view onto payments:view, the
booking list now requires bookings:view for staff instead of accepting
any employee, and wagon reads require wagons:view or fleet:view rather
than bare authentication.
2026-08-07 07:41:00 +00:00
Nathnael
0114673120 feat(auth): gate and regate freight API controllers
Gates the previously open support-agent, procurement, compliance,
facilities, list-users and trade-access controllers, separates customer
from staff routes across bookings, contracts, companies, billing,
warehouses, files and train scheduling, and moves billing, overview,
reports and the settings controllers onto their own keys instead of the
blanket admin key. Drops the demo-permissions module and the untested
notification test route.
2026-08-07 07:32:25 +00:00
Nathnael
ab7069e335 fix 2026-08-06 10:26:32 +00:00
Nathnael
23e756e0c7 fix(billing): ceil CBE invoice amounts to whole birr 2026-08-06 09:16:01 +00:00
Marshal
5933795116 add metadata to ignore audit logging in payment events 2026-08-05 22:26:04 +00:00
Marshal
8089e5cfd9 feat(billing): enhance invoice payment processing and revert handling
feat(bookings): add event handlers for booking invoice payment processing
fix(bookings): include PAYMENT_VERIFICATION_IN_PROGRESS status in queries
fix(train-scheduling): update status checks to include PAYMENT_VERIFICATION_IN_PROGRESS
feat(notifier): notify customers when a train is cancelled
2026-08-05 20:46:44 +00:00
Marshal
b7dcc1bf0a feat(billing): add PAYMENT_PROCESSING invoice status on payment success redirect (all except CBE bill) 2026-08-05 12:59:37 +00:00
marshal
c3ba0192a9 Merge pull request #1083 from Tria-plc/freight_feature/usermanagement
Freight feature/usermanagement
2026-08-03 01:40:20 +03:00
Marshal
f4fd469643 per-user trade-direction access scope 2026-08-02 22:29:58 +00:00
ghost2023
12fb756cf5 fix: duplicate 2026-08-03 00:32:38 +03:00
Nathnael Wondisha
62a7e35708 Merge branch 'dev' into staging 2026-08-03 00:24:17 +03:00
Nathnael
6f137a11c3 fix:cbe and cac 2026-08-02 20:37:16 +00:00
Marshal
930e39c4fc Enhance internal payment handling and e2e testing setup 2026-08-02 18:39:17 +00:00
Nathnael
dd0c7af251 fix: internal payment controller 2026-08-02 18:34:12 +00:00
Nathnael
7762d6c2d3 fix: payemetn race condition 2026-08-02 18:28:40 +00:00
Nathnael
7cebef8c39 fix: min amount of cac 2026-08-02 18:10:12 +00:00
Nathnael Wondisha
938b34b55c Merge pull request #1060 from Tria-plc/freight/fix/pay
fix: hardcoded payment api url
2026-08-01 11:34:57 +03:00
ghost2023
1c508d23ae fix: hardcoded payment api url 2026-08-01 11:31:30 +03:00
Nathnael Wondisha
616269a988 Merge branch 'staging' into dev-to-staging 2026-08-01 10:27:47 +03:00
Abubeker Yasin
aa4ce7fd23 feat: ( payment ) specific CBE query descriptions + Payment_Reason 2026-07-31 16:03:28 +03:00
Nathnael
c176b9e7d6 fix(payment): give the payment-service client a 60s budget
CAC Bank's initiate SMSes an OTP before it answers and routinely takes more
than the 10s this client allowed, so every CAC charge came back as a 502
while the bank was still working — and if the bank had answered, the payer
would have been texted a code for an intent the freight side never recorded.
Matches the passenger API, which already budgets 60s and reads the same
PAYMENT_API_HTTP_TIMEOUT_MS override.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 09:02:27 +00:00
Nathnael
6f5f6d7b0a test(payment): cover the CAC Bank OTP confirm path
The confirm flow settles money on a provider with no webhook, so the two
places it can go wrong are worth pinning: that the OTP is forwarded against
the GATEWAY intent id (not the local projection id), and that a rejected
code leaves the intent open instead of failing the payment.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 08:20:35 +00:00
Nathnael
97bfe95ec3 feat(payment): integrate CAC Bank OTP payments into freight flows
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>
2026-07-31 08:11:23 +00:00
Abubeker
37855b0a83 feat: ( payment ) implement cbe payment 2026-07-31 07:50:10 +00:00
Marshal
acb6f286d4 fix(payments): reconcile with gateway before expiring unpaid holds
Replace the fixed 5-minute grace with a settlement check at expiry:
expire() calls the payment API's reconcile endpoint — paid intents are
kept and allocated via payment.succeeded, unverifiable results defer
expiry to the next tick, only verifiably unpaid holds expire.
2026-07-30 12:01:59 +00:00
Nathnael
dcc94643d0 feat(companies): enforce customers:* permissions on customer endpoints
The customers:* keys were seeded and present in the backoffice constants but
enforced nowhere except reset-password. Customer CRUD sat behind the coarse
edr_freight_app:admin umbrella, and every company read endpoint was unguarded.

Two routes could not be gated on the route alone, because the authority they
need depends on the request BODY, not the path:

  - PATCH /companies/:id carries `status` (UpdateCompanyDto extends
    PartialType(CreateCompanyDto)), so it both edits fields and blacklists.
  - PATCH /company-profiles/:profileId/status is approve, reject, suspend and
    blacklist on one route.

Both now take a one-of route guard and assert per-status against a shared
STATUS_PERM map: approving/reactivating needs customers:verify, suspending or
blacklisting needs customers:deactivate. PATCH /companies/:id additionally
requires customers:update when any non-status field is present, so a caller
holding only deactivate cannot rename a company. The backoffice mirrors the
same map so no button is offered that the server would reject.

GET /companies/:companyId/documents is left authenticated-only with the split
in the handler: it is dual-audience. The portal reads its own documents during
onboarding, and the contract-request detail page (gated on contracts:view)
reads the applicant's. Gating it on customers:view alone would have 403'd
customers on their own documents and blanked the contract reviewer's panel.

The two by-company customer-view reads take a one-of guard for the same reason
— otherwise a staffer granted only customers:view gets a detail page whose tabs
403 individually.

Frontend: the customers routes were sidebar-filtered but not wrapped in
RequirePermission, so direct URL navigation rendered them for anyone.

Verified: freight-api type-check clean; backoffice type-check unchanged from
HEAD (pre-existing errors only); 25 tests pass across the companies and
freight-permission suites. Not exercised against a running API.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:48:42 +00:00
Marshal
18311f22f7 Comment out payment event handling for local demos in BillingService 2026-07-17 09:20:36 +00:00
Marshal
7058922987 changes 2026-07-04 06:19:35 +00:00
Nathnael
f938107245 chore: add logger to mark-paid 2026-07-03 12:22:46 +00:00
Nathnael
43f7a039ad fix: payment api crash 2026-07-03 07:20:31 +00:00
ghost2023
79c3293a72 fix: booking paid trigger 2026-07-02 16:18:46 +03:00
Marshal
7d3eb39625 fix error 2026-07-02 10:40:31 +00:00
Marshal
adddb24033 add public to InternalPaymentController 2026-07-02 10:16:58 +00:00
marshal
7b3f9094ed changes 2026-07-02 13:02:33 +03:00
marshal
56bb75c9a8 fix transi permit file upload 2026-07-02 12:22:07 +03:00
marshal
4fefe4f827 finilize gl 2026-07-02 12:06:17 +03:00
ghost2023
1c012ce1e2 refactor(payment): centralize invoice processing with detailed tracking and configurable logging 2026-07-02 11:47:35 +03:00
marshal
1a6f461a06 changes 2026-06-30 18:23:47 +03:00
Nathnael
0056dec924 style: clean up the invoice and setup event for warehouse. 2026-06-30 13:28:14 +00:00
Nathnael
7fa18b8ee7 fix: reference type in payment service 2026-06-30 11:54:43 +00:00
marshal
dd9a7e639a console 2026-06-30 06:15:57 +03:00
Marshal
f51c015814 Enhance payment module 2026-06-30 03:13:18 +00:00
marshal
d05f634948 Merge branch 'freight_feature/contrat' of github.com:Tria-plc/edr-platform into freight_feature/contrat 2026-06-30 05:22:10 +03:00
Marshal
a072f04450 Enhance contract and booking request handling 2026-06-30 02:20:32 +00:00
marshal
abce3da6ce merge conflict 2026-06-30 05:17:56 +03:00
Marshal
ce3584cd4a cfix payment 2026-06-29 15:41:00 +00:00
Nathnael Wondisha
4cf8e89780 Merge branch 'dev' into freight/feat/invoice 2026-06-29 17:24:29 +03:00
marshal
69df391f90 Update payment service and API base URL for local development 2026-06-29 16:03:53 +03:00