Multi-user customer accounts

A lot of your B2B customers aren't one person — they're a buying team. A purchasing manager approves, two buyers place orders, a finance person needs to see invoices. Distribu handles this with customer contacts: extra sub-users that live under a single Customer account.

This page explains when to use contacts, how to set them up, and how permissions work.

The model

Customer (parent account)
├── email + password        ← the primary login
├── addresses
├── credit limit
├── price overrides
├── order history
└── CustomerContacts        ← sub-users
    ├── contact A — email + password, role: ADMIN
    ├── contact B — email + password, role: BUYER
    └── contact C — email + password, role: VIEWER
  • The primary customer is the email + password that was first registered (or created via CSV import). Treat it like the "account holder".
  • Contacts are additional people at the same business. Each has their own login (email + password) but they all share the parent customer's record — same addresses, same price overrides, same order history.

Contacts show up in the dashboard on the customer detail page, under a Contacts panel.

When to use contacts

Some common patterns:

  • Team buying. The account holder approves purchase orders; junior buyers place day-to-day orders. Give the juniors the BUYER role.
  • Finance visibility. Your customer's finance team needs to download invoices and see the order history, but shouldn't be able to place orders. Give them the VIEWER role.
  • Handoff without losing history. When a buyer leaves a customer's company, you deactivate their contact — the customer's order history stays intact because it's all attached to the parent Customer record, not the contact.

If a customer only has one person, you don't need contacts — the primary login is enough.

The three contact roles

RoleCan browse catalogCan place ordersCan manage other contacts
ADMIN
BUYER (default)
VIEWER

The VIEWER restriction is enforced server-side when an order is placed — even a crafted request from the browser gets rejected with "Your account does not have permission to place orders."

The primary customer login is always effectively ADMIN — it isn't stored as a contact and has no contact role on its session.

Adding a contact

From the dashboard:

  1. Go to Customers and click the customer you want to add someone to.
  2. Scroll to the Contacts panel and click + Add contact.
  3. Enter their email, optional name, and pick a role (defaults to BUYER).
  4. Click Add contact.

The contact is created immediately — but without a password. They can't log in yet.

How the contact sets their password

Send them to /store/{your-slug}/setup-password and let them know what email you added. On that page they:

  1. Enter the email you registered.
  2. Pick a password (8 characters or more) and confirm it.
  3. Submit.

Distribu looks up the contact by email, verifies it has no password set yet, securely stores the new password, and redirects them to /store/{your-slug}/login ready to sign in.

Tip. The setup-password route only works once per contact — it only accepts a contact who hasn't set a password yet. After the first setup, the same email logs in normally at /login.

How the contact logs in

At /store/{your-slug}/login, the login action tries two things in order:

  1. Primary customer match — look for a customer with this email, check the password, sign them in as the account holder.
  2. Contact match — if no primary match, look for a contact with this email whose parent customer is active, check the password, sign them in as a contact.

Either way, the session cookie ends up identifying the parent customer. When signed in as a contact, the session also carries the contact's ID and role so the VIEWER restriction above can be enforced server-side.

From the contact's perspective, the storefront looks identical to a primary customer session — same catalog, same addresses, same prices — except the Place order button is disabled (and server-rejected) for VIEWERs.

Changing a role or removing a contact

On the customer detail page, inside the Contacts panel:

  • Change role — click the role pill next to a contact and pick a new role. Takes effect on their next request; any existing session immediately reflects the new role because the role is re-checked on every action.
  • Remove — clicking Remove deletes the contact. They lose access immediately. Their previously placed orders stay on the parent customer's order list (orders are attached to the customer, not the individual contact).

What contacts share vs. don't

Shared with the parent customerUnique per contact
AddressesEmail
Credit limitPassword
Per-product price overridesName (optional)
Status (ACTIVE / BLOCKED — blocking the customer locks everyone out)Role
Order history (all orders are on the parent)

Blocking the parent customer (setting the customer's status to BLOCKED) blocks every contact too — login fails for all of them. Deactivating a single contact only affects that one.


That's the end of the Core Concepts section. Next up: Products & inventory walks through managing your catalog, pricing, and stock.