Customer (Buyer) Portal
The customer app is a white-label, mobile-first self-service app for your B2B customers. They sign in with their email, see only their company's catalog and price list, place orders without an agent in the loop, and check shipment status. Optional — disabled by default.
Beta status. The customer app is feature-complete and production-stable, but we keep "beta" on it because we're still iterating on white-label theming and aggregate analytics. Use it freely — your data is safe, your buyers won't see anyone else's prices.
Activation
- Open Settings → Buyer app.
- Toggle
buyerPortalEnabledon. - Save. The customer app is now reachable at
/buyer/<your-shop-handle>.
White-label customization
From Settings → Buyer app:
- Logo — upload SVG or PNG. Shown in the top bar and the email magic-link templates.
- Brand color — single accent color for buttons and links. Defaults to monochrome black.
- Custom domain (Scale tier) — point a CNAME at
buyer.soryk.appto host the portal atorders.yourbrand.com. - From-email name — appears as the sender display name on transactional emails.
For deeper customization (custom CSS, login page hero copy), the Custom Branding add-on is available on Growth and Pro for +€29/mo.
Buyer signin flow
- Buyer visits the portal URL (or follows a link from a quote / invoice email).
- They enter their email.
- An OTP code is sent via Resend. Magic-link version also supported.
- They enter the code → JWT cookie set, valid 90 days.
- Alternatively: "Sign in with Google" if you've configured Google OAuth.
The buyer's email must already exist as a contact on a Shopify B2B Company. If not, signin fails with "no matching company". This prevents drive-by signups.
Rate-limited. The OTP request endpoint is dehindrate-limited (5 per identity, 30 per IP, 5-minute window) to prevent abuse. Excess returns HTTP 429.
Catalog scoping
The buyer's view is automatically scoped to their company:
- Catalog — only products in the B2B catalog assigned to their company.
- Pricing — Shopify contextualPricing applied, so they see their tier's prices.
- Locations — they can pick from their company's locations as ship-to.
Server-side enforcement: every buyer API verifies that the requested location belongs to the session's companyId. Cross-company access returns HTTP 403. No client-side scoping — it's all enforced on the API.
Cart & ordering
- Buyer browses catalog, taps + on items to add to cart.
- Cart screen shows lines, subtotal, ship-to picker.
- Slide-to-confirm gesture submits the order.
- A draft order is created in Shopify, tagged with
soryk_buyer:<email>(sanitized). - Shopify proceeds with the standard B2B checkout / invoicing.
Reorder from history
From the Orders tab, every past order has a Reorder button. Tap it to copy all line items into a fresh cart — quantities included. Out-of-stock items are flagged but not blocked (matches the agent-side behaviour).
Shipment tracking
The Shipments tab lists fulfillment events for the company's recent orders, with carrier tracking links straight to UPS / DHL / GLS / etc. — pulled from Shopify's native fulfillment objects.
Buyer analytics
A simple consumption dashboard: spend per period, order count trend, top products. Useful for buyers who want to forecast or report internally. Scoped strictly to the buyer's own company.
Limitations vs agent mode
| Capability | Agent mode | Buyer portal |
|---|---|---|
| Place orders for a company | Yes (any assigned) | Yes (own company only) |
| Apply discount | Yes (within cap) | No |
| Save quotes | Yes | No (current beta) |
| See other companies' data | If assigned | Never — strict scoping |
| Custom payment terms | Pick from approved list | Defaults to company's term |
| Visit forms | Yes | N/A |
| Push notifications | Yes (push notifications) | Not yet |
When to enable the customer app
- D2C wholesalers with hundreds of small accounts who don't justify dedicated agent time.
- Subscription-style B2B where customers reorder the same SKUs monthly — the Reorder button is a killer feature here.
- Hybrid orgs where premium accounts get an agent and long-tail accounts self-serve.
- Catalog refresh notifications — when you add new products, every buyer with portal access can browse and order without waiting for their agent.
When to leave it off
- You only sell through agents and want full attribution control.
- Your prices are negotiated per-order and shouldn't be self-served.
- You haven't yet decided how to handle support requests from self-serve buyers.