
Multi-tenant marketplace platform with admin, merchant, courier, and consumer portals.
BAZR is an enterprise-scale multi-vendor marketplace platform supporting four independently scoped portals: Admin, Merchant, Courier, and Consumer. Each portal runs its own authentication policy, data access layer, and purpose-built UI. Role-based access control (AdminOnly, MerchantOnly, CourierOnly, CustomerOnly) is enforced at the API layer via JWT claims, and payment/stock-allocation flows run inside RepeatableRead-isolated transactions to guard against IDOR and TOCTOU race conditions. The merchant portal covers catalogue management, order fulfillment, sales analytics, channel comparison (Marketplace vs E-Store), subscription plans (Basic/Pro/Enterprise), and subdomain/custom-domain support. The courier portal provides live shipment status, pickup/delivery confirmation, and earnings history. On the consumer side, Stripe PaymentIntent handles checkout, SignalR delivers real-time shipment tracking, and the platform includes cart, wishlist, and a notification centre. Hangfire drives background jobs (order status, delayed shipment, notifications, shipment sync), QuestPDF generates invoices, and SendGrid/Twilio handle email and SMS notifications. Redis backs both caching and the SignalR backplane. The design system is built on CSS custom-property tokens with an accessible Radix UI-based component library. Built on .NET 10 Web API (Clean Architecture + CQRS/MediatR), Next.js 16 (App Router), TypeScript, PostgreSQL, and Redis.
<div class="project-info">
<p>
This project was developed using the best tools modern web technologies offer. Each technology was carefully selected to maximize performance, security, and user experience. During development, the focus was on component-based architecture, reusable code, and optimized rendering performance.
</p>
<p>
The user interface was designed to provide a clean yet impactful visual experience. The design system is built on principles of consistency, readability, and accessibility. Modern CSS frameworks and utility tools were used to provide a strong styling foundation.
</p>
<p>
On the frontend, powerful technologies like React and Next.js provided great advantages in terms of fast load times and SEO optimization. Additionally, Tailwind CSS accelerated the design process and made development more flexible.
</p>
<p>
As a result, this technology stack forms a modern and sustainable infrastructure that supports not only today’s needs but also future scalability goals.
</p>
<p>
The project also delivers a seamless experience across all devices thanks to responsive design and a mobile-first approach. Every aspect of the design was optimized for usability and accessibility, ensuring smooth user interactions.
</p>
<p>
Performance optimizations were implemented to minimize page load times, including efficient media and image handling. This approach improves user experience while providing a solid foundation for SEO and overall site performance._
</p>
</div>ASP.NET Core
Backend
Next.js
Frontend
React
Frontend
TypeScript
Language
Tailwind CSS
Frontend
PostgreSQL
Database
Redis
Database
Stripe
Backend
Docker
DevOps
Vercel
DevOps
An Upwork client needed a multi-tenant marketplace connecting admins, merchants, couriers, and customers with different data-access needs, on top of payment flows that are natural targets for IDOR and stock-race exploits.
I architected a Clean Architecture/CQRS (MediatR) .NET API with JWT-based role scoping (AdminOnly/MerchantOnly/CourierOnly/CustomerOnly) enforced at the API layer, RepeatableRead-isolated transactions around payment/stock allocation, Stripe PaymentIntent checkout, SignalR with a Redis backplane for real-time tracking, and Hangfire for background jobs.
Isolation-level choice is a real architectural decision, not a database default to accept blindly — RepeatableRead was the right trade-off here because stock allocation reads then writes the same rows within one transaction.
If you'd like to discuss the architecture decisions, the tech stack, or a similar technical problem, I'm happy to talk.
Get in Touch