The Problem In One Sentence
In Moroccan COD ecommerce, checkout is not the sale. The merchant pays operational cost before knowing whether the buyer is serious, reachable, or likely to refuse delivery.
That creates the real product problem: merchants do not need another order table; they need an operating system that manages COD work and learns which orders are risky before shipping.
Evidence Of The Workflow Problem
The visual evidence above is the product argument: Wasilio was shaped around repeated operational failure points, then each failure point became a queue, workflow, risk signal, or staff control.
This is why the system is modeled around workflows and state transitions instead of generic CRUD.
Design Decision
The visual model above is the core of the case study. The product was not organized around database tables; it was organized around who owns the next operational step.
The backend enforces that model in OrderLifecycleService. That means the system rejects impossible actions, such as delivering an order that was never picked up or modifying an order already in a final state.
Risk Intelligence Direction
The important product direction is that failed COD orders should not disappear into reports. They should become risk signals.
| Signal | Why it matters | Product response | | --- | --- | --- | | Repeated refusal from the same phone or address | Indicates possible fake intent or repeat abuse | Buyer risk score | | Customer unreachable after several attempts | Predicts likely failed delivery | Hold or reconfirm before shipping | | Bad address or suspicious location pattern | Increases courier cost and failure probability | Address risk flag | | Courier reports vague failure reasons | Hides whether the issue is buyer, courier, or operations | Structured failure taxonomy | | Merchant keeps shipping similar failed orders | Repeats preventable shipping loss | Recommendation before dispatch |
The score should not behave like a black box. A merchant should see the reasons behind the risk score, then decide whether to ship, reconfirm, require prepayment, hold for review, or reject clear abuse.
Architecture Decision
Wasilio uses an event-backed lifecycle for order changes and a read projection for operational screens. That event history is also the foundation for future risk scoring.
Why this matters:
- The event log explains how an order reached its state.
- The projection keeps dashboards and queues fast.
- The lifecycle service protects business invariants.
- Failed delivery outcomes become features for future order scoring.
Confirmation Is Not A Boolean
COD confirmation has more outcomes than yes or no:
sequenceDiagram
autonumber
participant Customer as Customer
participant Agent as Confirmation agent
participant App as Wasilio workspace
participant Risk as Risk signals
participant Order as Order lifecycle
participant Events as domain_events
participant Queue as Courier queue
Customer->>App: Places COD order
App->>Risk: Check phone, address, attempts, past outcomes
Risk-->>App: Risk level + explanation
Agent->>App: Record call attempt and note
App->>Order: Request transition
alt Confirmed and acceptable risk
Order->>Events: OrderConfirmed
Order->>Queue: Ready for courier assignment
else Call back later
Order->>Events: CallbackScheduled
App->>Agent: Requeue for follow-up
else Rejected or high-risk abuse
Order->>Events: OrderRejected
App->>Risk: Feed failure signal
else Delivered or failed after dispatch
Queue->>Order: Delivery outcome
Order->>Events: Delivered or FailedDeliveryCaptured
Order->>Risk: Feed outcome for future scoring
endThe separate confirmation_attempts model preserves history: who called, what happened, which attempt number it was, and whether a callback is due, overdue, upcoming, or resolved.
System Surfaces
Wasilio has three product surfaces:
| Surface | Why it exists | | --- | --- | | Public landing and signup | Capture serious pilot merchants | | Merchant workspace | Run COD operations day to day | | Staff admin | Manage tenants, plans, manual payments, receipts, and lead follow-up |
This separation matters because the buyer journey, merchant workflow, and internal operations are different systems with different permissions.
The website demo points to wasilio.ma. The full merchant application is not publicly deployed yet, so the portfolio presents the architecture and product direction without implying the private app is live.
Security And Operations
The implementation includes JWT authentication, role-aware routing, tenant status blocking, password reset tokens, public signup controls, abuse throttling, Flyway migrations, local seed data separation, and actuator health endpoints.
Those details are not decorative. They make the system usable as a real SaaS pilot instead of a dashboard prototype.
Trade-Offs
Modular monolith first
Orders, confirmations, couriers, billing, and leads are separate concerns, but splitting them into services too early would create distributed complexity before the product needs it.
Event log plus projection
Event-backed order state is more work than a direct status update. The payoff is auditability and stronger workflow validation.
Manual billing first
For early Moroccan COD pilots, managed onboarding and manual receipts are more realistic than automated subscription checkout. The trade-off is staff workload, but it matches the sales motion.
Explainable risk scoring
Risk scoring can reduce shipping loss, but it must be explainable. A silent score would make the system hard to trust. Wasilio should show the reason: failed confirmation history, repeat refusal pattern, suspicious address, or courier outcome trend.
What This Case Study Demonstrates
Wasilio demonstrates product architecture under local business constraints:
- Turning a messy operational process into explicit workflows.
- Using state machines to protect business invariants.
- Combining event history with fast read models.
- Designing a foundation for failed-order prediction and fraud detection.
- Designing multi-tenant SaaS with staff controls.
- Choosing architecture based on product stage, not trend.
The engineering point is simple: architecture is valuable when it preserves business truth. For Wasilio, that truth is the journey from customer intent to confirmed order, courier handoff, delivered cash, explained failure, and smarter future shipping decisions.