Anonymized B2B logistics case: schools, manifests, and pallets—not consumer doorstep delivery.
The merchant already had ShipStation for labels and tracking. The pain was operational truth: finance and warehouse leadership could not answer, from systems alone:
- “Is this carton on the approved manifest for Institution X?”
- “Did Pallet 14 actually contain every order assigned to it before the truck departed?”
- “Why does ERP revenue not match delivered cartons this month?”
We put Laravel in the middle—not to replace ShipStation, but to normalize events, apply business rules, and expose reconciliation dashboards exports.
1. Ingestion: webhooks first-class
Routes
POST /webhooks/shipstationbehind signature verification (ShipStation’s shared secret pattern).- Return
200fast; push payload to queue—never do heavy SQL in HTTP thread.
Idempotency
- Table
webhook_events: unique(provider, event_id)or hash of body + type. - Handlers must tolerate at-least-once delivery—
insertOrIgnore+ state machine transitions.
Event types we cared about
SHIP_NOTIFY— tracking number existsITEM_ORDER_NOTIFY— line-level ship quantities (when available)- Fulfillment updates that implied multi-carton splits
2. Normalization layer
ShipStation’s orderNumber often maps to merchant internal order—sometimes with prefixes (PO-12345-B). We built:
- Regex rules per client (versioned YAML) to extract
internal_order_id,line_suffix,manifest_idfrom tags/notes whenorderNumberwas ambiguous. - Dead letter queue for payloads that fail normalization with raw JSON attached for human triage.
3. Institutional verification (“school” rules)
Table ship_to_approvals (illustrative):
institution_id,ship_to_hash(normalized address),valid_from,valid_to,status- Queue worker: on each outbound ship event, verify order’s ship-to matches an active approval for the SKU category (some institutions only accept certain product lines).
Outcomes
MATCHED,FLAGGED,BLOCKED(blocked triggers Slack + holds ERP export line).
4. Palletization
Schema
pallets(id, truck_load_id, statusopen|sealed|departed)pallet_items(pallet_id, carton_id or order_line_shipment_id, scanned_by, scanned_at)- Scan API from warehouse handhelds: Laravel Sanctum tokens, optimistic locking on pallet status (
sealedrejects new scans).
Reconciliation
- Nightly job:
assigned_to_palletvsscan_eventsvs ShipStationquantity_shipped.
5. Dashboards and exports
- Ops UI: filters by institution, pallet, date range; drill to raw webhook JSON.
- Finance CSV: vocabulary matched their existing “GL export” column names—adoption hinge.
- Audit trail: who overrode a mismatch and why (
override_reasonrequired).
6. Why not do this inside ShipStation alone?
ShipStation excels at carrier workflows—not arbitrary institutional policy graphs or ERP reconciliation state. Laravel gives:
- Policies (
Gate) for roles (warehouse vs supervisor vs read-only finance) - Horizon for queue visibility
- Fast iteration on rules without carrier downtime
7. Failure stories we planned for
- Webhook storm on Cyber Monday → scale workers horizontally; DB connection pooling tuned.
- Institution changes address mid-season → approvals versioned; old shipments remain tied to old hash.
Resume framing
“Built a Laravel reconciliation hub on ShipStation: signed webhooks, idempotent normalization, institutional rule engine, pallet scan model, and finance-grade exports.”