
Confidential Enterprise Project (Protected Under NDA)
Proprietary source code, database architectures, and internal endpoint credentials are confidential. This case study highlights non-proprietary architectural patterns, technical solutions, and verified outcomes.
CelleUp is an established wholesale/retail wireless distribution back office: a Super Admin → Distributor → Dealer/Store → Sales Rep hierarchy that already handled single-line activations, point-of-sale transactions, device leasing/financing, and reporting across a long list of carrier and payment integrations (T-Mobile, AireSpring, Surge, PrepaidIQ, Emida, CellPay, Bitrefill, Acima, and more - each with its own bespoke
Service class).As MVNO and prepaid volume grew, dealers and kiosks needed to activate SIMs in bulk - dozens or hundreds of lines in a single sitting, or migrate a batch of existing customers as part of a SIM-swap campaign - rather than one line at a time through the existing single-activation screens. The obstacle was that every carrier speaks a different language: T-Mobile, Rogue Mobile and Nexio Mobile each have distinct plan-code and inventory rules, while a separate Nexus/ISPWN wholesale layer exposes a full GSMA/GSMT porting, SIM, and eSIM lifecycle (port add/status/MDN-change, SIM add/suspend/reconnect/plan-change, eSIM download/confirm/QR) behind yet another auth scheme. Years of incremental, carrier-by-carrier scripting (two multi-thousand-line
Helper classes) meant there was no unified way to say "activate these 500 SIMs" without hand-rolling the logic per carrier every time. Getting this wrong is expensive in both directions: a botched bulk activation either burns non-refundable wholesale SIM cost or leaves a customer without service, and any new workflow had to keep the platform's multi-tenant wallet accounting (distributor funds a dealer, a dealer funds its own store) correct under concurrent, long-running jobs.Provider abstraction. Each upstream carrier/MVNO gets its own
Service class (NexusService, ISPWNService, RogueMobileService, NexioMobileService, and siblings for the platform's other integrations). NexusService handles bearer-token login/refresh plus bulk-activation submission and batch-status polling; ISPWNService switches between sandbox and production credential sets and exposes the full port/SIM/eSIM lifecycle as discrete methods (portsAdd, simsChangePlan, simsSuspend, simsGetEsim, etc.). Each service normalizes a differently-shaped upstream response into one internal activation result, so the rest of the application never has to know which carrier it's talking to.Data model. The platform uses a star-schema-style Laravel/MySQL layer (dimension/fact table naming) for accounts, dealers, distributors, products, carriers, and transactions. SwapPad's own tables -
SwappadProduct, StoreSwappadProduct, SimBank, ISPActivationBatch/ISPActivation - were added on top of that existing schema rather than requiring a rewrite, so the new bulk-activation product line inherits the platform's existing reporting and billing views.Bulk pipeline. A dealer uploads a CSV; the header shape is auto-detected (ICCID + ZipCode, or ZipCode + Quantity), then a provider-specific preflight runs before anything is charged - for example, Nexio Mobile activations are checked against zip-level plan-code coverage up front so a bad row fails the whole batch atomically instead of charging and refunding after the carrier rejects it. Funds are then validated up the wallet chain (distributor → dealer → store) before the batch is persisted to
ISPActivationBatch and handed to ProcessSwapPadBatchJob, a queued job (2-hour timeout, since some carrier sandboxes are slow) that activates each row against the right carrier, updates row-level status, and records the cost split for each tier.Real-time feedback. Rather than have the dealer's browser poll for status, a Server-Sent-Events endpoint (
streamStatus) watches the batch record every two seconds and pushes completed / failed / total counters directly to the UI, closing automatically once the batch finishes, fails, or a 5-minute connection cap is hit.Access control & tenancy. Spatie
laravel-permission plus a custom Distributor/Dealer/Team role hierarchy scope what each tier can see and act on - a distributor can view every batch beneath it; a dealer sees only its own.Reporting & ops. Yajra DataTables-driven transaction views, PDF export via DomPDF, Excel export of batch results, Slack alerting on failures, and scheduled Artisan commands reconcile status with each carrier independently of the request/response cycle.
1. Reconciling incompatible carrier semantics inside one CSV workflow. Some carriers need an ICCID+ZIP pair per row; Nexio Mobile needs ZIP+quantity and a hard check that inventory exists for that zip before anything is charged. Solved with header-based CSV shape detection plus a dedicated preflight step (
performNexioPreflight) that validates provider-specific constraints and fails the entire batch before any wallet hold is placed - avoiding a charge/refund dance when a downstream API would have rejected the row anyway.2. Keeping multi-tier wallet accounting correct across long, asynchronous jobs. A single batch can run for up to two hours against rate-limited carrier sandboxes, and cost has to land on the right tier (distributor-funded vs. self-funded store) without double-charging on retry. Solved by holding the full estimated charge at submission time (
calculateTotalStoreChargeForCsv / calculateTotalDistributorChargeForCsv) and reconciling actual per-row cost as the queue worker completes each activation, with a separate retryBatch path that only re-submits the rows that actually failed.3. Giving dealers live visibility into a long-running batch without overloading the server. Implemented an SSE stream instead of client-side polling, with a bounded connection lifetime and automatic close-on-completion, so a dealer watching a 500-row activation gets sub-2-second updates without generating hundreds of redundant HTTP requests.
Replaced manual, one-line-at-a-time carrier activation with a single CSV-driven bulk workflow spanning T-Mobile, Rogue Mobile, Nexio Mobile, and the Nexus/ISPWN wholesale MVNO layer (porting, new SIM, eSIM, plan changes, suspend/reconnect) behind one dealer-facing screen.
Extended a years-old, single-carrier-at-a-time back office with an entirely new bulk-activation product line without a schema rewrite, by layering new tables cleanly onto the existing dimensional model.
Gave distributors and dealers real-time batch visibility and self-service retry, reducing reliance on support tickets to find out whether a bulk order went through.
Preserved the platform's existing multi-tier wallet/commission model across the new bulk path, so distributor → dealer → store accounting stayed correct without standing up a parallel billing system.
Gallery
sim activation
hirearchy tree
sim bank
Tech stack
Laravel
Timeline & Milestones
Designed Product/SimBank/ISPActivationBatch tables and the carrier-service abstraction layered onto the existing CelleUp data model
0 likes · 4 views · Oct 15, 2026
Developed a bulk SIM activation platform for CelleUp, enhancing carrier integration and workflow efficiency.