Zappocity customers, products and subscriptions
Zappocity is the central site for every product it sells. It keeps the customers and what they buy; each product (Mailocity today) carries that out. See the platform design for where this is going: single sign-on, billing, coupons, rewards and support for every product.
The pieces
- People are Zappocity accounts: an email address and, once they set one, a password. A person need not have a mailbox.
- Organizations pay. Each has members with a role: owner (everything), admin (runs the Mailocity tenant, not its billing), billing (invoices and payment), support (tickets), member or guest. These are the same six roles a Mailocity tenant's mailboxes have. An organization always keeps at least one owner.
- Products are what Zappocity sells: Mailocity is available, xi.ht is coming. A product's plans come from the product itself (Mailocity's are the mail plans under Plans); its prices, per month and per year, are set here in US dollars.
- Subscriptions give an organization a product's plan. The product makes what it buys: for Mailocity, a tenant named after the organization.
- Mailboxes are Mailocity's email accounts, inside tenants. They are not Zappocity accounts: a person signs in to a mailbox with their Zappocity account (single sign-on), and that links the two. A person can sign in to several mailboxes; a mailbox nobody has signed in to with Zappocity is linked to nobody.
In short: an organization pays, a person signs in, a mailbox receives mail.
In the admin panel
Customers finds organizations, people and mailboxes with one search (name, email, address, tenant or customer number such as C-1042), in tabs: All, Organizations, People and Mailboxes, each with how many matched. It adds people and organizations. An organization's page shows its members (change a role or remove someone), its subscriptions and their history; a person's page shows their organizations and the Mailboxes they sign in to; a mailbox's page (under Mailboxes) shows the Zappocity account that signs in to it and that person's organizations.
- Subscribe picks a plan and makes a new tenant, or adopts an existing one: enter the tenant's id (from its page under Tenants) to bring a tenant under the organization, keeping its plan unless you pick another.
- Changing a subscription's plan changes the tenant's plan. A plan the tenant does not fit (more mailboxes than it allows, for example) is refused and nothing changes.
- Suspend a subscription to suspend its tenant; Resume to bring it back. Cancel suspends the tenant and ends its subscription, keeping its mail and its organization, so it can be adopted again later (by that organization or another).
- Suspend on the organization suspends every product it has; Make active brings back those whose subscription is active.
Every tenant has an organization
Every active Mailocity tenant belongs to a Zappocity organization, as one made through Zappocity does. For a tenant made any other way (Mailocity's sign-up and join pages, the admin API, before Zappocity accounts), the account sync job makes one within a minute:
- named after the tenant; personal for a free or solo plan, company for a team plan;
- owned by the Zappocity account of the tenant's first owner (else its first admin, else its first member). A tenant with no mailbox linked to a Zappocity account yet waits until it has one;
- with a Mailocity subscription to the tenant on its plan, with one seat per mailbox, that Zappocity does not bill (it never renews): the tenant goes on paying as it did. To bill it through Zappocity, set its renewal on the subscription.
A suspended tenant gets its organization once it is active again. A tenant whose subscription was canceled keeps its organization and gets no new subscription until one adopts it. The organization appears under Customers with the rest; the history says it was made for the tenant.
Members, roles and names stay the same
The account sync (every minute) keeps an organization and its Mailocity tenants the same, both ways:
- Members. Everyone with a mailbox in one of the organization's tenants (linked to their Zappocity account) is a member, marked from a mailbox. When their mailboxes there are gone, the sync removes them. Members added on Zappocity without a mailbox (a bookkeeper with the billing role, say) stay. Shared mailboxes are not people and are left out.
- Roles. A mailbox's role and its owner's role in the organization are the same six (owner, admin, billing, support, member, guest). Whichever was changed last wins: a role set on the organization's page reaches all that person's mailboxes in its tenants within a minute, and one set on a mailbox comes back to the organization. A person with several mailboxes there has the highest of their roles. From before the sync, when neither side was changed since, the higher role wins on both. The organization's last owner stays owner on Zappocity, whatever their mailbox's role, until it has another.
- Names. The organization's name and its tenant's (when it has one tenant), and a person's name and the display name of their mailbox at their own email address, follow whichever was changed last. An empty name never replaces one.
Removing on Zappocity a member who has a mailbox in one of the organization's tenants is refused: delete the mailbox in Mailocity, or unlink it from the Zappocity account, first. When a tenant moves to another organization (its subscription canceled and adopted from the other), its people move with it, and leave the old one.
Merging duplicates
When one company was recorded as two organizations, or one person has two Zappocity accounts, merge them. On the page of the one to keep, choose Merge a duplicate at the top (or scroll to Merge a duplicate into this one), search for the other, choose Merge into ... and type MERGE.
- Organizations: the other's members (a person in both keeps the stronger role), subscriptions, invoices, credit, coupons, help desks, DNS accounts, tickets and Mailocity tenants move. Its balance moves by an adjustment entry on each ledger (ledger entries are never changed). The one kept keeps its name, billing details and payment method. Needs the billing permission.
- People: the other's memberships, help desk seats, tickets, points, badges, invitations, sign-in history and linked mailboxes move. The one kept keeps its email address, password and two-step sign-in; the other is signed out and its email address can be used again. Needs the tenants permission. Neither may be deleted or waiting to be. A tenant's mailboxes stay with the tenant: if the other is linked to a mailbox of a tenant the one kept is not on (it has no mailbox there and is not in the tenant's organization), the merge is refused, naming the mailbox. Unlink the mailbox first, or add the person to the tenant.
- The one merged in is kept as history, marked merged, with a link to the one kept; it no longer appears in lists (a person is still found by customer number). A merge cannot be undone, and the History card records what moved.
- If the mail side could not be reached, the merge says so: merge again to finish moving the mailboxes or tenants.
A mailbox linked to the wrong person
A mailbox is linked to the Zappocity account that signs in to it. To take it away (such as a tenant's mailbox merged into someone's personal account), use Unlink next to it in the person's Mailboxes card, or Unlink from ... on the mailbox's page under Mailboxes (corpsuite mailbox zappocity unlink USER). That person can no longer open it with their Zappocity sign-in, and its webmail sessions end. Within a minute the account sync gives the mailbox a Zappocity account of its own address and password, as it does for any mailbox. Memberships that moved with a merge stay: remove the person from the tenant's organization on its page if they should not be in it.
From the command line: corpsuite zappocity org merge ORG-ID from=OTHER-ORG-ID and corpsuite zappocity person merge PERSON-ID from=OTHER-PERSON-ID.
Products sets each product's name, status, site and description, and each plan's prices. Only a product with a module on this server can be Available.
Every change is recorded in a history that cannot be edited, with who made it: the History card on each page, or corpsuite zappocity audit.
From the command line
sudo corpsuite zappocity person add email=amy@acme.com name="Amy" verified:=true
sudo corpsuite zappocity org add name="Acme" owner=amy@acme.com
sudo corpsuite zappocity subscribe ORG-ID product=mailocity plan=team period=year
sudo corpsuite zappocity subscribe ORG-ID product=mailocity resourceRef=TENANT-ID
sudo corpsuite zappocity price set mailocity team month:=1200 year:=12000
sudo corpsuite zappocity subscription set SUBSCRIPTION-ID status=canceled
sudo corpsuite zappocity org merge KEEP-ORG-ID from=DUPLICATE-ORG-ID
sudo corpsuite zappocity person merge KEEP-PERSON-ID from=DUPLICATE-PERSON-ID
The API is described in api/platform.yaml (/v1/platform). Staff need read to look, plans to change products and prices, and tenants for the rest. Tenants cannot use it.
Signing in to Zappocity
The account page is /account on the Zappocity host (such as https://zappo.city/account; the homepage's Sign in goes there). People can:
- Create an account with an email address and a password of at least 12 characters. A link is emailed to confirm the address; opening it signs them in. Until then the account works but is unconfirmed, and products will not trust its address. Signing up with an address that already has an account answers the same, and emails its owner instead, so the page never reveals who has an account.
- Sign in. Ten wrong passwords in a row lock the account for 15 minutes (it then answers like too many attempts, even with the right password); attempts from one address are throttled too. The platform's captcha settings for sign-up, sign-in and resets apply.
- Reset a forgotten password with an emailed link that works once, for an hour, and signs out every device.
- Turn on two-step sign-in with an authenticator app (scan the QR code, enter a code, keep the ten recovery codes). Signing in then needs a code as well; a wrong code counts like a wrong password, and each code works once. Every product signed in to with Zappocity is protected by it, and products are told it was used (the
amrclaim). Turning it on signs out every other device. A confirmation link never signs in to an account with two-step sign-in. Staff can turn it off for someone who has lost their phone and codes (Turn off two-step sign-in on the person's page, after checking who is asking). - Add security keys and passkeys (WebAuthn, FIDO2) under Security keys and passkeys: a hardware key such as a YubiKey, or a passkey in 1Password, iCloud Keychain, Google Password Manager or Windows Hello. Any key makes signing in take a second step (the browser asks for the key after the password; the authenticator app's code still works if both are set up). A passkey also signs in on its own with Sign in with a passkey: no email or password, and since it checks a PIN or fingerprint it counts as two-step sign-in for every product. Adding or removing a key needs the password and is told by email; the first key signs every other device out and gives ten recovery codes. Up to 20 keys; a key that looks copied (its counter goes back) is refused. Keys belong to the site's host name: add them on zappo.city.
- Security alerts: an email when the account is signed in to from a device (address and browser) not seen in the last 90 days, unless turned off; changes to the password, two-step sign-in and keys are always emailed.
- Invite friends: a personal sign-up link (
#signup&invite=CODE) to share or send by email (20 a day, confirmed address needed); who joins through it is recorded for referral rewards. - Signing out everywhere (and a new password, or two-step sign-in turned on) also ends the person's webmail sessions.
- See their organizations (owners and billing members also see the products), change their name and password (other devices are signed out and the address is told), see where they are signed in and sign out everywhere else, and see their recent sign-ins.
Zappocity's mail (confirmation and reset links) comes from the platform's notice address (noticeFrom in the settings) under the name Zappocity.
Not yet
Nothing is charged yet: billing, coupons and rewards come next. Single sign-on is described in One sign-in for everything.