Start ProjectGet in Touch
Project02 / 22

Max Weigel B2B

Max Weigel B2B: Titelbild des Projekts
The project

Max Weigel equips industrial companies with protective workwear. The B2B shop sits behind the login and shows every worker only their own assortment. We built it with Medusa and a Next.js storefront, running on our own server via Docker. Added to that are spending limits per employee, payment by invoice and an order email that the Sage ERP can process directly.

Services

Headless shop with a Medusa backend and a Next.js storefront, self-hosted via Docker, plus a fully German interface in both shop and admin. Catalog import from the ERP, company and employee management, order notification with a CSV attachment for Sage, and automated tests in CI.

Focus

A closed shop in which every field worker only sees the items of their own product group. The buyer creates employees, budgets and cost centres without asking the supplier.

Details

Prices are net, VAT is shown separately. Payment is by invoice only, and there is deliberately no shipping selection and no self-registration. No tracking, no analytics, only technically necessary cookies.

Max Weigel B2B: Bild 1
Max Weigel B2B: Bild 2
Max Weigel B2B: Bild 3

When a shop is not allowed to show anything

In B2B, a catalog is rarely an offer to everyone. Which items a customer gets and on what terms is written down in an agreement, and that agreement applies to them and not to the next customer. An open shop would have to hide those differences even though they are the actual content. So not opening the shop in the first place is the obvious move.

That sounds simpler than it builds. A closed area is only as tight as its weakest point, and that point is rarely where you look first. The product page itself is usually secured quickly. What remains are the side roads: navigation that gives away product groups in the menu, a search that answers on request, a sitemap that lists addresses, a search index still holding a page from last week.

For Max Weigel the protection therefore runs on several levels rather than one. A check in the request path sends everything except a handful of public pages to the login. Navigation and footer hide product groups and search entirely while nobody is signed in, so the structure of the assortment does not reveal what the catalog is meant to keep. And the shop removes itself from the index via noindex and robots.txt, because a closed system has nothing to gain in a search engine. Accounts are created by Max Weigel only, there is no self-registration.

Everyone sees their own assortment

The field workers ordering at Max Weigel work in different areas. Anyone who needs multinorm protective clothing has nothing to do with high-visibility clothing, and the other way round. A shared catalog would walk both groups past items that are not intended for them. That is not a comfort problem but a source of error: protective clothing ordered by mistake does not protect.

The separation therefore runs through customer groups rather than permissions on individual items. Each group has its product groups, while a small shared set such as accessories and shirts stays visible to everyone. It is assigned at the moment of invitation, so no second place to maintain appears. If an account lacks the assignment, it sees the full assortment instead of none. That direction is a deliberate choice: a catalog that is too large is an annoyance, an empty shop is an outage.

On top of that come spending limits per employee with a selectable cycle, from daily to yearly. The buyer sets them, sees consumption as a bar in the account and needs nobody at the supplier to do it. The limit is checked on the server when the order is completed, not only in the interface. A rule that lives in the frontend alone is not a rule, it is a request.

Handing over to the ERP

An order in a shop only becomes an order once it arrives in the merchant's system. At Max Weigel, invoice and delivery note are created in Sage, and the shop is the capture step before that. Between the two lies a gap that is classically closed by retyping, and retyping is where item numbers turn into transposed digits.

Every order therefore produces a notification with a ready-made CSV attachment: item number, description, variant, quantity, net prices, plus order number, orderer, company, customer number and cost centre. The file is built for the import and not for the eye, with semicolons, CRLF and a byte order mark so Excel does not break the umlauts. The cost centre is resolved in a fixed order, first the entry from checkout, then the employee's fixed cost centre.

A real interface to Sage would be the next step, and it deliberately was not the first one for this stage. A live connection requires an agreement about field names and error cases, and that conversation can happen while the shop is already running. The interim state costs one import per order and in exchange takes retyping and follow-up questions out of the way. Generating that file is covered by tests, as are the shop's critical rules in general: role checks, spending limits, invitations. Several of those tests exist because of a specific incident, and that is exactly why they are there.

Related services

Ready for Your Next Project?

Write to us or book an initial consultation directly. We reply within 24 hours, usually faster on weekdays.