Merit · Product · Internal Explainer
Merit sells goods it does not own. The Seller Portal is where the people who do own them list their stock, take orders, and get them out of the door. Every screen below is exported from the Seller Portal Figma file, so this is the real design, not an impression of it.
If you only read one section, read this one.
Merit runs branded marketplaces where members burn loyalty points on real goods. Someone has to supply those goods. Some come from Merit's own stock, but most come from third party sellers, and every one of them needs a way to say here is my product, here is my price, here is how much I have, and then a way to actually fulfil the orders that follow.
The Seller Portal is that surface. It is the seller's entire relationship with Merit: catalog in, orders out, money back. Before it existed, sellers emailed spreadsheets to the Operations team, who typed them in by hand. Average time from a seller having a product to that product being buyable was seven days.
The strategic goal for 2026 is written as "from manual oversight to automated autonomy". In plain terms: get Merit's Operations team out of the middle. Every screen in this portal exists to remove one thing a human at Merit used to do by hand.
Sellers list products by web form, CSV, SFTP or API. Products land in PIM, an Offer is created against the seller, and it goes live.
Orders arrive, the seller accepts, picks, packs and ships. Who ships depends on the model in section 03.
Delivery closes the order and triggers payout. Today the payout itself is still calculated by hand, monthly.
This is not a consumer product. The primary user is a warehouse operator under time pressure, often on a shared login, often not the person who owns the account. Most design decisions in the portal follow from that single fact, and most of the friction in the product comes from forgetting it.
Building this page from the real Figma turned up several places where the shipped design and the written specification disagree, including one that is fully inverted. Section 08 lists them. They are not nitpicks, they change what the revamp is actually for.
Four roles, two of them inside Merit. Each one meets a different part of the product, which is why there is no single "the seller journey".
Sets the account up, adds the catalog, sets prices, manages bank details and invites their own staff. Logs in weekly, not hourly. Cares about margin, payout and whether their products are winning the Buy Box.
The heaviest user by a wide margin. Opens the order queue in the morning and works it down. Standing, often on a shared screen, frequently holding a physical box. Needs big targets, printable paper, and no ambiguity about what to do next.
A trusted seller allowed to use their own couriers. Same portal, different order screen and an extra tracking step. Cannot self serve into this tier, Merit switches it on.
Operates through an admin role inside the Seller Portal itself, cross tenant. Invites sellers, sets their shipping model, flips the Elite toggle, reviews the matches the AI matching engine is unsure about, and is the hub for operating physical orders across every seller. Half of what a seller sees is decided here.
Merit sells its own goods through a Merit-owned seller account, on the same Seller Portal every third party seller uses. No separate tooling for first-party stock.
The Digital Seller Portal is a separate workflow on the same Seller Portal codebase, for gift card and other digital sellers. A seller doing both physical and digital switches between the two at the top of the portal, and the data stays segregated. It records the commercial terms and the fulfilment route; the Fulfillment Service performs the fulfilment. E-commerce Core holds the gift card commercial terms, discount, markup, transaction fee and tenant revenue split, per tenant and per product.
A seller is configured to exactly one of these. It changes the order screen, the actions available, and in principle the data they can see. Read this before section 07.
| Model | Who moves the box | Shown in the portal as | Extra steps |
|---|---|---|---|
| SPL Standard Pick-up Logic | Merit's carrier collects from the seller | Merit Logistics (SPL) | Pack, then request an AWB for pickup |
| FBM Fulfilled by Merit | Merit, from Merit's own warehouse | Seller is mostly out of the per order loop | Send stock to Merit up front |
| MFN Elite Self shipping | The seller's own fleet or courier | Self Managed | Accept, then enter courier and tracking |
SPL is the default. MFN Elite is off unless an Ops Admin turns it on, and per the specification it requires a verified warehouse address in Saudi Arabia and a cancellation rate under two percent.
Users: Ops Admin, then Seller Admin. Sellers cannot sign themselves up. Every account starts as an invitation from inside Merit.
Setting a seller's default shipping method at invite time happens through the admin role in the Seller Portal, which this file does not cover. It matters because every invited seller defaults to SPL, and if they are really an MFN or FBM seller somebody has to correct it afterwards.
The seller's KYB business address is never a warehouse. A warehouse is its own structured location, stored in the Identity Service address module, which the Seller Portal proxies writes to and keeps no copy of. Every warehouse carries a mandatory map pin, a pickup contact name, email and mobile, and a system location code. A seller can register many warehouses, and each warehouse can carry many offers. The Fulfillment Service mirrors every warehouse and registers it with OTO as a pickup location. Deactivating a warehouse switches off every offer linked to it, the same as zero stock does.
Deactivating a seller auto-suspends every one of their offers. It does not remove their catalog entries; that cleanup stays a manual Ops check.
User: Seller Admin. This is the largest surface in the product and the flow that replaced emailing spreadsheets to Operations. There are five distinct ways in, aimed at five sizes of seller. All five need to be designed, because a seller picks one and lives in it.
| Method | Who uses it | What it handles |
|---|---|---|
| 1. Single web form | Small sellers, one-off additions | One product, via a search-first wizard |
| 2. Bulk CSV | Mid size, hundreds of SKUs | Template, partial success, per-row results |
| 3. Bulk images by URL | Anyone using CSV | An images column of pipe-separated URLs, fetched asynchronously |
| 4. SFTP drop | Enterprise, 1000+ SKUs | Seller's ERP writes a CSV to a dedicated folder, polled every 5 minutes |
| 5. API | Technically integrated sellers and aggregators | Keys, batch endpoint, status polling, rate limits, and a supplier-facing order API |
Every listing, whatever the method, originates in the Seller Portal. A seller picks one method and lives in it, and the method changes nothing downstream: the same matching, the same offer, the same order flow.
The most important thing about this flow is the order of operations. It does not begin by asking for a category or product details. It begins by asking whether Merit already sells this thing.
From here the flow forks, and the Figma organises it as exactly those two branches: Listing Exists and Listing Doesn't Exist.
A Variant is the Product plus the complete set of its variant axis values, colour and size for example. When a new offer collides with an existing variant, the fix is cheapest first: split into separate Products, or add an allowed value to an axis, before ever adding a new axis, and a category carries at most five axes. A new Offer never resolves a collision. A seller can never create a variant axis themselves.
For Smartphones, region, UAE, International, US, is itself a variant axis. One grouped PDP holds every region, and Buy Box competition happens within a region rather than across all of them.
The tooltips in that screen are the clearest statement of the rules anywhere in the product:
| Outcome | What the tooltip says | What happens next |
|---|---|---|
| Successfully processed | All mandatory attributes are present, the entry has been accepted and processed | Goes live |
| Invalid or rejected | One or more mandatory attributes are missing, the entry was rejected and needs correcting before re-uploading | Seller fixes and re-uploads |
| Match found | A matching product was found, shown with its confidence score | Ops accepts or rejects the match |
| Possible match | A similar product may already exist, this entry will be reviewed by the admin team to confirm the correct match | Ops accepts or rejects the match |
| No match found | No matching product was found, a new listing will be created after admin review | Ops reviews and creates the new listing |
Matching runs in shadow mode. Every row carries a visible confidence score, but nothing goes live off that score alone: an Ops reviewer accepts or rejects every match. LiveOps sets the automation level per category, fully manual, semi-automated, or fully automated, so there is no single fixed percentage that decides for everyone. The AI team at Merit owns the matching engine.
A row missing a critical field, price, SKU or GTIN, is Rejected and the seller must fix the file. A row missing a recommended field, description or weight, becomes a Draft, saved and finishable in the UI. Same failed import, two completely different recovery journeys.
Bulk images ride on the CSV rather than being a separate upload: an images column holds pipe-separated public URLs, fetched asynchronously and stored under a content-addressable name so the same photo uploaded by two sellers is stored once. Links must be direct and unauthenticated, with a specific exception for public Google Drive links. Failures are per image, not per row, so a product can go live with two of its three photos.
SFTP gives enterprise sellers a folder at /sftp/seller_{id}/inventory/, polled every five minutes, with differential updates so unchanged rows are skipped and a processing report emailed back. The portal is a monitoring surface for this method, not an input one.
The API needs a developer area: sk_live and sk_test key management, webhooks, a rate limit of 100 requests per minute, and batch status polling via POST /v1/products/batch then GET /v1/batches/{id}. A separate, supplier-facing Order API lets integrated sellers work their orders by API instead of the UI. It maps onto the same states the UI uses: a pickup request means accepted and ready to ship, a cancel call with a reason code means rejected, and shipped or delivered follow from the carrier's own events.
User: Seller Admin. The highest frequency catalog action by far, and the one where latency costs real money.
Stock decrements when payment is confirmed, not when the customer reaches checkout. There is no reservation or hold. Two customers can therefore both buy the last unit, and one of them fails after paying. This is known, confirmed current behaviour, and the interface has to deal with it honestly rather than pretend it cannot happen.
User: warehouse operator. The core loop of the product, and the screen the heaviest user spends the day in. The Figma splits it into two boards, one per shipping model.
The Seller Portal does not talk to the Fulfillment Service directly. The Order Management System is the single source of truth for order and fulfilment status, and the portal shows what OMS knows.
Every order also carries a short, human-readable reference in the form SELLER_PREFIX-YYMMDD-NNNN, for example AF-260819-0042, unique per seller per day and reset at Riyadh midnight. It is shown next to the system order id and printed on the pick and pack label, but it is never a lookup key.
Merit Logistics (SPL). The primary action is Request AWB and Ship, with the helper text "Pack the order and click Request AWB when ready for SPL pickup", so the seller signals readiness and Merit's carrier takes over. Note the right hand Order Timeline, Print Items on the items card, and Special Instructions carrying handling notes. Figma: Hi Fi Designs / Orders - Merit logistics, 988:10172| State | Allowed action | Who gets told |
|---|---|---|
| New | Accept, Cancel with a reason picked from a dropdown, Print items | Seller email |
| Accepted | Pick and pack, upload the invoice, then Request AWB (SPL) or enter tracking (Self Managed) | Customer sees "Accepted" |
| Ready to ship | Hand over to carrier | Customer push notification |
| Shipped | Manual delivery override only | Customer sees courier and tracking |
| Delivered | None, order is closed | Payout triggered |
An order becomes Delivered when the customer taps "Received" in the B2C app, or automatically after seven days with no dispute raised. That auto close is what makes payout possible without a human confirming every parcel.
After bulk accepting a batch of orders, the operator is returned to the order list with no indication of what to do next, and has to open each order individually. The proposed fix is a preparation view: the accepted batch on one scrollable surface, each card showing order, tenant, item, SKU, quantity and packing notes, markable as packed without navigating away, resumable if they leave. It is not in the Figma and it is the highest value gap in the product.
Found by building this page from the Figma and the PRDs side by side. Each of these needs a decision, and each one changes what the revamp is for.
The upload specification offers sellers an sk_test sandbox key. There is no Seller Portal sandbox environment; it was deferred with the wider sandbox effort, which is also why the design team has to be given staging accounts instead.
The product upload screens use a dark navy application header. The order screens use a white header with a left navigation rail carrying text labels. These are different design eras sitting in the same product, and any revamp has to pick one deliberately rather than inherit both.
No design exists for: the SFTP monitoring surface, the developer and API area, bulk image partial-failure states, the admin role's own screens, the printed pick list, the post-bulk-accept preparation view, self-service returns, or a settlement and payout view. Some of this is a redesign and some is original design, and those are different kinds of work to plan for.
The constraints that will bite, and are not obvious from the screens alone.
The words that come up constantly and mean something specific here.
SELLER_PREFIX-YYMMDD-NNNN, unique per seller per day, reset at Riyadh midnight. Shown next to the system order id and printed on the pick and pack label. Never a lookup key.