International Wholesale B2B E-Commerce Platform
Enterprise Magento 2.4 platform serving 15+ European markets with custom multi-format product feeds, percentage-based surcharges, scripted multi-server deployment, and external OMS integration.
The Challenge
Managing an international e-commerce operation across 15+European markets presents significant technical and organisational challenges. This project required a sophisticated platform capable of handling diverse business requirements whilst maintaining a single codebase.
Show what makes multi-market B2B commerce complexHide what makes multi-market B2B commerce complex
Unlike B2C storefronts, wholesale operations demand credit account visibility and integration with external order management systems, so customers can see their order history and credit position directly in the portal.
The platform needed to serve both traditional B2B customers accessing the portal directly and integration partners consuming product data via configurable feeds.
The platform needed to support B2B wholesale customers who need order history and credit account visibility, external system integrations for order management, and configurable product feeds for integration partners across multiple data formats.
Key Requirements
- Multi-language support for 16 locales with full translation coverage and locale-specific formatting conventions
- Integration with external Order Management System for customer-facing account history and credit ageing analysis
- Customer-specific product feed configurations supporting CSV, JSON, and XML formats
- Jurisdiction-specific surcharge mechanisms for opt-in customer segments
- Reliable, repeatable scripted deployment across three production servers
Technical Architecture
The implementation is built on Magento 2 extension patterns with emphasis on plugin-based extension, service contracts, declarative schema management, and dependency injection. This architectural approach maintains clean upgrade paths whilst enabling extensive customisation.
Show why plugin-based extension over class preferenceHide why plugin-based extension over class preference
Magento 2 offers two primary extension mechanisms: plugins (interceptors) and preferences (class replacements). Plugins allow method interception without replacing entire classes, reducing conflicts with other modules and simplifying upgrades.
The project uses 27plugins across custom modules. This approach kept upgrade paths cleaner than class preferences, which reduced conflicts with other modules.
Technology Stack
Built on Magento 2.4 Community Edition with PHP 8.3, the platform uses MySQL 8.0 for persistence, Elasticsearch 7.17 for search, Redis 7.0 and Varnish 7.5 for caching layers, and RabbitMQ 3.9 for asynchronous message processing.
Module Organisation
Custom functionality is organised by vendor namespace:
- Primary modules - Core business logic (product feeds, surcharge calculations, stock management)
- Secondary modules - UI components (mega menu, image carousels, promotional banners)
- Integration modules - External system connectors (OMS REST APIs, marketing automation)
This separation ensures clear ownership and reduces coupling between feature areas.
Ready to eliminate your technical debt?
Transform unmaintainable legacy code into a clean, modern codebase that your team can confidently build upon.
Technical Challenges
Four significant challenges emerged during implementation, each requiring custom solutions that demonstrate enterprise-grade architecture whilst maintaining clean, testable code.
Challenge 1: Multi-Format Customer-Specific Feeds
Problem: Integration partners required product data in different formats (CSV, JSON, XML) with customer-specific field configurations. Each customer needed to select which attributes to include in their feed, with locale-aware number formatting.
Show why per-customer configuration mattersHide why per-customer configuration matters
Integration partners have varying technical capabilities. Some can parse any format, whilst others have rigid import requirements. Some partners need computed values like tiered pricing or stock levels.
Providing configurable feeds reduced partner onboarding friction significantly. The feed module comprises 3,309lines across 63files, implementing three serialisation formats with dynamic attribute processors.
The feed system supports three distinct feed types.
Show the three feed typesHide the three feed types
ProductFeedInterface: Contains all enabled products with the customer's chosen attributes.
OrderedProductFeedInterface: Filters to products a specific customer has previously purchased.
CategoryFeedInterface: Exports the category hierarchy.
Challenge 2: Jurisdiction-Specific Surcharges
Problem: Certain customer segments required percentage-based surcharges on their orders (including shipping), opt-in at registration time, flowing through the entire order lifecycle (quote → order → invoice → credit memo).
The surcharge module (1,947lines) extends 5database tables and implements total collectors for each sales document type.
Show why opt-in attribute rather than group-based rulesHide why opt-in attribute rather than group-based rules
Regulatory requirements meant customers needed to actively consent to surcharge application. A boolean customer attribute (customer_add_surcharge) set during registration provided clearer audit trails than group-based logic.
The trade-off was reduced flexibility: surcharge applicability cannot easily change after registration. This was accepted because compliance requirements outweighed flexibility.
Challenge 3: Multi-Server Deployment for 16 Locales
Problem: Static content deployment for 16 locales was time-consuming and error-prone. Changes needed to synchronise across three production servers without service interruption.
Show deployment complexity at scaleHide deployment complexity at scale
Static content deployment covers 16 locales across 2 theme variants, and the output must stay consistent across all three production servers.
Custom deployment scripts (292lines of Bash) implement dynamic CPU-scaled threading and hub-and-spoke synchronisation.
The deployment approach reflects the team's operational philosophy and resource constraints.
Show why manual scripts instead of CI/CD pipelineHide why manual scripts instead of CI/CD pipeline
The operations team size (small) and existing infrastructure (traditional hosting) made full CI/CD overhead disproportionate. Safety gates in scripts provide human verification at critical points.
The team valued explicit control over fully automated deployments. Triple- confirmation gates (general prompt, server verification, database change awareness) provide human verification at critical points, and have prevented multiple potential production incidents. The trade-off is that there is no automated rollback and deployments require human presence.
Challenge 4: External OMS Integration with Ageing Analysis
Problem: B2B customers needed to view order history, invoices, and credit memos from an external Order Management System, with credit account ageing buckets (30/60/90/120 days).
Two modules (3,160lines combined) implement REST API endpoints for OMS data ingestion and customer-facing account history pages.
Show why separate API and frontend modulesHide why separate API and frontend modules
The OMS team and frontend team worked on different release cycles. Separating concerns allowed API changes without frontend redeployment and vice versa.
The trade-off was more modules to maintain and some code duplication in view models, accepted because deployment independence reduced coordination overhead.
Implementation Solutions
Each challenge was addressed with custom implementations that prioritise extensibility, maintainability, and performance.
Beyond feed generation, the platform required custom financial logic to handle jurisdiction-specific surcharges flowing through the complete order lifecycle.
Reliable deployment across multiple servers and locales required custom automation that balanced speed with safety whilst adapting to available hardware resources.
Customer-facing transparency required deep integration with the external Order Management System to surface transaction history and credit account status directly in the platform.
Ready to eliminate your technical debt?
Transform unmaintainable legacy code into a clean, modern codebase that your team can confidently build upon.
Measurable Outcomes
The platform demonstrates enterprise-grade architecture through substantial custom development and sophisticated integrations.
Development Scale
- 26,048lines of custom PHP code implementing business logic
- 65+modules providing discrete, testable functionality
- 16locales supported with full translation coverage
- 3servers in production with scripted synchronisation
Module Complexity
- Feed system: 3,309lines across 63files
- Surcharge module: 1,947lines extending 5tables
- OMS integration: 3,160lines across 2modules
- Deployment automation: 292lines of shell scripts
Show development velocity and code churnHide development velocity and code churn
Over a two-year period, the project accumulated 650+commits demonstrating consistent development velocity. In the most recent year, the codebase saw 427,507insertions reflecting active feature development and maintenance.
These figures point to sustained development activity over the period.
Skills Demonstrated
This implementation showcases expertise across multiple domains:
- Magento 2 Architecture - Plugin/interceptor patterns, service contracts, declarative schema, total collectors, extension attributes
- Integration Engineering - REST API design, multi-system data flow, payment gateway integration
- DevOps & Automation - Multi-server deployment, resource-aware scaling, safety engineering with confirmation gates
- Internationalisation - 16-locale support, locale-aware formatting, multi-language maintenance pages
Key Insights & Lessons
What Worked Well
Feed System Architecture: The dynamic attribute processor pattern proved highly extensible. New computed fields (stock levels and tiered pricing) were added without modifying core feed logic.
Surcharge Implementation: The observer-based approach for PayPal integration was cleaner than anticipated. Storing both base and store currency amounts enabled accurate multi-currency reporting.
Show deployment safety patterns that prevented incidentsHide deployment safety patterns that prevented incidents
The triple-confirmation pattern has prevented multiple potential production incidents.
Dynamic thread scaling adapts to different server hardware automatically.
Hub-and-spoke synchronisation with selective exclusions preserves server-specific data such as media, logs and exports.
OMS Integration Design: Separating API persistence from frontend display modules allowed independent evolution. The API module could be updated to support new OMS endpoints without touching customer-facing code. The hydrator pattern simplified partial updates from the OMS, reducing synchronisation complexity.
Areas for Improvement
Feed Configuration Caching: Test observations note configuration values being cached between tests, suggesting optimisation opportunities for production performance. Smarter cache invalidation could improve feed generation speed.
Testing Coverage: Integration tests exist but coverage is relatively light, and unit test coverage could be expanded.
Show testing coverage and quality assuranceHide testing coverage and quality assurance
Integration tests exist but coverage is relatively light (39integration tests). Expanding unit test coverage is a clear improvement area.
Deployment Automation: The current manual execution could be enhanced with CI/CD integration, though the safety gates provide value for the current team size. The lack of automated rollback is a further improvement area.
Show cI/CD integration considerationsHide cI/CD integration considerations
The team values explicit control over deployments, but automation could reduce toil without sacrificing safety. A hybrid approach might preserve manual approval gates whilst automating compilation, synchronisation, and verification steps.
The current approach has no automated rollback and requires human presence during deployment, a trade-off accepted for explicit control.
Key Takeaways
- Plugin over preference: Using interceptors rather than class preferences kept upgrade paths cleaner and reduced conflicts with other modules
- Dual-currency storage: Always store both base and store currency for financial totals to enable accurate reporting across currency boundaries
- Safety gates matter: Human-in-the-loop confirmations prevent costly mistakes
- Separation of concerns: API modules separate from frontend modules enabled independent deployment cycles and reduced coordination overhead
Related Services
Explore our expertise in e-commerce, PHP development, and infrastructure automation
Magento Development
Enterprise Magento 2 development, custom modules, and complex business logic
PHP Development
Modern PHP development with type safety, testing, and best practices
Ready to eliminate your technical debt?
Transform unmaintainable legacy code into a clean, modern codebase that your team can confidently build upon.