B2B SaaS / internal ops platform
Multi-Carrier
Shipping Label Platform
One screen for multi-channel orders, multi-carrier labels, quoting and wallet billing.
A shipping platform that lets online sellers generate labels across Royal Mail, DPD, Evri, DHL and FedEx from one place, with a digital wallet, automated postage calculation and direct integration with major marketplaces.
- Shipping labels generated
- 8,700+
- Carrier integrations
- 9
- Sales channels unified
- 8
- Carrier rate cards
- 49
One Dashboard
All major carriers
01Summary
A B2B fulfilment platform that sits between e-commerce sellers and UK shipping carriers. It pulls orders from every sales channel into one place, lets ops staff generate compliant labels across multiple carriers without touching each carrier's dashboard, and lets the business price, quote and invoice shipping as a resold service — with wallet billing, claims handling and role-based access on top.
- Faster shipping workflows
- Reduced manual work
- Scales with your business

02The Problem
A seller running stores on eBay, Shopify, TikTok Shop, Amazon and other marketplaces otherwise has to:
Log into each channel's seller dashboard separately to see what has sold.
Pick a carrier and service for every order by hand, re-keying addresses into each carrier's portal.
Live without a single view of what is fulfilled versus still waiting across channels.
Accept each carrier's own rate card, with no way to add a margin or offer customers a discounted rate.
Handle quoting, invoicing and prepaid billing as a shipping reseller — none of which exists in any carrier's tooling.
03My Role & Scope
End-to-end development, from architecture to deployment and ongoing production support.
- Order ingestionOAuth and webhook integrations per channel (eBay, Shopify, TikTok Shop), normalising very different order shapes into one internal model.
- Label creation abstractionOne internal request type fanning out to carrier-specific implementations — Royal Mail, Evri, Amazon Shipping, Yodel/OneWorld — each with its own auth, XML or JSON format and undocumented limits.
- Rates & quotingAdmin-configurable rate cards, margin and discount rules, branded PDF quotes with expiry dates, delivered by email.
- BillingStripe-backed prepaid wallet, automatic invoicing and downloadable statements.
- Operational toolingUnified order dashboard, bulk labels, audit log, RBAC, claims workflow, customer-service chat and a background tracking worker.
- API migrationLeading the move from the server-rendered MVC monolith to a Clean Architecture REST API (Domain / Application / Infrastructure / Api).
04Architecture
SQL Server via EF Core — about 45 domain models and 50 view models across 30 feature areas, from orders and carriers to quotes, wallet, invoicing, claims and chat.
Sales channels
Order import & normalisation
Unified order dashboard
Label creation abstraction
Background tracking worker
05Key Features
Everything the platform does, in one place.
- Unified order dashboardEvery order from every channel in one filterable table, with bulk label creation that resolves which integration really owns each order.
- Carrier rate managementPer-carrier, per-service, per-country rate cards with weight bands, surcharges, margin % and maximum discount %.
- Quote generationBranded shipping-rate PDFs with the business's margin applied, valid for a chosen period, previewed and emailed to leads.
- One label interface, many carriersAdding a carrier means implementing one interface — not rewriting the order flow.
- Tracking automationA scheduled worker updates delivery and return status and repairs shipments left in an inconsistent state.
- Wallet, billing & claimsPrepaid Stripe wallet, automatic invoices, role-based staff access, a full audit log and a lost/damaged claims workflow.
06Engineering challenges & how I solved them
Real problems found against live production data — with the actual debugging path, not just the fix.
An undocumented carrier limit was silently failing a whole channel's labels+
Symptom: Labels for one channel started failing with "Invalid Customer Reference 1 (Error 10030)" — and the carrier publishes no API reference.
Investigation: Queried the shipment history instead of guessing against a paid API: every successful label had a reference of 19 characters or fewer, every failure had 24 or more.
Fix: Truncated the reference defensively at the single shared conversion method every entry point uses, and mirrored the fix into the API rewrite.
A background job logged false errors that masked real ones+
Symptom: The tracking worker logged a TaskCanceledException "error" every couple of hours — only in production.
Investigation: The worker waits up to 24 hours between runs; every app-pool recycle or deployment cancels that wait, which is normal shutdown but was logged like a failure.
Fix: Caught the cancellation case specifically and logged it at Information level, so Error-level logs are trustworthy again.
Client-side sorting ordered dates as strings+
Symptom: Rows arrived newest-first from the server, but after the table library loaded, 11 Sept appeared before 28 Aug.
Investigation: Formatted dates are not a pattern the table library recognises, so it fell back to alphabetical order.
Fix: Supplied a raw timestamp as the sortable value alongside the readable text through the library's orthogonal-data support.
A stale config value had permanently blocked a feature+
Symptom: Quotes for one carrier failed with "End date cannot exceed 30 Mar 2026" — for any date at all.
Investigation: A "price valid until" date on the carrier record had lapsed without renewal, and the check compared every quote against it unconditionally.
Fix: Enforced the cutoff only while it is still current, on both the PDF preview and the quote-creation paths, which had drifted apart.
Order routing was not the same as the order's display label+
Investigation: Older imports stored a retail channel name in the field newer orders use for the platform, so routing on that text risked calling an integration the seller never connected.
Fix: Built a resolver that trusts a match only when the seller has that platform connected, falls back to their only connected platform, and otherwise disables label creation rather than guessing.
Case study
An undocumented carrier limit was silently failing a whole channel's labels
Problem
Labels for one channel started failing with "Invalid Customer Reference 1 (Error 10030)" — and the carrier publishes no API reference.
Investigation
Queried the shipment history instead of guessing against a paid API: every successful label had a reference of 19 characters or fewer, every failure had 24 or more.
Solution
Truncated the reference defensively at the single shared conversion method every entry point uses, and mirrored the fix into the API rewrite.
07Impact
What changed once the platform was in place.
- Shipping labels generated
- 8,700+
- Carrier integrations
- 9
- Sales channels unified
- 8
- Carrier rate cards
- 49
- Replaced logging into several channel dashboards with one screen and bulk label creation.
- Removed a class of silent carrier-API failures by fixing at the shared abstraction layer.
- Turned misleading production logs into a trustworthy signal.
- Kept a live quoting feature from going dark whenever a config value lapsed.
- 8,700+ labels shipped across 9 carrier integrations through one consistent interface.
ASP.NET CoreEF CoreSQL ServerREST API designClean ArchitectureOAuth & webhooksSOAP/XML & RESTBackground jobsPDF generationStripeRBACLegacy-to-API migration
Have a similar project?
Let's build something great together.
From shipping platforms to custom business tools — I can help turn your idea into reality.
- Free consultation
- Clear roadmap
- On-time delivery

