Team management
The surface where the merchant manages who has access to their dashboard and at what permission level. Owners can invite new teammates, change their roles, remove them, and transfer primary ownership. Pending invitations are listed alongside current members so the merchant can see at a glance who has been invited but not yet joined.
Role hierarchy
From highest to lowest privilege:
| Role | Permissions | Per-merchant count |
|---|---|---|
| Primary Owner | Full access, team management, only role that can transfer ownership | Exactly one |
| Owner | Full access + team management (within the rules below) | Unlimited |
| Editor | Edit settings and most operational data | Unlimited |
| Viewer | Read-only access | Unlimited |
Plus Firmly admins can do all of the above regardless of their own merchant role.
Role-gated actions
The rules below are enforced both in the UI (buttons hidden / disabled) and on the server:
| Action | Who can do it |
|---|---|
| Invite new members | Owner, Primary Owner, Firmly admin |
| Change roles | Owner, Primary Owner, Firmly admin (within their own level) |
| Remove members | Owner, Primary Owner, Firmly admin |
| Transfer ownership | Only the current Primary Owner |
| Cancel a pending invitation | Owner, Primary Owner, Firmly admin |
Editors and Viewers cannot invite or manage members.
Inviting a member
Clicking Invite Member opens a dialog that collects:
- Invitee’s email
- Role to grant (Owner / Editor / Viewer)
Primary Owner is not an invitable role — there is exactly one per merchant, and it only changes via ownership transfer. Submitting the form creates a pending invitation and dispatches the invitation email. The table refreshes to show the new pending row.
The invitee-facing flow works like this: the invitation goes to the invitee’s email and links to an invitation confirmation card. An existing Firmly user accepts in one click; a brand-new user is walked through profile creation before accepting.
Pending invitations
Pending invitations render alongside accepted members in the same table, marked with a “pending” status. Each pending row shows:
- Invitee email
- Role they’re invited as
- Who invited them
- When the link expires
Owners can cancel a pending invitation from the row action menu.
Per-member row actions
Row actions appear only for members whose role is below the current user’s. Within those rows, a user can promote a member up to (but not above) their own level:
| Action | What it does |
|---|---|
| Change Role | Opens a dialog that allows promoting / demoting to any role at or below the current user’s level |
| Remove Member | Opens a confirmation dialog that explicitly states the user will lose access immediately |
So an Owner manages Editors and Viewers and can promote one up to Owner (their own level), but Owners don’t see row actions on other Owners.
Ownership transfer
Only the current Primary Owner sees the Transfer Ownership action. The confirmation dialog is intentionally heavy — it states that:
- The current Primary Owner becomes an Owner
- The chosen member becomes the new Primary Owner
- The change is logged in the audit trail
Self-management guardrails
- A user cannot change their own role from this page
- A Primary Owner cannot remove themselves — they must transfer ownership first
These constraints ensure a merchant account always retains a Primary Owner who can perform owner-level operations.
Audit trail
Every team action (invite, accept, role change, removal, ownership transfer, invite cancellation) writes a typed event to the Audit logs with the actor’s email recorded.
Related
- Audit logs
- Domains and SSO — SSO enforcement affects how team members sign in
- Portal overview