Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/monetize

crates/monetize-server/src/services/signup.rs

//! **`Signup.Status`** — what became of a vendor checkout session, and
//! **`SignupAdmin.List`** — the operator's read of the same store.
//!
//! # Why `UNKNOWN` is not an error
//!
//! The return page opens the moment the vendor redirects the browser back, and
//! the webhook is a SEPARATE delivery over a different connection. Which of the
//! two arrives first is the vendor's business and it is regularly the page. So
//! a session nobody has heard of answers `UNKNOWN` with an empty everything —
//! not `NotFound`, which a polling page would have to special-case as "keep
//! going" while every other `NotFound` in this API means "stop". The page polls
//! until it sees `CREATED` or `REFUSED`, and `UNKNOWN` and `PENDING` are both
//! "not yet".
//!
//! # The e-mail is on the operator's wire only
//!
//! [`crate::signup::SignupRecord`] keeps the address the buyer typed (and
//! confirmed) before the checkout. `Status` never carries it: it is polled by a
//! page holding nothing but a session id the vendor put in a URL. `List` does,
//! behind the operator bearer — changed 2026-09-15, when the first paid signup
//! showed an operator an account with no way to know whom to write to.

use std::sync::Arc;

use monetize_proto::signup_admin_server::SignupAdmin;
use monetize_proto::signup_server::Signup;
use monetize_proto::{self as pb};
use tonic::{Request, Response, Status};

use super::blocking;
use crate::signup::{SignupRecord, SignupState};
use crate::state::AppState;
use crate::store::StoreError;

pub struct SignupService(pub Arc<AppState>);
pub struct SignupAdminService(pub Arc<AppState>);

fn store_err(e: StoreError) -> Status {
    Status::internal(format!("signup store: {e}"))
}

/// The wire state of a record. One writer for both services (one implementation).
fn state_of(rec: &SignupRecord) -> pb::signup_status_response::State {
    use pb::signup_status_response::State as S;
    match rec.state {
        SignupState::Pending => S::Pending,
        SignupState::Created { .. } => S::Created,
        SignupState::Refused { .. } => S::Refused,
    }
}

/// The wire refusal of a record. `REFUSAL_UNSPECIFIED` for anything that is not
/// a refusal at all, which is what proto3's zero value means here.
fn refusal_of(rec: &SignupRecord) -> pb::signup_status_response::Refusal {
    use pb::signup_status_response::Refusal as R;
    match rec.state {
        SignupState::Refused { refusal, .. } => match refusal {
            crate::signup::Refusal::Unknown => R::Unspecified,
            crate::signup::Refusal::Name => R::Name,
            crate::signup::Refusal::Final => R::Final,
        },
        _ => R::Unspecified,
    }
}

/// What the RETURN PAGE is told — a customer's surface, so `reason` and
/// `words` are the customer's sentences (`crate::signup::customer_words`) and
/// never the product's own message. The operator's copy is [`row_to_pb`].
fn status_response(
    store: &crate::signup::SignupStore,
    rec: &SignupRecord,
    now_ms: i64,
) -> pb::SignupStatusResponse {
    let (words, reason) = crate::signup::customer_words(store, rec, now_ms);
    let (words_if_silent, silent_after_ms) = crate::signup::words_ahead(store, rec, now_ms);
    let (username, namespace) = match &rec.state {
        SignupState::Pending | SignupState::Refused { .. } => (String::new(), String::new()),
        // The username the PRODUCT settled on, not the one the customer typed:
        // they are usually the same and the difference is the whole reason
        // `SignupOutcome::Created` carries both.
        SignupState::Created {
            namespace,
            username,
            ..
        } => (username.clone(), namespace.clone()),
    };
    pb::SignupStatusResponse {
        state: state_of(rec) as i32,
        username,
        namespace,
        reason,
        product: rec.signup.product.clone(),
        plan: rec.signup.plan.clone(),
        paid_at_unix_ms: rec.signup.paid_at_unix_ms,
        refusal: refusal_of(rec) as i32,
        words,
        words_if_silent,
        silent_after_ms,
    }
}

/// **A "not now" on a customer's surface**: the real reason to the log and to
/// `functional_status`, the customer's sentence on the wire. `what` names the
/// verb for the operator's line.
fn unavailable_for_customer(what: &str, why: &str, customer: &str) -> Status {
    skidbladnir::functional_status(
        "monetize-server/signup",
        what,
        true,
        &format!("unavailable: {why}"),
    );
    eprintln!("monetize-server: signup {what} unavailable: {why}");
    Status::unavailable(customer)
}

/// **The plan a `Signup.Start` sells**, and the refusal when that is not one
/// thing.
///
/// Empty means "the only one". A console carries no price list — the whole
/// reason `[signups.<product>.plans]` lives here is that the price is the operator's — and
/// a deployment that sells exactly one plan should not make every caller name
/// it. Two plans and no name is a refusal that LISTS them, never a pick:
/// guessing which of two prices a stranger meant to pay is the one mistake that
/// cannot be undone once the card is charged.
fn plan_for<'a>(
    plans: &'a std::collections::BTreeMap<String, crate::config::SignupPlan>,
    asked: &str,
) -> Result<(&'a str, crate::config::SignupPlan), Status> {
    let known: Vec<&str> = plans.keys().map(String::as_str).collect();
    if !asked.is_empty() {
        return plans
            .get_key_value(asked)
            .map(|(k, v)| (k.as_str(), *v))
            .ok_or_else(|| {
                Status::failed_precondition(format!(
                    "plan {asked:?} is not sold here; [signups.<product>.plans] names {known:?}"
                ))
            });
    }
    match known.as_slice() {
        [] => Err(Status::unimplemented(
            "this deployment sells no signups: [signups.<product>.plans] is empty, so there is nothing a checkout page could charge for",
        )),
        [only] => Ok((*only, plans[*only])),
        _ => Err(Status::failed_precondition(format!(
            "this deployment sells {} signup plans and the request named none; ask for one of {known:?}",
            known.len()
        ))),
    }
}

/// **[`plan_for`], told the customer's market** (g-currencies, money
/// 2026-09-28): with no plan named and several sold, the plan priced in THAT
/// market's currency — one plan per market is how the Danish company sells a
/// signup to a Swede in SEK, a Finn in EUR and a Dane in DKK. A named plan
/// wins; one plan is the plan; no market is the deployment's DEFAULT market
/// when each market sells exactly one plan (release-3); otherwise (or none
/// priced for it) it falls back to [`plan_for`]'s refusal that lists them.
fn plan_for_market<'a>(
    plans: &'a std::collections::BTreeMap<String, crate::config::SignupPlan>,
    asked: &str,
    market: Option<monetize_pay::Market>,
    default_market: monetize_pay::Market,
) -> Result<(&'a str, crate::config::SignupPlan), Status> {
    // An account at the shop is taken only when it is NAMED: a request that
    // names no plan (the functional test, an older page) is choosing ROOM.
    if asked.is_empty() && plans.values().any(crate::signup::is_account_plan) {
        let selling: std::collections::BTreeMap<String, crate::config::SignupPlan> = plans
            .iter()
            .filter(|(_, p)| !crate::signup::is_account_plan(p))
            .map(|(k, v)| (k.clone(), *v))
            .collect();
        return plan_for_market(&selling, asked, market, default_market).map(|(id, p)| {
            (
                plans
                    .get_key_value(id)
                    .map(|(k, _)| k.as_str())
                    .unwrap_or_default(),
                p,
            )
        });
    }
    if asked.is_empty() && plans.len() > 1 {
        // No market named (a console whose browser language names none, the
        // functest): the DEFAULT market's plan — only when every market sells
        // exactly one plan, so "the plan of that market" means one thing.
        let one_per_market = {
            let mut seen = std::collections::BTreeSet::new();
            plans
                .values()
                .all(|p| seen.insert(format!("{:?}", p.currency.market())))
        };
        let market = market.or_else(|| one_per_market.then_some(default_market));
        if let Some(m) = market {
            let mine: Vec<(&String, &crate::config::SignupPlan)> = plans
                .iter()
                .filter(|(_, p)| p.currency.market() == m)
                .collect();
            if let [(k, p)] = mine.as_slice() {
                return Ok((k.as_str(), **p));
            }
        }
    }
    plan_for(plans, asked)
}

/// **One plan a new account may be bought on, as the sign-up page shows it**
/// (`Signup.Plans`, 2026-10-07): the page writes no price and no size of its own.
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct PlanOnOffer {
    pub id: String,
    pub name: String,
    pub resources_words: String,
    pub price_words: String,
    pub cap_bytes: u64,
    pub period_days: u32,
}

/// The room as words, in the GB the front page's offer names (`10 GB`).
fn room_words(bytes: u64) -> String {
    let gib = bytes as f64 / (1u64 << 30) as f64;
    if (gib - gib.round()).abs() < 0.05 {
        format!("{} GB", gib.round() as u64)
    } else {
        format!("{gib:.1} GB")
    }
}

/// The period a plan's price covers, as words.
fn period_words(days: u32) -> String {
    match days {
        28..=31 => "a month".into(),
        365 | 366 => "a year".into(),
        1 => "a day".into(),
        n => format!("for {n} days"),
    }
}

/// The product's plans that sell ROOM — a plan with no price (an account at
/// the shop) is never on offer as room.
fn room_plans<'a>(
    plans: &'a std::collections::BTreeMap<String, crate::config::SignupPlan>,
    product: &str,
) -> Vec<(&'a String, &'a crate::config::SignupPlan)> {
    let product = product.trim();
    plans
        .iter()
        .filter(|(id, _)| product.is_empty() || id.split('/').next() == Some(product))
        .filter(|(_, p)| p.amount_minor > 0)
        .collect()
}

/// **The ONE market a new account's plans are offered in** (the sign-up page,
/// owner 2026-10-08: its − / + steps through SIZES, never through
/// currencies): the market asked when it has plans on offer, else the
/// deployment's default market when it has, else the first market that has
/// any (SE, FI, DK). `None`: nothing is on offer.
pub(crate) fn market_on_offer(
    plans: &std::collections::BTreeMap<String, crate::config::SignupPlan>,
    product: &str,
    market: Option<monetize_pay::Market>,
    default_market: monetize_pay::Market,
) -> Option<monetize_pay::Market> {
    use monetize_pay::Market;
    let on_offer = room_plans(plans, product);
    market
        .into_iter()
        .chain([default_market, Market::Se, Market::Fi, Market::Dk])
        .find(|m| on_offer.iter().any(|(_, p)| p.currency.market() == *m))
}

/// **The plans on offer to a new account**: the product's own (`gunnar/…`;
/// every plan when none is named), in ONE market — [`market_on_offer`]'s:
/// the customer's where it has any, else the deployment's default — smallest
/// room first, then cheapest. Never a mix of currencies (test2, 2026-10-08:
/// every market's plans to a browser naming none, and the page's + stepped
/// SEK → EUR → DKK).
pub(crate) fn plans_on_offer(
    plans: &std::collections::BTreeMap<String, crate::config::SignupPlan>,
    product: &str,
    market: Option<monetize_pay::Market>,
    default_market: monetize_pay::Market,
) -> Vec<PlanOnOffer> {
    let Some(one) = market_on_offer(plans, product, market, default_market) else {
        return Vec::new();
    };
    // An account at the shop sells no room: never on offer as room.
    let mut shown: Vec<(&String, &crate::config::SignupPlan)> = room_plans(plans, product)
        .into_iter()
        .filter(|(_, p)| p.currency.market() == one)
        .collect();
    shown.sort_by_key(|(id, p)| (p.cap_bytes, p.amount_minor, (*id).clone()));
    shown
        .into_iter()
        .map(|(id, p)| PlanOnOffer {
            id: id.clone(),
            name: room_words(p.cap_bytes),
            resources_words: format!(
                "{} of room, kept on the server and its replica",
                room_words(p.cap_bytes)
            ),
            price_words: format!(
                "{} {}",
                monetize_pay::Money {
                    minor: p.amount_minor,
                    currency: p.currency
                }
                .in_words(),
                period_words(p.period_days)
            ),
            cap_bytes: p.cap_bytes,
            period_days: p.period_days,
        })
        .collect()
}

/// **`Signup.Start` for an account at the shop** ([`crate::signup::ACCOUNT_VENDOR`]):
/// a plan with no price and no room. The sink makes the account at once, the
/// record is CREATED under a session of the shop's own, and the answer leads to
/// the console's own welcome page (`success_url`), where the passkey is
/// registered as after any signup. A sink that refuses makes nothing that is
/// kept; nothing is owed, because nothing was paid.
fn start_account(
    s: &AppState,
    r: &pb::StartSignupRequest,
    plan_id: &str,
    plan: &crate::config::SignupPlan,
    product: &str,
    email: String,
    (estate, site): (Option<&str>, Option<&str>),
) -> Result<pb::StartSignupResponse, Status> {
    if plan.cap_bytes != 0 {
        return Err(Status::failed_precondition(format!(
            "plan {plan_id:?} has room and no price: room is never given away here — an account at the shop holds none ([signups.<product>.plans] amount_minor = 0 needs cap_bytes = 0)"
        )));
    }
    let session = crate::signup::account_session().map_err(|why| {
        Status::unavailable(format!("no session could be made for the account: {why}"))
    })?;
    let now = s.now() as i64;
    let signup = monetize_pay::signup::PaidSignup {
        vendor: crate::signup::ACCOUNT_VENDOR.to_owned(),
        session: session.clone(),
        reference: String::new(),
        email,
        username: r.username.clone(),
        product: product.to_owned(),
        plan: plan_id.to_owned(),
        amount: monetize_pay::Money {
            minor: 0,
            currency: plan.currency,
        },
        tax: monetize_pay::Money {
            minor: 0,
            currency: plan.currency,
        },
        paid_at_unix_ms: now,
        customer_country: None,
    };
    match make_account(s, &signup, None, estate, &r.success_url, site)? {
        Made::Created | Made::Pending => Ok(pb::StartSignupResponse {
            url: r.success_url.replace("{session}", &session),
            session,
        }),
        Made::NameTaken(why) => Err(Status::failed_precondition(why)),
        Made::Refused => Err(Status::failed_precondition(
            crate::signup::words::COULD_NOT_CREATE,
        )),
    }
}

/// What [`make_account`] did.
enum Made {
    /// The account exists (CREATED).
    Created,
    /// Kept PENDING: a pulled product's main makes it from the order it pulls.
    Pending,
    /// The name was taken (the customer's sentence).
    NameTaken(String),
    /// The sink refused; nothing is kept.
    Refused,
}

/// **The account at the shop, made** (one writer for [`start_account`] and the card check's
/// finish): the sink makes it on the estate the caller is, the record is kept under
/// [`crate::signup::ACCOUNT_VENDOR`] with the checked card on it (`card`), and the sign-in
/// link (`success_url` with the session) is mailed. A sink that is unavailable is
/// UNAVAILABLE, and nothing is kept.
fn make_account(
    s: &AppState,
    signup: &monetize_pay::signup::PaidSignup,
    card: Option<&crate::signup::CardOnFile>,
    estate: Option<&str>,
    success_url: &str,
    site: Option<&str>,
) -> Result<Made, Status> {
    let now = s.now() as i64;
    let session = signup.session.as_str();
    let to = signup.email.clone();
    let kept = |state: Option<SignupState>| -> Result<(), Status> {
        s.signups
            .record_pending_on(signup, now, estate)
            .map_err(store_err)?;
        if let Some(card) = card {
            s.signups
                .set_card(crate::signup::ACCOUNT_VENDOR, session, card)
                .map_err(store_err)?;
        }
        if let Some(state) = state {
            s.signups
                .set(crate::signup::ACCOUNT_VENDOR, session, state)
                .map_err(store_err)?;
        }
        Ok(())
    };
    // ★ Made on the estate the caller is (its own bearer), and kept with the record so a
    // later settle asks the same estate (ONE box, several sites of one product).
    match s.signup_sink.paid_on(signup, estate) {
        Ok(monetize_pay::signup::SignupOutcome::Created {
            namespace,
            username,
        }) => {
            kept(Some(SignupState::Created {
                namespace,
                username,
                at_unix_ms: now,
            }))?;
            eprintln!(
                "monetize-server: an account at the shop was made for {:?} ({}{})",
                signup.username,
                crate::signup::ACCOUNT_VENDOR,
                if card.is_some() { ", card checked" } else { "" }
            );
            mail_sign_in_link(
                s,
                &signup.product,
                &signup.username,
                &to,
                &success_url.replace("{session}", session),
                site,
            );
            Ok(Made::Created)
        }
        Err(monetize_pay::signup::SignupError::NameTaken(why)) => Ok(Made::NameTaken(why)),
        // **A pulled product** (5.4, G1): the estate's main makes the account from the order
        // it pulls, so the record is kept PENDING under this session — `settle_pending` (and
        // the welcome page's `Status` poll) finishes it once the main has acked. Answering
        // UNAVAILABLE here kept nothing: the next Start minted a new session, a second order,
        // and found the name taken by the first (money-flow 2026-10-10).
        Err(monetize_pay::signup::SignupError::Unavailable(why))
            if why.starts_with(crate::signup_pull::QUEUED) =>
        {
            kept(None)?;
            eprintln!(
                "monetize-server: an account at the shop for {:?} is pending ({}): {why}",
                signup.username,
                crate::signup::ACCOUNT_VENDOR
            );
            mail_sign_in_link(
                s,
                &signup.product,
                &signup.username,
                &to,
                &success_url.replace("{session}", session),
                site,
            );
            Ok(Made::Pending)
        }
        Err(
            monetize_pay::signup::SignupError::Unavailable(why)
            | monetize_pay::signup::SignupError::Maintenance(why),
        ) => Err(unavailable_for_customer(
            "account",
            &why,
            crate::signup::words::SHOP_DOWN,
        )),
        Err(other) => {
            eprintln!(
                "monetize-server: an account at the shop for {:?} was refused by the sink: {other}",
                signup.username
            );
            Ok(Made::Refused)
        }
    }
}

/// ★ **Pay once** (owner 2026-10-22, `DESIGN-PRIVATE-PAY-ONCE.md`): what a refused visitor
/// reads where this shop cannot make an account with a private order (no account plan).
pub const NO_ACCOUNT_WITH_ORDER: &str =
    "An account cannot be made with this order here. Sign in to your account, or create it first.";

/// ★ **An estate order's own cancel page** (A10 row 6, `EstateOrder.Start{cancel_url}`): empty
/// stays empty (the vendor's own); else an https page on the order's site — the calling
/// estate's, else the sold product's home ([`site_refusal`]) — or the refusal.
pub(crate) fn order_cancel_page(
    s: &AppState,
    estate: Option<&str>,
    cancel_url: &str,
) -> Result<String, Status> {
    let cancel_url = cancel_url.trim();
    if cancel_url.is_empty() {
        return Ok(String::new());
    }
    if !cancel_url.starts_with("https://") || cancel_url.contains(char::is_whitespace) {
        return Err(Status::invalid_argument(
            "the cancel page is an https:// address",
        ));
    }
    let site_estate = match estate {
        Some(e) => Some(e.to_owned()),
        None => s.sold_product().ok().and_then(|p| s.registry.home_of(p)),
    };
    // As a signup's pages: checked against the site where one is known ([`page_refusal`]).
    match site_estate
        .as_deref()
        .and_then(|e| s.registry.site_of(e))
        .and_then(|site| site_refusal(&site, "", cancel_url))
    {
        Some(why) => Err(Status::invalid_argument(why)),
        None => Ok(cancel_url.to_owned()),
    }
}

pub(crate) fn new_account_for_order(
    s: &AppState,
    estate: Option<&str>,
    username: &str,
    email: &str,
    welcome_url: &str,
) -> Result<crate::estate_order::account::NewAccount, Status> {
    let product = match estate.and_then(|e| s.registry.product_of_estate(e)) {
        Some(p) => p,
        None => s
            .sold_product()
            .map_err(Status::failed_precondition)?
            .to_owned(),
    };
    if !s.signup_sink.creates_accounts_for(&product) {
        return Err(no_sink(&product));
    }
    let Some((plan, terms)) = s
        .signup_plans
        .snapshot_of(&product)
        .into_iter()
        .find(|(_, p)| crate::signup::is_account_plan(p) && p.cap_bytes == 0)
    else {
        eprintln!("monetize-server: a private order with a new account was refused: {product} sells no account plan ([signups.{product}.plans] amount_minor = 0, cap_bytes = 0)");
        return Err(Status::failed_precondition(NO_ACCOUNT_WITH_ORDER));
    };
    let site_estate: Option<String> = match estate {
        Some(e) => Some(e.to_owned()),
        None if s.registry.sold_per_site(&product) => {
            return Err(Status::permission_denied(format!("REFUSED [estate-unnamed] {product} is sold for several sites here and this order names none: its account and its sign-in mail are only ever on its estate's site")))
        }
        None => s.registry.home_of(&product),
    };
    let site = site_estate.as_deref().and_then(|e| s.registry.site_of(e));
    let welcome_url = welcome_url.trim();
    if !welcome_url.starts_with("https://") || !welcome_url.contains("{session}") {
        return Err(Status::invalid_argument(
            "the welcome page is an https:// address with {session} in it",
        ));
    }
    if let Some(why) = site
        .as_deref()
        .and_then(|site| page_refusal(site, welcome_url, ""))
    {
        return Err(Status::invalid_argument(why));
    }
    if let Some(why) = name_refusal(s, &product, username, estate)? {
        return Err(Status::failed_precondition(why));
    }
    let email = email.trim();
    if let Some(why) = monetize_pay::signup::email_refusal(email) {
        return Err(Status::invalid_argument(why));
    }
    match s.signups.has_account_with_email_on(
        &product,
        estate,
        s.registry.home_of(&product).as_deref(),
        email,
    ) {
        Ok(false) => {}
        Ok(true) => {
            return Err(Status::failed_precondition(
                crate::signup::words::EMAIL_HAS_ACCOUNT,
            ))
        }
        Err(e) => return Err(store_err(e)),
    }
    if let Some(h) = s
        .signups
        .name_hold(
            &product,
            &hold_site(s, &product, estate),
            username,
            s.now() as i64,
        )
        .map_err(store_err)?
    {
        if !h.email.trim().eq_ignore_ascii_case(email) {
            return Err(Status::failed_precondition(
                crate::signup::words::NAME_BEING_BOUGHT,
            ));
        }
    }
    let session = crate::signup::account_session().map_err(|why| {
        Status::unavailable(format!("no session could be made for the account: {why}"))
    })?;
    Ok(crate::estate_order::account::NewAccount {
        product,
        plan,
        currency: terms.currency,
        username: username.to_owned(),
        email: email.to_owned(),
        welcome_url: welcome_url.to_owned(),
        session,
        estate: estate.map(str::to_owned),
        site,
        back_to: String::new(),
        cancel_to: String::new(),
        test_payer: String::new(),
    })
}

/// ★ What a signed-in account reads when this shop holds no address for it and none was sent.
pub const NO_EMAIL_HERE: &str = "This account has no e-mail address here for the order's mail. Contact us, and nothing has been charged.";

/// ★ **The address a PROVEN account's order mails** (owner 2026-10-22: "man skall inte kunna
/// byta email"): the one the account was made with — the newest signup that created it on its
/// site — whatever the page sent. Only an account this shop holds no address for (one an
/// operator made by hand) takes the address an older page still sends; none sent: refused.
pub(crate) fn account_email(
    s: &AppState,
    estate: Option<&str>,
    account: &str,
    sent: &str,
) -> Result<String, Status> {
    let product = match estate.and_then(|e| s.registry.product_of_estate(e)) {
        Some(p) => p,
        None => s
            .sold_product()
            .map_err(Status::failed_precondition)?
            .to_owned(),
    };
    let home = s.registry.home_of(&product);
    let away = estate.filter(|e| home.as_deref() != Some(*e));
    let namespace = crate::site_ticket::tenant_on(s, &product, away, account)
        .unwrap_or_else(|_| account.to_owned());
    match s
        .signups
        .email_of(&product, &namespace)
        .map_err(store_err)?
    {
        Some(own) => Ok(own),
        None if !sent.trim().is_empty() => Ok(sent.trim().to_owned()),
        None => Err(Status::failed_precondition(NO_EMAIL_HERE)),
    }
}

/// ★ **Pay once: the name held for the order's payment page** — at least
/// [`crate::signup::NAME_HOLD_MS`], and as long as the page may be paid (`page_ms`).
pub(crate) fn hold_for_order(
    s: &AppState,
    na: &crate::estate_order::account::NewAccount,
    page_ms: u64,
) -> Result<(), Status> {
    let until = s.now() as i64 + crate::signup::NAME_HOLD_MS.max(page_ms as i64 + 5 * 60 * 1000);
    let hold = crate::signup::NameHold {
        vendor: crate::signup::ACCOUNT_VENDOR.to_owned(),
        session: na.session.clone(),
        email: na.email.clone(),
        until_unix_ms: until,
    };
    s.signups
        .hold_name(
            &na.product,
            &hold_site(s, &na.product, na.estate.as_deref()),
            &na.username,
            &hold,
        )
        .map_err(store_err)
}

/// ★ **Pay once: a held name let go** (the order was not started after all).
pub(crate) fn release_order_hold(s: &AppState, na: &crate::estate_order::account::NewAccount) {
    if let Err(e) = s
        .signups
        .release_names_of(crate::signup::ACCOUNT_VENDOR, &na.session)
    {
        eprintln!(
            "monetize-server: the name held for {:?} was not let go ({e}); it lapses by itself",
            na.username
        );
    }
}

/// ★ **Pay once: the account a PAID private order makes** (owner 2026-10-22), as a paid
/// signup's: the sink makes it on the order's site (a pulled product's main when it next calls
/// monetize: PENDING, settled by [`crate::signup::settle_pending`]), its record is kept under
/// [`crate::signup::ACCOUNT_VENDOR`] with the order's session, and its sign-in link is mailed.
/// ONCE: a session that already has its record makes nothing. `Err`: why the paid order waits
/// (an ALERT when the account cannot be made at all — never laid for another's account).
pub(crate) fn make_paid_order_account(
    s: &AppState,
    reference: &str,
    na: &crate::estate_order::account::NewAccount,
) -> Result<(), String> {
    if s.signups
        .get(crate::signup::ACCOUNT_VENDOR, &na.session)
        .map_err(|e| format!("paid; its account cannot be looked up yet: signup store: {e}"))?
        .is_some()
    {
        return Ok(());
    }
    let zero = monetize_pay::Money {
        minor: 0,
        currency: na.currency,
    };
    let signup = monetize_pay::signup::PaidSignup {
        vendor: crate::signup::ACCOUNT_VENDOR.to_owned(),
        session: na.session.clone(),
        reference: reference.to_owned(),
        email: na.email.clone(),
        username: na.username.clone(),
        product: na.product.clone(),
        plan: na.plan.clone(),
        amount: zero,
        tax: zero,
        paid_at_unix_ms: s.now() as i64,
        customer_country: None,
    };
    match make_account(s, &signup, None, na.estate.as_deref(), &na.welcome_url, na.site.as_deref()) {
        Ok(Made::Created | Made::Pending) => {
            release_order_hold(s, na);
            Ok(())
        }
        Ok(Made::NameTaken(why)) => Err(format!("ALERT estate-orders.account-not-made: paid, and its account {:?} could not be made ({why}); an operator sets it right — nothing is laid for another's account", na.username)),
        Ok(Made::Refused) => Err(format!("ALERT estate-orders.account-not-made: paid, and the sink refused its account {:?}; an operator sets it right — nothing is laid", na.username)),
        Err(status) => Err(format!("paid; its account {:?} is not made yet: {}", na.username, status.message())),
    }
}

/// ★ **The vendor that checks a card for a free account on this site** (owner 2026-10-15),
/// or `Ok(None)` where the product is routed to NO vendor at all (an open build that takes
/// no money anywhere — the account is made as before). A site that sells through a vendor
/// makes a free account ONLY after that vendor checked a card.
fn card_check_vendor<'s>(
    s: &'s AppState,
    product: &str,
    estate: Option<&str>,
) -> Result<Option<monetize_pay::Vendor<'s>>, Status> {
    match s.registry.route_for(product, estate) {
        Err(why) if why == s.registry.route_said(product) => Ok(None),
        Err(why) => Err(Status::permission_denied(why)),
        Ok(route) => match s.registry.find_vendor(&route) {
            Some(v) => Ok(Some(v)),
            None => {
                eprintln!("monetize-server: a free {product} account was asked for and its vendor {route:?} is not loaded: no card check, no account");
                Err(Status::failed_precondition(
                    crate::signup::words::CARD_CHECK_NOT_HERE,
                ))
            }
        },
    }
}

/// ★ **`Signup.Start` for a free account on a site that sells through a vendor** (owner
/// 2026-10-15): nothing is made yet. The vendor mints a CARD CHECK — a page where the card is
/// checked and saved and nothing is charged (Stripe: Checkout `mode=setup`) — returning to
/// the console's own welcome page; what the account will be is kept here
/// ([`crate::signup::CardCheckStarted`]). The account is made when the welcome page asks
/// `Signup.Status` and the vendor says the card is checked ([`finish_card_check`]).
fn start_card_check(
    s: &AppState,
    vendor: monetize_pay::Vendor<'_>,
    r: &pb::StartSignupRequest,
    (plan_id, plan): (&str, &crate::config::SignupPlan),
    product: &str,
    email: String,
    (estate, site): (Option<&str>, Option<&str>),
) -> Result<pb::StartSignupResponse, Status> {
    if plan.cap_bytes != 0 {
        return Err(Status::failed_precondition(format!(
            "plan {plan_id:?} has room and no price: room is never given away here — an account at the shop holds none ([signups.<product>.plans] amount_minor = 0 needs cap_bytes = 0)"
        )));
    }
    let host = site.map(str::to_owned).unwrap_or_else(|| {
        r.success_url
            .split("://")
            .nth(1)
            .unwrap_or_default()
            .split('/')
            .next()
            .unwrap_or_default()
            .to_owned()
    });
    let order = monetize_pay::signup::SignupOrder {
        username: r.username.clone(),
        email: email.clone(),
        product: product.to_owned(),
        plan: plan_id.to_owned(),
        amount: monetize_pay::Money {
            minor: 0,
            currency: plan.currency,
        },
        market: plan.currency.market(),
        description: format!("Card check for your free account at {host} — nothing is charged"),
        success_url: r.success_url.clone(),
        cancel_url: r.cancel_url.clone(),
    };
    match vendor.card_check_page(&order) {
        Ok(Some(page)) if !page.session.trim().is_empty() => {
            let started = crate::signup::CardCheckStarted {
                product: product.to_owned(),
                plan: plan_id.to_owned(),
                username: r.username.clone(),
                email,
                currency: plan.currency,
                estate: estate.map(str::to_owned),
                site: site.map(str::to_owned),
                success_url: r.success_url.clone(),
                started_at_unix_ms: s.now() as i64,
                refused: None,
            };
            s.signups
                .record_card_check(vendor.name, &page.session, &started)
                .map_err(store_err)?;
            hold_for_page(
                s,
                product,
                estate,
                &r.username,
                &started.email,
                vendor.name,
                &page.session,
            )?;
            eprintln!("monetize-server: a card check for a free {product} account {:?} was minted at {} ({})", r.username, vendor.name, page.session);
            Ok(pb::StartSignupResponse {
                url: page.url,
                session: page.session,
            })
        }
        Ok(_) => {
            eprintln!("monetize-server: vendor {:?} checks no card (or named no session): no free {product} account is made without one", vendor.name);
            Err(Status::failed_precondition(
                crate::signup::words::CARD_CHECK_NOT_HERE,
            ))
        }
        Err(monetize_pay::PayError::Unavailable(why)) => Err(unavailable_for_customer(
            "card check",
            &format!("vendor: {why}"),
            crate::signup::words::SHOP_DOWN,
        )),
        Err(e) => {
            eprintln!(
                "monetize-server: vendor {:?} would not mint a card check: {e}",
                vendor.name
            );
            Err(Status::failed_precondition(
                crate::signup::words::CARD_CHECK_NOT_HERE,
            ))
        }
    }
}

/// ★ The site a name is held on: the calling estate's, else the product's home.
fn hold_site(s: &AppState, product: &str, estate: Option<&str>) -> String {
    estate
        .map(str::to_owned)
        .or_else(|| s.registry.home_of(product))
        .unwrap_or_default()
}

/// ★ **Hold `username` for the vendor page `(vendor, session)`** for [`crate::signup::NAME_HOLD_MS`].
fn hold_for_page(
    s: &AppState,
    product: &str,
    estate: Option<&str>,
    username: &str,
    email: &str,
    vendor: &str,
    session: &str,
) -> Result<(), Status> {
    let hold = crate::signup::NameHold {
        vendor: vendor.to_owned(),
        session: session.to_owned(),
        email: email.trim().to_owned(),
        until_unix_ms: s.now() as i64 + crate::signup::NAME_HOLD_MS,
    };
    s.signups
        .hold_name(product, &hold_site(s, product, estate), username, &hold)
        .map_err(store_err)
}

/// ★ **`Signup.Status` for a paid signup this box minted and has no row for yet** (owner
/// 2026-10-15, B: a plan row goes to the vendor once; the account is made once the payment is
/// confirmed, monetize asking the vendor itself). `Ok(None)`: not such a session, or a vendor
/// that cannot say — the webhook decides, as before. Paid → kept and settled as a verified
/// webhook is (one settle path); open → PENDING; closed unpaid → REFUSED, the name free again.
pub fn finish_paid_signup(
    s: &AppState,
    vendor: &str,
    session: &str,
) -> Result<Option<pb::SignupStatusResponse>, Status> {
    use pb::signup_status_response::State as S;
    if s.signups.get(vendor, session).map_err(store_err)?.is_some() {
        return Ok(None);
    }
    let Some(estate) = s.signups.minted(vendor, session).map_err(store_err)? else {
        return Ok(None);
    };
    let Some(v) = s.registry.find_vendor(vendor) else {
        return Ok(None);
    };
    let answer = |state: S, words: &str| pb::SignupStatusResponse {
        state: state as i32,
        reason: if state == S::Refused {
            words.to_owned()
        } else {
            String::new()
        },
        refusal: if state == S::Refused {
            pb::signup_status_response::Refusal::Final as i32
        } else {
            0
        },
        words: words.to_owned(),
        ..Default::default()
    };
    match v.signup_standing(session) {
        Ok(Some(monetize_pay::signup::SignupAtVendor::Paid(paid))) => {
            s.signups
                .record_pending_on(&paid, s.now() as i64, estate.as_deref())
                .map_err(store_err)?;
            let decided = crate::signup::settle(s, &paid);
            eprintln!("monetize-server: signup {vendor}:{session} read PAID at the vendor by its return page: {decided:?}");
            if !decided.is_pending() {
                s.signups
                    .release_names_of(vendor, session)
                    .map_err(store_err)?;
            }
            Ok(crate::signup::status_with_retry(s, vendor, session)
                .map_err(store_err)?
                .map(|rec| status_response(&s.signups, &rec, s.now() as i64)))
        }
        Ok(Some(monetize_pay::signup::SignupAtVendor::Open)) => Ok(Some(answer(
            S::Pending,
            crate::signup::words::PAYMENT_WAITING,
        ))),
        Ok(Some(monetize_pay::signup::SignupAtVendor::Closed)) => {
            s.signups
                .release_names_of(vendor, session)
                .map_err(store_err)?;
            Ok(Some(answer(
                S::Refused,
                crate::signup::words::PAYMENT_NOT_FINISHED,
            )))
        }
        Ok(None) => Ok(None),
        Err(e) => {
            eprintln!("monetize-server: signup {vendor}:{session}: the vendor could not say where it stands ({e}); the webhook decides");
            Ok(None)
        }
    }
}

/// A card check refused: final for the session, and its name is free again.
fn release_and_refuse(
    s: &AppState,
    vendor: &str,
    session: &str,
    words: &str,
) -> Result<(), StoreError> {
    s.signups.release_names_of(vendor, session)?;
    s.signups.refuse_card_check(vendor, session, words)
}

/// One card check's finish at a time in this process: the "does this card have a free
/// account here" read and the account it makes are one step, so two sessions with the
/// same card cannot both pass the read.
static CARD_GATE: std::sync::Mutex<()> = std::sync::Mutex::new(());

/// A `Signup.Status` answer that is not a stored record (a card check not finished yet,
/// or refused before any account existed).
fn card_answer(
    state: pb::signup_status_response::State,
    started: &crate::signup::CardCheckStarted,
    words: &str,
) -> pb::SignupStatusResponse {
    let refused = state == pb::signup_status_response::State::Refused;
    pb::SignupStatusResponse {
        state: state as i32,
        reason: if refused {
            words.to_owned()
        } else {
            String::new()
        },
        product: started.product.clone(),
        plan: started.plan.clone(),
        refusal: if refused {
            pb::signup_status_response::Refusal::Final as i32
        } else {
            0
        },
        words: words.to_owned(),
        ..Default::default()
    }
}

/// ★ **`Signup.Status` for a card check this box minted** (owner 2026-10-15) — `Ok(None)` for
/// any other session. The vendor is asked where the check stands (never the return URL):
/// open → PENDING; closed unchecked → REFUSED; checked → the card's fingerprint is held
/// against the free accounts on this site — one there already is REFUSED
/// ([`crate::signup::words::CARD_HAS_ACCOUNT`]), else the account is made as at once
/// before ([`make_account`]) with the card on it, and its record answers from then on.
pub fn finish_card_check(
    s: &AppState,
    vendor: &str,
    session: &str,
) -> Result<Option<pb::SignupStatusResponse>, Status> {
    use pb::signup_status_response::State as S;
    let Some(started) = s.signups.card_check(vendor, session).map_err(store_err)? else {
        return Ok(None);
    };
    let account = |s: &AppState| -> Result<Option<pb::SignupStatusResponse>, Status> {
        Ok(
            crate::signup::status_with_retry(s, crate::signup::ACCOUNT_VENDOR, session)
                .map_err(store_err)?
                .map(|rec| status_response(&s.signups, &rec, s.now() as i64)),
        )
    };
    if let Some(answer) = account(s)? {
        return Ok(Some(answer));
    }
    if let Some(words) = &started.refused {
        return Ok(Some(card_answer(S::Refused, &started, words)));
    }
    let Some(v) = s.registry.find_vendor(vendor) else {
        return Err(unavailable_for_customer(
            "card check",
            &format!("vendor {vendor:?} is not loaded"),
            crate::signup::words::SHOP_DOWN,
        ));
    };
    let check = match v.card_check(session) {
        Ok(Some(c)) => c,
        Ok(None) => {
            return Err(unavailable_for_customer(
                "card check",
                &format!("vendor {vendor:?} cannot say where card check {session} stands"),
                crate::signup::words::SHOP_DOWN,
            ))
        }
        Err(monetize_pay::PayError::Unavailable(why)) => {
            return Err(unavailable_for_customer(
                "card check",
                &format!("vendor: {why}"),
                crate::signup::words::SHOP_DOWN,
            ))
        }
        Err(e) => {
            eprintln!("monetize-server: card check {vendor}:{session}: the vendor said {e}");
            return Err(unavailable_for_customer(
                "card check",
                &format!("vendor: {e}"),
                crate::signup::words::SHOP_DOWN,
            ));
        }
    };
    match check.state {
        monetize_pay::signup::CardCheckState::Open => {
            return Ok(Some(card_answer(
                S::Pending,
                &started,
                crate::signup::words::CARD_BEING_CHECKED,
            )))
        }
        monetize_pay::signup::CardCheckState::Expired => {
            release_and_refuse(s, vendor, session, crate::signup::words::CARD_NOT_CHECKED)
                .map_err(store_err)?;
            return Ok(Some(card_answer(
                S::Refused,
                &started,
                crate::signup::words::CARD_NOT_CHECKED,
            )));
        }
        monetize_pay::signup::CardCheckState::Checked => {}
    }
    if check.fingerprint.trim().is_empty() {
        return Err(unavailable_for_customer(
            "card check",
            &format!("vendor {vendor:?} answered card check {session} checked with no fingerprint"),
            crate::signup::words::SHOP_DOWN,
        ));
    }
    let _one = CARD_GATE.lock().unwrap_or_else(|p| p.into_inner());
    // Another poll may have made it while this one waited at the gate.
    if let Some(answer) = account(s)? {
        return Ok(Some(answer));
    }
    let home = s.registry.home_of(&started.product);
    if let Some((held, _)) = s
        .signups
        .free_account_with_card_on(
            &started.product,
            started.estate.as_deref(),
            home.as_deref(),
            vendor,
            &check.fingerprint,
        )
        .map_err(store_err)?
    {
        eprintln!("monetize-server: card check {vendor}:{session}: the card already has a free {} account here ({held}); no second one", started.product);
        release_and_refuse(s, vendor, session, crate::signup::words::CARD_HAS_ACCOUNT)
            .map_err(store_err)?;
        return Ok(Some(card_answer(
            S::Refused,
            &started,
            crate::signup::words::CARD_HAS_ACCOUNT,
        )));
    }
    let now = s.now() as i64;
    let signup = monetize_pay::signup::PaidSignup {
        vendor: crate::signup::ACCOUNT_VENDOR.to_owned(),
        session: session.to_owned(),
        reference: check.reference.clone(),
        email: started.email.clone(),
        username: started.username.clone(),
        product: started.product.clone(),
        plan: started.plan.clone(),
        amount: monetize_pay::Money {
            minor: 0,
            currency: started.currency,
        },
        tax: monetize_pay::Money {
            minor: 0,
            currency: started.currency,
        },
        paid_at_unix_ms: now,
        customer_country: None,
    };
    let card = crate::signup::CardOnFile {
        vendor: vendor.to_owned(),
        fingerprint: check.fingerprint.trim().to_owned(),
        customer: check.customer.clone(),
        payment_method: check.payment_method.clone(),
        reference: check.reference.clone(),
        checked_at_unix_ms: now,
    };
    match make_account(
        s,
        &signup,
        Some(&card),
        started.estate.as_deref(),
        &started.success_url,
        started.site.as_deref(),
    )? {
        Made::Created | Made::Pending => {
            s.signups
                .release_names_of(vendor, session)
                .map_err(store_err)?;
            account(s)
        }
        Made::NameTaken(why) => {
            let words = format!("{why} Nothing has been charged — start again with another name.");
            release_and_refuse(s, vendor, session, &words).map_err(store_err)?;
            Ok(Some(card_answer(S::Refused, &started, &words)))
        }
        Made::Refused => {
            release_and_refuse(s, vendor, session, crate::signup::words::COULD_NOT_CREATE)
                .map_err(store_err)?;
            Ok(Some(card_answer(
                S::Refused,
                &started,
                crate::signup::words::COULD_NOT_CREATE,
            )))
        }
    }
}

/// **The account's sign-in link, by mail** (OM-20): the welcome page the answer leads to is
/// also mailed to the address the account was made for, so a buyer who closes the tab still
/// reaches it. The link is the secret and is only in the mail's body. A mail that is not
/// sent is logged and fails nothing: the account is made, and the page still leads on.
pub(crate) fn mail_sign_in_link(
    s: &AppState,
    product: &str,
    username: &str,
    to: &str,
    url: &str,
    site: Option<&str>,
) {
    match sign_in_mail(s, product, username, to, url, site) {
        Ok(sent) => eprintln!("monetize-server: the sign-in link for {username:?} was mailed: {sent}"),
        Err(e) => eprintln!("monetize-server: the sign-in link for {username:?} was NOT mailed to {} ({e:?}); the account is made", monetize_mail::masked(to)),
    }
}

/// The sign-in mail itself: the link in the body only, the host in the subject.
/// `site`: the estate's own site (ST-23) — the host the mail names; the link is on it
/// (checked at Start). `None` only where no site is declared at all.
fn sign_in_mail(
    s: &AppState,
    product: &str,
    username: &str,
    to: &str,
    url: &str,
    site: Option<&str>,
) -> Result<String, monetize_pay::signup::SignupError> {
    let host = site.unwrap_or_else(|| {
        url.split("://")
            .nth(1)
            .unwrap_or(url)
            .split('/')
            .next()
            .unwrap_or_default()
    });
    let body = format!(
        "Your account {username} at https://{host} is made. This link registers your passkey on it, while it has none:\n\n  {url}\n\n\
         After that, sign in at https://{host} with your passkey. If you did not sign up, you can ignore this mail.\n"
    );
    let notice = monetize_pay::CustomerNotice {
        product: product.to_owned(),
        tenant: username.to_owned(),
        to: to.to_owned(),
        kind: "account.sign_in".into(),
        subject: format!("Your sign-in link for https://{host}"),
        body,
    };
    s.signup_sink.notify(&notice)
}

/// How often one signup's sign-in link may be sent again.
pub const SIGN_IN_AGAIN_EVERY_MS: u64 = 60_000;

/// **`Signup.SendSignInAgain`** (owner 2026-10-11: the welcome page says where the link went,
/// with [Send again]): a CREATED signup's link — `welcome_url` with its session — mailed
/// again to the address the signup was made with. The signup is found by its session, for
/// `product`, from the site that asks (another site's is not found); the page is on the
/// signup's site (`[signup-other-site]`) and https, with `{session}` in it; once a minute per
/// session. The answer names the address MASKED only.
pub fn send_sign_in_again(
    s: &AppState,
    product: &str,
    session: &str,
    welcome_url: &str,
    estate: Option<&str>,
) -> Result<pb::SignupSignInAgainResponse, Status> {
    static SENT: std::sync::OnceLock<std::sync::Mutex<std::collections::BTreeMap<String, u64>>> =
        std::sync::OnceLock::new();
    let session = session.trim();
    let missing = || Status::not_found(format!("no {product} signup {session:?} here"));
    let rec = s
        .signups
        .list(0)
        .map_err(store_err)?
        .into_iter()
        .find(|r| !session.is_empty() && r.signup.session == session && r.signup.product == product)
        .ok_or_else(missing)?;
    if let Some(caller) = estate {
        let home = s.registry.home_of(product);
        if rec.estate.as_deref().or(home.as_deref()) != Some(caller) {
            return Err(missing());
        }
    }
    let SignupState::Created { username, .. } = &rec.state else {
        return Err(Status::failed_precondition(
            "This account is not made yet: its sign-in link is mailed once it is.",
        ));
    };
    let url = welcome_url.trim();
    if !url.starts_with("https://") || !url.contains("{session}") {
        return Err(Status::invalid_argument(
            "the welcome page is an https:// address with {session} in it",
        ));
    }
    // ST-23: the link is on the signup's own site (its estate's, else the home's), always.
    let site = estate
        .map(str::to_owned)
        .or_else(|| rec.estate.clone())
        .or_else(|| s.registry.home_of(product))
        .and_then(|e| s.registry.site_of(&e));
    if site.is_none() && s.registry.sold_per_site(product) {
        return Err(Status::permission_denied(format!("REFUSED [estate-unnamed] {product} is sold for several sites here and this signup's site is not known: its sign-in link is only ever on its estate's site")));
    }
    if let Some(why) = site.as_deref().and_then(|site| page_refusal(site, url, "")) {
        return Err(Status::invalid_argument(why));
    }
    let now = s.now();
    {
        let mut sent = SENT
            .get_or_init(Default::default)
            .lock()
            .unwrap_or_else(|p| p.into_inner());
        if sent
            .get(session)
            .is_some_and(|at| now.saturating_sub(*at) < SIGN_IN_AGAIN_EVERY_MS)
        {
            return Err(Status::resource_exhausted("It was sent a moment ago. Look in your inbox (and spam), or try again in a minute."));
        }
        sent.insert(session.to_owned(), now);
    }
    let to = rec.signup.email.trim();
    match sign_in_mail(
        s,
        product,
        username,
        to,
        &url.replace("{session}", session),
        site.as_deref(),
    ) {
        Ok(sent) => {
            eprintln!(
                "monetize-server: the sign-in link for {username:?} was mailed again: {sent}"
            );
            Ok(pb::SignupSignInAgainResponse {
                words: format!("We’ve sent it again to {}.", monetize_mail::masked(to)),
            })
        }
        Err(e) => {
            eprintln!("monetize-server: the sign-in link for {username:?} was NOT mailed again to {} ({e:?})", monetize_mail::masked(to));
            Err(Status::unavailable(
                "The mail could not be sent right now. Try again in a while.",
            ))
        }
    }
}

/// **Is this name free?** The shape rule, then the sink — in that order, because
/// the shape rule names the offending character and costs no call.
///
/// A name is free or taken FOR a product (one monetize sells gunnar's and
/// holger's accounts, each from its own sink); the product is the caller's.
///
/// One writer for `CheckName` and `Start`: the check a console makes is a
/// courtesy and the one `Start` makes is the gate, and two spellings of one
/// question is two answers that can disagree.
/// The product a Signup call is FOR, or INVALID_ARGUMENT: one monetize sells
/// several products, and none is assumed.
fn product_named(product: &str, verb: &str) -> Result<String, Status> {
    let p = product.trim();
    if p.is_empty() {
        return Err(Status::invalid_argument(format!(
            "Signup.{verb} names no product: one monetize sells several, and a call says which"
        )));
    }
    Ok(p.to_owned())
}

/// UNIMPLEMENTED for a product with no sink that creates accounts.
fn no_sink(product: &str) -> Status {
    Status::unimplemented(format!("no signup sink is loaded for {product}: this server creates no {product} account, so it sells none ([signups.{product}] guest = … is the sink)"))
}

fn name_refusal(
    s: &AppState,
    product: &str,
    username: &str,
    estate: Option<&str>,
) -> Result<Option<String>, Status> {
    if let Some(why) = monetize_pay::signup::username_refusal(username) {
        return Ok(Some(why));
    }
    // On the estate the account would be made on (the caller's), never another site's names.
    match s.signup_sink.name_verdict_on(product, username, estate) {
        Ok(monetize_pay::signup::NameVerdict::Free) => Ok(None),
        Ok(monetize_pay::signup::NameVerdict::Taken(why)) => Ok(Some(why)),
        // **Not "taken".** A console that said "choose another username"
        // because the appliance was rebooting would be lying to somebody whose
        // name is free, and they would spend it on a second-choice name.
        // The product's own words are for the log; a visitor reads that the
        // shop is down, not what gunnar said about a credential.
        Err(monetize_pay::signup::SignupError::Unavailable(why)) => Err(unavailable_for_customer(
            "name check",
            &why,
            crate::signup::words::SHOP_DOWN,
        )),
        Err(other) => Ok(Some(other.to_string())),
    }
}

/// A `Signup.Start` past this is said at WARN (the front raises a line that
/// says FAILED): a healthy one is the vendor's one round trip.
pub const START_BUDGET: std::time::Duration = std::time::Duration::from_secs(5);

/// **Where one `Signup.Start` spent its time**, said as ONE line when it ends
/// — minted, refused or failed. Each stage is the time since the previous mark.
pub struct StartTimings {
    user: String,
    began: std::time::Instant,
    last: std::time::Instant,
    marks: Vec<(String, u128)>,
    pub outcome: &'static str,
    say: fn(&str),
}

impl StartTimings {
    pub fn new(user: &str) -> StartTimings {
        StartTimings::saying(user, |l| eprintln!("{l}"))
    }
    pub fn saying(user: &str, say: fn(&str)) -> StartTimings {
        let now = std::time::Instant::now();
        StartTimings {
            user: user.to_owned(),
            began: now,
            last: now,
            marks: Vec::new(),
            outcome: "not minted",
            say,
        }
    }
    pub fn mark(&mut self, stage: &str) {
        self.mark_owned(stage.to_owned());
    }
    pub fn mark_owned(&mut self, stage: String) {
        let now = std::time::Instant::now();
        self.marks
            .push((stage, now.duration_since(self.last).as_millis()));
        self.last = now;
    }
    /// The line, for a total of `total`.
    pub fn line(&self, total: std::time::Duration) -> String {
        let stages = self
            .marks
            .iter()
            .map(|(s, ms)| format!("{s} {ms} ms"))
            .collect::<Vec<_>>()
            .join(" · ");
        let over = if total > START_BUDGET {
            format!(
                " — SLOW: past the {} s a signup may take (budget FAILED)",
                START_BUDGET.as_secs()
            )
        } else {
            String::new()
        };
        format!(
            "monetize-server: signup start {:?}: {} in {} ms — {stages}{over}",
            self.user,
            self.outcome,
            total.as_millis()
        )
    }
}

impl Drop for StartTimings {
    fn drop(&mut self) {
        (self.say)(&self.line(self.began.elapsed()));
    }
}

/// **How a `Signup.Start` is paid.**
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PayBy {
    /// The customer's way: the vendor mints its hosted page and the webhook settles it.
    Checkout,
    /// **The operator's TEST BUTTON** (2026-10-11): the vendor, on a TEST key
    /// only, takes the money with its own test payment method and answers the
    /// paid signup its webhook would have carried; it is settled through the
    /// ONE settle path every webhook takes ([`crate::signup::settle`]).
    /// Everything before the vendor — the name, the address, the plan, the
    /// room, the sold capacity — is the customer's path, unchanged. A FREE account asked for
    /// this way (the button's private-instance run) is made at once, without the card check
    /// a customer's free account takes (owner 2026-10-15): the operator's own test account.
    TestPayment,
}

/// Pure: **a signup's pages must be on its site** — `https://<site>/…` for the success and
/// the cancel page alike (an empty one is the vendor's own default and passes). `None`: both
/// are; else the refusal, naming the page and the site.
pub fn site_refusal(site: &str, success_url: &str, cancel_url: &str) -> Option<String> {
    let origin = format!("https://{site}/");
    // WWW-CANON (owner 2026-10-30): the site's www name is the site, and its console's origin.
    let www = format!("https://www.{site}/");
    [("success", success_url), ("cancel", cancel_url)]
        .into_iter()
        .find(|(_, u)| !u.is_empty() && !u.starts_with(&origin) && !u.starts_with(&www))
        .map(|(which, u)| format!("REFUSED [signup-other-site] the {which} page {u:?} is not on this estate's site {site}: a signup returns where it began"))
}

/// What the test button reads when the routed vendor is not on a test key.
pub const NOT_A_TEST_KEY: &str = "the vendor's key is not a TEST key (live, or it cannot say): a test button never spends live money";

/// **`Signup.Start`, the one implementation** — the sign-up page's call
/// ([`PayBy::Checkout`]) and the operator's test button ([`PayBy::TestPayment`]).
/// `estate`: the site the call comes from ([`crate::auth::CallerEstate`]); a product with
/// `[estates]` declared bills ONLY through that site's own account
/// ([`crate::registry::Registry::route_for`]), and its pages must be on that site
/// ([`site_refusal`]).
pub fn start_signup(
    s: &AppState,
    r: &pb::StartSignupRequest,
    pay: PayBy,
    estate: Option<&str>,
) -> Result<pb::StartSignupResponse, Status> {
    start_signup_in(s, r, pay, estate)
}

/// A signup's pages are on its site ([`site_refusal`]). (A33-12: the ONE shop's own welcome page
/// is no exception any more: its sign-up page is deleted.)
pub fn page_refusal(site: &str, success_url: &str, cancel_url: &str) -> Option<String> {
    site_refusal(site, success_url, cancel_url)
}

fn start_signup_in(
    s: &AppState,
    r: &pb::StartSignupRequest,
    pay: PayBy,
    estate: Option<&str>,
) -> Result<pb::StartSignupResponse, Status> {
    // One line when this returns, whichever way: the total and where
    // it went (test2 2026-09-30: 25 s with nothing logged in between).
    let mut timed = StartTimings::new(&r.username);
    // A checkout is minted FOR a product: its plans, its sink, its
    // vendor instance. None named mints nothing.
    let product = product_named(&r.product, "Start")?;
    // **No account can be made here, so none is sold** (owner
    // 2026-09-26): with no sink that creates one, a checkout would take
    // a stranger's money for an account that never exists.
    // UNIMPLEMENTED — the answer a console already turns into "this
    // console cannot sell an account".
    if !s.signup_sink.creates_accounts_for(&product) {
        return Err(no_sink(&product));
    }
    // ★ ST-23: **a signup begins on ONE site, and its pages (and the account's mail) are on
    // it** — the calling estate's, else the product's home where it is not sold per site. A
    // product sold for several sites refuses a Start that names none: the sign-in mail would
    // otherwise link to whatever host `success_url` names.
    let site_estate: Option<String> = match estate {
        Some(e) => Some(e.to_owned()),
        None if s.registry.sold_per_site(&product) => {
            return Err(Status::permission_denied(format!(
                "REFUSED [estate-unnamed] {product} is sold for several sites here and this signup names none (the estate's own bearer names it): its pages and its sign-in mail are only ever on its estate's site"
            )))
        }
        None => s.registry.home_of(&product),
    };
    let site = site_estate.as_deref().and_then(|e| s.registry.site_of(e));
    if let Some(why) = site
        .as_deref()
        .and_then(|site| page_refusal(site, &r.success_url, &r.cancel_url))
    {
        return Err(Status::invalid_argument(why));
    }
    let named = name_refusal(s, &product, &r.username, estate);
    timed.mark("name");
    if let Some(reason) = named? {
        return Err(Status::failed_precondition(reason));
    }
    // **The contact address, before any card form.** Required: a signup
    // whose only address is whatever a wallet handed the vendor is one
    // the buyer never chose (measured 2026-09-15). INVALID_ARGUMENT, so a
    // console shows the sentence and the buyer fixes one field.
    let email = r.email.trim().to_owned();
    if let Some(reason) = monetize_pay::signup::email_refusal(&email) {
        return Err(Status::invalid_argument(reason));
    }
    // **One address, one account** (PLAN §3c, OM-19 (4)): an address
    // that already has an account here signs in to it — a second
    // account is never made for it, and nothing is merged by email.
    // ★ ST-6: per SITE — an address with an account on another site signs up here.
    match s.signups.has_account_with_email_on(
        &product,
        estate,
        s.registry.home_of(&product).as_deref(),
        &email,
    ) {
        Ok(false) => {}
        Ok(true) => {
            return Err(Status::failed_precondition(
                crate::signup::words::EMAIL_HAS_ACCOUNT,
            ))
        }
        Err(e) => return Err(Status::internal(format!("signup store: {e}"))),
    }
    // ★ **A name held for somebody else's open vendor page** (owner 2026-10-15, B): nobody
    // takes it while that payment (or card check) runs. The same buyer starting again is not
    // shut out by their own page.
    // ★ A33-2: the test button's press takes this check too: only its card differs.
    if let Some(h) = s
        .signups
        .name_hold(
            &product,
            &hold_site(s, &product, estate),
            &r.username,
            s.now() as i64,
        )
        .map_err(store_err)?
    {
        if !h.email.trim().eq_ignore_ascii_case(&email) {
            return Err(Status::failed_precondition(
                crate::signup::words::NAME_BEING_BOUGHT,
            ));
        }
    }
    let market = match monetize_proto::Market::try_from(r.market) {
        Ok(monetize_proto::Market::Se) => Some(monetize_pay::Market::Se),
        Ok(monetize_proto::Market::Fi) => Some(monetize_pay::Market::Fi),
        Ok(monetize_proto::Market::Dk) => Some(monetize_pay::Market::Dk),
        _ => None,
    };
    let plans_now = s.signup_plans.snapshot_of(&product);
    let default_market = s
        .terms
        .read()
        .unwrap_or_else(|e| e.into_inner())
        .default_market;
    // ★ Room by the rule (round 5.3.1): a PRICED id is sold only at the
    // price it names, and only while that is today's — the checkout
    // charges exactly what the page showed, or nothing is started.
    let priced: Option<(String, crate::config::SignupPlan)> = match crate::plans::parse_priced_id(
        &r.plan,
    ) {
        None => None,
        Some((of, _, _)) if of != product => {
            return Err(Status::invalid_argument(format!(
                "plan {:?} is {of}'s, and this checkout is for {product}",
                r.plan
            )))
        }
        Some((_, _, price)) => {
            let in_market = market.unwrap_or_else(|| price.currency.market());
            match crate::plans::priced_id_is_current(s, &r.plan, in_market) {
                Ok(true) => Some((r.plan.clone(), crate::plans::priced_signup_plan(s, &r.plan).ok_or_else(|| Status::invalid_argument(format!("plan {:?} is not sold here", r.plan)))?)),
                Ok(false) => return Err(Status::failed_precondition("The price of this plan changed while the page was open. Look again: nothing has been charged.")),
                Err(why) => return Err(Status::failed_precondition(why)),
            }
        }
    };
    let (plan_id, plan) = match &priced {
        Some((id, p)) => (id.as_str(), *p),
        None => plan_for_market(&plans_now, &r.plan, market, default_market)?,
    };
    // The plan is the product's own (`gunnar/10gb-1m` is one bundle of
    // one product), and the sink reads `metadata[product]` back off the
    // session to know whose account it is making.
    if crate::signup::plan_product(plan_id) != product {
        return Err(Status::invalid_argument(format!(
            "plan {plan_id:?} is not {product}'s"
        )));
    }
    // ★ **An account at the shop, without room here** (one shop, owner
    // 2026-10-07): a plan with no price sells nothing, so it asks no box
    // for room and no vendor for money — the account is made now.
    if plan.amount_minor == 0 {
        timed.outcome = "account";
        // ★ **A free account only after a card check** (owner 2026-10-15), on every site
        // that sells through a vendor; a product routed to no vendor at all (an open
        // build) makes it at once, as before.
        // ★ A33-2/A33-3: no account is made around the card check: a free account the test
        // button asked for where a card check stands is refused by name (its private press is a
        // visitor's order, whose account is made when the order is paid).
        let checks = card_check_vendor(s, &product, estate)?;
        if checks.is_some() && pay == PayBy::TestPayment {
            timed.outcome = "test refused";
            return Err(Status::failed_precondition("a free account is made only after a card check: the test button buys a paid plan or a private instance, never a free account by itself"));
        }
        if let Some(vendor) = checks {
            timed.outcome = "card check";
            return start_card_check(
                s,
                vendor,
                r,
                (plan_id, &plan),
                &product,
                email,
                (estate, site.as_deref()),
            );
        }
        return start_account(
            s,
            r,
            plan_id,
            &plan,
            &product,
            email,
            (estate, site.as_deref()),
        );
    }
    // **THE BOX IS ASKED WHETHER IT HAS THE ROOM, BEFORE THE CARD.**
    //
    // A purchase has asked since the order model was written
    // (`Transaction::quote` → `Product::can_absorb`, whose own test is
    // "No money moves for capacity that cannot be delivered"). A signup
    // asked nobody: its three checks are the name, the plan and the
    // amount, and `signup_sales` recorded each one with "the room was on
    // hand" — an assumption never once put to the appliance. On a full
    // box the shop went on minting live checkouts, every one a real
    // charge for a cap the box cannot honour and a refund by hand to
    // undo.
    //
    // HERE and not in the webhook, because this is the last moment a
    // capacity refusal is free: after the webhook the money has moved.
    //
    // A deployment with no product linked — the open build — is not
    // gated by a box it does not have. A product that will not ANSWER is
    // refused like a full one: neither is a box that can be sold.
    if let Some(p) = s.registry.products().find(|p| p.id() == product) {
        let caps = std::collections::BTreeMap::from([(
            s.signup_plans.cap_meter_of(&product),
            plan.cap_bytes,
        )]);
        // **NO TENANT ID, and that is the whole question.** A signup is
        // asking "could you serve N bytes that are not here yet"; a
        // purchase is asking "could you raise THIS tenant to N", and
        // gunnar's `Admin.Capacity` says in its own proto which field
        // picks between them: *"Empty asks the harder question … which
        // is the right one for a brand-new tenant and the wrong one for
        // a raise."*
        //
        // Naming the username here asked the RAISE question about an
        // account that by definition does not exist yet. gunnar answers
        // `NOT_FOUND` — deliberately, because quoting a raise against
        // the wrong tenant's zero is how a seller oversells — the
        // plugin turns that into "no tenant to raise", and
        // `Capacity::Unanswered` is refused like a full box, because
        // silence is not a yes.
        //
        // MEASURED on the front 2026-09-18: every signup was refused
        // with NO_ROOM on a box with room. The log said so exactly —
        // *"gunnar's catalog does not hold the namespace \"henrilina\",
        // so there is no tenant to raise … THAT IS A MEASUREMENT THAT
        // DID NOT HAPPEN, not a full disk"* — and the refusal chain was
        // right at every step but this one. The empty id is what
        // `GunnarProduct::servable` already passes for the same reason.
        // …with the queue past the room (round 5.3): a full box whose main
        // grows its own set when told still sells, and the main is told.
        // ★ ST-11: a signup from ANOTHER site of the product asks that site's own main. A
        // pulled product routes `@<estate>/<name>` to the estate's report, where a name not
        // promised anything yet is the same brand-new-tenant question; the home asks as above.
        let asked = match estate.filter(|e| s.registry.home_of(&product).as_deref() != Some(*e)) {
            Some(e) => monetize_product::TenantId::on_estate(e, &r.username),
            None => monetize_product::TenantId(String::new()),
        };
        let absorbed = crate::grow::can_absorb_queued(s, p, &asked, &caps);
        timed.mark("capacity");
        if let Err(why) = absorbed {
            return Err(unavailable_for_customer(
                "capacity",
                &format!("{product}: {why}"),
                crate::signup::words::NO_ROOM,
            ));
        }
    }
    // **AND WHAT HAS ALREADY BEEN SOLD**, which the question above does
    // not ask. `can_absorb` is `Admin.Capacity` against FREE space, and
    // free space is what nobody has written yet: eleven tenants holding
    // a tenth of their 10 GiB caps leave a box that answers yes to
    // every one of them (measured on the front 2026-09-18). The caps
    // are the promise, and the caps are what breaks.
    //
    // `monetize::fleet::Oversell` has computed `sum(sold) − servable`
    // since it was written and gated nothing — it is rendered on the
    // Usage page. This is that same fold, with THIS sale added, against
    // the allowance the operator wrote down. See `crate::oversell` for
    // the knob, and for what the hold below does and does not close.
    //
    // The hold lives to the end of this closure: a slot is held from
    // here until the checkout is minted, so two `Signup.Start` calls
    // racing for the last one cannot both be told yes. Dropping it —
    // any error path below, including the vendor refusing to mint —
    // frees the slot.
    let hold = match s.registry.products().find(|p| p.id() == product) {
        Some(p) => {
            let admitted = crate::oversell::admit_on(s, p, plan.cap_bytes, estate);
            timed.mark("sold-capacity");
            match admitted {
                Ok(hold) => Some(hold),
                // ★ Round 5.3 (owner 2026-10-08: "the customer must not
                // know about a cap! it must be queued and resized
                // later"): where the set is resized later, past the
                // sold-capacity wall is SOLD and QUEUED at the estate that
                // grows its own set when told; the operator is told.
                Err(why) if crate::grow::queues_for_resize(s, p) => {
                    // Once per signup, as INFO (round 5.3): queued is not a refusal.
                    if let Some(line) = crate::oversell::queue_note(
                        &format!("signup:{product}/{}", r.username),
                        &format!("{product}/{}", r.username),
                        &why,
                    ) {
                        eprintln!("{line}");
                    }
                    None
                }
                Err(why) => {
                    return Err(unavailable_for_customer(
                        "capacity",
                        &why,
                        crate::signup::words::NO_ROOM,
                    ))
                }
            }
        }
        // No product linked: the open build is not gated by a box it
        // does not have, exactly as `can_absorb` above is not.
        None => None,
    };
    let market = plan.currency.market();
    // UNIMPLEMENTED, like no sink: "not sold here" is a configuration
    // gap a console tells apart by CODE (stinky gunnar-ui #7), never by
    // these words — FAILED_PRECONDITION is a refusal about the order.
    // An estate-routed product: the site's own account, its pages on its site — or a
    // refusal naming what is missing, never another site's account.
    if plan.price().minor != 0 {
        match s.registry.route_for(&product, estate) {
            // Routed NOWHERE (no `vendor`, no site): the configuration gap the
            // UNIMPLEMENTED below names, not a refusal about this order.
            Err(why) if why == s.registry.route_said(&product) => {}
            Err(why) => return Err(Status::permission_denied(why)),
            Ok(_) => {}
        }
    }
    let vendor = s
        .registry
        .vendor_for_estate(&plan.price(), market, &product, estate, &r.vendor)
        .ok_or_else(|| {
            Status::unimplemented(format!(
                "no vendor here can sell a {product} signup at {} in {:?}: {}; serving: {:?}",
                plan.price().in_words(),
                market,
                s.registry.route_said(&product),
                s.registry.vendor_names()
            ))
        })?;
    // What the vendor's page names: the product, its room and period, and the price (A16).
    let description = crate::signup::signup_checkout_words(&product, &plan);
    let order = monetize_pay::signup::SignupOrder {
        username: r.username.clone(),
        email,
        product,
        plan: plan_id.to_owned(),
        // **NET.** `monetize_server::signup::refusal` compares the plan
        // price against `amount - tax`, so what the vendor is asked for
        // is the price before whatever tax it calculates on top.
        amount: plan.price(),
        market,
        // In MAJOR units: this is what the buyer reads on the vendor's
        // page, and `10000 SEK` for a 100,00 kr plan is a hundredfold lie.
        description,
        success_url: r.success_url.clone(),
        cancel_url: r.cancel_url.clone(),
    };
    if pay == PayBy::TestPayment {
        return pay_as_test(s, vendor, &order, hold, &r.success_url, estate, &mut timed);
    }
    let minted = vendor.signup_page(&order);
    timed.mark_owned(format!("vendor {}", vendor.name));
    match minted {
        Ok(Some(checkout)) => {
            // ★ ST-7: this box settles only the sessions it minted — kept here, with the
            // site, before the buyer is sent to pay. A vendor that names no session at mint
            // cannot be told apart from another system's money on the same account.
            if checkout.session.trim().is_empty() {
                return Err(Status::unimplemented(format!(
                    "vendor {:?} minted a checkout with no session id: this monetize settles only the sessions it minted (ST-7), so it does not sell signups through it",
                    vendor.name
                )));
            }
            s.signups.record_minted(vendor.name, &checkout.session, estate).map_err(store_err)?;
            s.signups.record_welcome(vendor.name, &checkout.session, &order.success_url).map_err(store_err)?;
            // ★ The name is held while the payment page runs (owner 2026-10-15, B).
            hold_for_page(s, &order.product, estate, &order.username, &order.email, vendor.name, &checkout.session)?;
            timed.outcome = "minted";
            // The checkout exists: the slot stays held until the
            // webhook settles the session or the hold's TTL runs out.
            if let Some(hold) = hold {
                hold.minted(vendor.name, &checkout.session);
            }
            Ok(pb::StartSignupResponse { url: checkout.url, session: checkout.session })
        }
        Ok(None) => Err(Status::unimplemented(format!(
            "vendor {:?} mints no signup checkout; this deployment's signups are sold some other way",
            vendor.name
        ))),
        Err(monetize_pay::PayError::Unavailable(why)) => Err(unavailable_for_customer("checkout", &format!("vendor: {why}"), crate::signup::words::SHOP_DOWN)),
        Err(e) => Err(Status::failed_precondition(format!("vendor: {e}"))),
    }
}

/// [`PayBy::TestPayment`]'s vendor step: refused unless the vendor's key is a
/// TEST key; the vendor pays with its test payment method and answers the paid
/// signup; it is kept and settled exactly as a verified webhook is.
fn pay_as_test(
    s: &AppState,
    vendor: monetize_pay::Vendor<'_>,
    order: &monetize_pay::signup::SignupOrder,
    hold: Option<crate::oversell::Hold<'_>>,
    success_url: &str,
    estate: Option<&str>,
    timed: &mut StartTimings,
) -> Result<pb::StartSignupResponse, Status> {
    if vendor.livemode() != Some(false) {
        timed.outcome = "test refused";
        return Err(Status::failed_precondition(format!(
            "{}: {NOT_A_TEST_KEY}",
            vendor.name
        )));
    }
    let paid = vendor.test_signup(order);
    timed.mark_owned(format!("vendor {} (test payment)", vendor.name));
    let paid = match paid {
        Ok(Some(p)) => p,
        Ok(None) => {
            return Err(Status::unimplemented(format!(
                "vendor {:?} cannot pay a signup without a person (it has no test payment method)",
                vendor.name
            )))
        }
        Err(e) => {
            return Err(Status::failed_precondition(format!(
                "vendor (test payment): {e}"
            )))
        }
    };
    timed.outcome = "test paid";
    if let Some(hold) = hold {
        hold.minted(vendor.name, &paid.session);
    }
    // ★ A33-2: the session the vendor's test card paid is recorded as this box's own, with its
    // welcome page, exactly as a buyer's minted checkout is (ST-7) — the one settle path below
    // then reads it as a buyer's.
    s.signups
        .record_minted(vendor.name, &paid.session, estate)
        .map_err(store_err)?;
    s.signups
        .record_welcome(vendor.name, &paid.session, success_url)
        .map_err(store_err)?;
    // The one settle path every verified webhook takes: kept first — with the site the
    // press named, so the account is made THERE (ST-8) — then the sink.
    s.signups
        .record_pending_on(&paid, s.now() as i64, estate)
        .map_err(store_err)?;
    let decided = crate::signup::settle(s, &paid);
    eprintln!("monetize-server: a TEST signup {}:{} for {:?} was paid with the vendor's test payment method: {decided:?}", paid.vendor, paid.session, paid.username);
    Ok(pb::StartSignupResponse {
        url: success_url.replace("{session}", &paid.session),
        session: paid.session,
    })
}

/// **The vendor a console's signup row is kept under.** A console names the vendor KIND
/// (`stripe`, gunnar-ui `auth::signup`); on a box selling one product for several sites the
/// webhook keeps the paid row under the calling site's INSTANCE (`stripe/gunnar-test2`,
/// `monetize_pay::instance`). The row under the name asked wins; else the calling estate's
/// own instance of that kind — never another site's (i54a, 2026-10-12: test2's welcome page
/// polled `stripe` and read UNKNOWN for ever).
fn row_vendor(s: &AppState, named: &str, session: &str, estate: Option<&str>) -> String {
    // ★ A32-15: a site names no vendor (the shop link's vendor is empty): the calling estate's
    // own vendor instance is the one its sign-ups were minted at.
    if named.trim().is_empty() && !session.starts_with(crate::signup::ACCOUNT_SESSION_PREFIX) {
        if let Some(v) = estate.and_then(|e| s.registry.estate_vendors().get(e).cloned()) {
            return v;
        }
    }
    let direct = crate::signup::vendor_of(named, session);
    if direct != named || named.contains('/') {
        return direct.to_owned();
    }
    match estate.and_then(|e| s.registry.instance_of_kind(e, named)) {
        Some(instance) if !matches!(s.signups.get(named, session), Ok(Some(_))) => instance,
        _ => named.to_owned(),
    }
}

#[tonic::async_trait]
impl Signup for SignupService {
    /// Read-only about the store and safe to poll every 2 s — with one
    /// deliberate side effect, spelled out in [`crate::signup::status_with_retry`]:
    /// a PENDING signup is pushed at the sink again before it is answered, so a
    /// customer watching the page is not left waiting for the poller's tick
    /// (which also retries it, for the customer who closed the tab —
    /// `crate::signup::settle_pending`). A poll of a decided signup reads one
    /// row and calls nobody.
    async fn status(
        &self,
        req: Request<pb::SignupStatusRequest>,
    ) -> Result<Response<pb::SignupStatusResponse>, Status> {
        let estate = req
            .extensions()
            .get::<crate::auth::CallerEstate>()
            .map(|e| e.0.clone());
        let r = req.into_inner();
        let out = blocking(&self.0, move |s| {
            let vendor = row_vendor(s, &r.vendor, &r.session, estate.as_deref());
            // ★ A card check this box minted for a free account (owner 2026-10-15).
            // Kept under the vendor INSTANCE that minted it: the row's vendor, else the
            // calling estate's own vendor (a console names only the kind).
            let estate_vendor = estate
                .as_deref()
                .and_then(|e| s.registry.estate_vendors().get(e).cloned())
                .filter(|v| *v != vendor);
            for v in std::iter::once(vendor.clone()).chain(estate_vendor) {
                if let Some(answer) = finish_card_check(s, &v, &r.session)? {
                    return Ok(answer);
                }
            }
            // ★ A paid signup this box minted and holds no row for: the vendor is asked (B).
            if let Some(answer) = finish_paid_signup(s, &vendor, &r.session)? {
                return Ok(answer);
            }
            let found =
                crate::signup::status_with_retry(s, &vendor, &r.session).map_err(store_err)?;
            Ok(match found {
                Some(rec) => status_response(&s.signups, &rec, s.now() as i64),
                // Never an error: the page may well be polling before the
                // webhook landed. See the module doc.
                None => pb::SignupStatusResponse {
                    state: pb::signup_status_response::State::Unknown as i32,
                    ..Default::default()
                },
            })
        })
        .await?;
        Ok(Response::new(out))
    }

    async fn send_sign_in_again(
        &self,
        req: Request<pb::SignupSignInAgainRequest>,
    ) -> Result<Response<pb::SignupSignInAgainResponse>, Status> {
        let estate = req
            .extensions()
            .get::<crate::auth::CallerEstate>()
            .map(|e| e.0.clone());
        let r = req.into_inner();
        let product = product_named(&r.product, "SendSignInAgain")?;
        let out = blocking(&self.0, move |s| {
            send_sign_in_again(s, &product, &r.session, &r.welcome_url, estate.as_deref())
        })
        .await?;
        Ok(Response::new(out))
    }

    /// **Asked before the card form, and it holds nothing.**
    ///
    /// It is an oracle by nature — anybody who can call it can learn whether a
    /// name is taken — and the mitigation is not here. This service is behind
    /// the same bearer as every other one; the surface that answers a stranger
    /// is the console's route in front of it, which carries a per-address budget
    /// and is where a limit belongs, because the addresses are there and not
    /// here.
    ///
    /// What this DOES refuse to do is say more than yes or no. `reason` is the
    /// sentence the customer reads, it never names another principal, and there
    /// is no verb here that lists anything.
    async fn check_name(
        &self,
        req: Request<pb::CheckNameRequest>,
    ) -> Result<Response<pb::CheckNameResponse>, Status> {
        let estate = req
            .extensions()
            .get::<crate::auth::CallerEstate>()
            .map(|e| e.0.clone());
        let r = req.into_inner();
        let product = product_named(&r.product, "CheckName")?;
        let out = blocking(&self.0, move |s| {
            Ok(
                match name_refusal(s, &product, &r.username, estate.as_deref())? {
                    None => pb::CheckNameResponse {
                        free: true,
                        reason: String::new(),
                    },
                    Some(reason) => pb::CheckNameResponse {
                        free: false,
                        reason,
                    },
                },
            )
        })
        .await?;
        Ok(Response::new(out))
    }

    /// **Mint the checkout for a name that has already been checked.**
    ///
    /// The name is checked AGAIN here, and that is not belt and braces: the
    /// caller's check is a courtesy to a person typing, and this one is the
    /// gate. It still closes nothing — a name free at this instant can be taken
    /// while the customer types a card, which is what `Rename` is for — but it
    /// means a console cannot mint a checkout for `admin` by skipping a step.
    ///
    /// `UNIMPLEMENTED` when the vendor mints no signup page (`invoice`, and any
    /// vendor written before this verb): that is the answer a console turns into
    /// its old fixed buy link, which is why it must be distinguishable from a
    /// refusal.
    async fn start(
        &self,
        req: Request<pb::StartSignupRequest>,
    ) -> Result<Response<pb::StartSignupResponse>, Status> {
        let estate = req
            .extensions()
            .get::<crate::auth::CallerEstate>()
            .map(|e| e.0.clone());
        let r = req.into_inner();
        let out = blocking(&self.0, move |s| {
            start_signup(s, &r, PayBy::Checkout, estate.as_deref())
        })
        .await?;
        Ok(Response::new(out))
    }

    /// **The race CheckName cannot close, settled without a refund.**
    ///
    /// See [`crate::signup::rename`]. The refusals are kept apart on the wire
    /// because a page answers each of them differently: `NOT_FOUND` is a session
    /// nobody has heard of, `FAILED_PRECONDITION` is a record a name cannot fix
    /// (and the message is the original refusal, so the page can show it),
    /// `INVALID_ARGUMENT` is the new name being refused in turn — which is the
    /// ordinary case, and the page simply asks again — and `UNAVAILABLE` is
    /// ours, where the customer waits rather than retypes.
    /// **What a new account costs, before anybody types a name** (the sign-up
    /// page, 2026-10-07). A read: no name, no vendor, no sink call. Where no
    /// account can be made, UNIMPLEMENTED — as `Start` answers, so a console
    /// offers nothing it could not finish.
    async fn plans(
        &self,
        req: Request<pb::SignupPlansRequest>,
    ) -> Result<Response<pb::SignupPlansResponse>, Status> {
        let r = req.into_inner();
        let s = &self.0;
        let product = product_named(&r.product, "Plans")?;
        if !s.signup_sink.creates_accounts_for(&product) {
            return Err(no_sink(&product));
        }
        let market = match monetize_proto::Market::try_from(r.market) {
            Ok(monetize_proto::Market::Se) => Some(monetize_pay::Market::Se),
            Ok(monetize_proto::Market::Fi) => Some(monetize_pay::Market::Fi),
            Ok(monetize_proto::Market::Dk) => Some(monetize_pay::Market::Dk),
            _ => None,
        };
        let default_market = s
            .terms
            .read()
            .unwrap_or_else(|e| e.into_inner())
            .default_market;
        // ★ Room by the rule (round 5.3.1, owner 2026-10-08: ONE bar at sign-up
        // too, "1 month" at 10 GiB and "12 months" from 10 to 1000 GiB): where
        // this deployment prices plans, a new account is offered THEM, priced
        // now in its market, each under its priced id.
        let in_market = market.unwrap_or(default_market);
        if let Some(rooms) = crate::plans::signup_rooms(s, &product, in_market) {
            let plans = rooms
                .into_iter()
                .map(|room| pb::SignupPlanOffer {
                    id: room.id,
                    name: room.name,
                    resources_words: format!(
                        "{} of room, kept on the server and its replica",
                        room_words(room.plan.cap_bytes)
                    ),
                    price_words: format!(
                        "{} {}",
                        monetize_pay::Money {
                            minor: room.plan.amount_minor,
                            currency: room.plan.currency
                        }
                        .in_words(),
                        period_words(room.plan.period_days)
                    ),
                    cap_bytes: room.plan.cap_bytes,
                    period_days: room.plan.period_days,
                })
                .collect();
            return Ok(Response::new(pb::SignupPlansResponse {
                plans,
                market: crate::convert::market_to_pb(in_market) as i32,
            }));
        }
        let table = s.signup_plans.snapshot_of(&product);
        // ONE market, and its name: the page sends it back with the order.
        let one = market_on_offer(&table, &product, market, default_market);
        let plans = plans_on_offer(&table, &product, market, default_market)
            .into_iter()
            .map(|p| pb::SignupPlanOffer {
                id: p.id,
                name: p.name,
                resources_words: p.resources_words,
                price_words: p.price_words,
                cap_bytes: p.cap_bytes,
                period_days: p.period_days,
            })
            .collect();
        let market = one
            .map(|m| crate::convert::market_to_pb(m) as i32)
            .unwrap_or_default();
        Ok(Response::new(pb::SignupPlansResponse { plans, market }))
    }

    async fn rename(
        &self,
        req: Request<pb::RenameSignupRequest>,
    ) -> Result<Response<pb::RenameSignupResponse>, Status> {
        let estate = req
            .extensions()
            .get::<crate::auth::CallerEstate>()
            .map(|e| e.0.clone());
        let r = req.into_inner();
        let out = blocking(&self.0, move |s| {
            use crate::signup::RenameRefusal;
            let vendor = row_vendor(s, &r.vendor, &r.session, estate.as_deref());
            match crate::signup::rename(s, &vendor, &r.session, &r.username) {
                Ok(rec) => Ok(pb::RenameSignupResponse {
                    status: Some(status_response(&s.signups, &rec, s.now() as i64)),
                }),
                Err(RenameRefusal::Unknown) => Err(Status::not_found(
                    "no signup here has that checkout session",
                )),
                Err(RenameRefusal::NotRenameable(why)) => Err(Status::failed_precondition(why)),
                Err(RenameRefusal::Name(why)) => Err(Status::invalid_argument(why)),
                // Money has moved here, so the sentence says they need not pay again.
                Err(RenameRefusal::Unavailable(why)) => Err(unavailable_for_customer(
                    "rename",
                    &why,
                    crate::signup::words::NOT_ANSWERING_PAID,
                )),
            }
        })
        .await?;
        Ok(Response::new(out))
    }
}

#[tonic::async_trait]
impl SignupAdmin for SignupAdminService {
    async fn list(
        &self,
        req: Request<pb::ListSignupsRequest>,
    ) -> Result<Response<pb::ListSignupsResponse>, Status> {
        let limit = req.into_inner().limit as usize;
        let rows = blocking(&self.0, move |s| {
            let rows = s.signups.list(limit).map_err(store_err)?;
            Ok(rows
                .iter()
                .map(|rec| row_to_pb(&s.signups, rec))
                .collect::<Vec<_>>())
        })
        .await?;
        Ok(Response::new(pb::ListSignupsResponse { signups: rows }))
    }

    /// **The owed-back queue.** See [`crate::signup::SignupStore::owed_back`]:
    /// every payment taken for an account that was never created, oldest first,
    /// UNCAPPED. `List`'s ceiling is a console page's and this is not a page —
    /// a deployment with six hundred refusals owes six hundred people.
    async fn list_owed_back(
        &self,
        _req: Request<pb::ListOwedBackRequest>,
    ) -> Result<Response<pb::ListOwedBackResponse>, Status> {
        let rows = blocking(&self.0, move |s| {
            let rows = s.signups.owed_back().map_err(store_err)?;
            Ok(rows
                .iter()
                .map(|rec| row_to_pb(&s.signups, rec))
                .collect::<Vec<_>>())
        })
        .await?;
        Ok(Response::new(pb::ListOwedBackResponse {
            total: rows.len() as u64,
            signups: rows,
        }))
    }

    /// See [`crate::signup::resend_welcome`]. The codes are the proto's.
    async fn resend_welcome(
        &self,
        req: Request<pb::ResendWelcomeRequest>,
    ) -> Result<Response<pb::ResendWelcomeResponse>, Status> {
        let r = req.into_inner();
        let outcome = blocking(&self.0, move |s| {
            use crate::signup::ResendRefusal;
            crate::signup::resend_welcome(s, &r.vendor, &r.session, r.force).map_err(|e| match e {
                ResendRefusal::Unknown => {
                    Status::not_found(format!("no signup {}:{} in the store", r.vendor, r.session))
                }
                ResendRefusal::NotSendable(why) => Status::failed_precondition(why),
                ResendRefusal::Unavailable(why) => Status::unavailable(why),
            })
        })
        .await?;
        Ok(Response::new(pb::ResendWelcomeResponse { outcome }))
    }

    /// **Give a refused signup's money back.** See [`crate::signup::refund`];
    /// OPERATOR BEARER ONLY ([`operator_only`]). The codes are the proto's.
    async fn refund(
        &self,
        req: Request<pb::RefundSignupRequest>,
    ) -> Result<Response<pb::RefundSignupResponse>, Status> {
        operator_only(&req, "Refund")?;
        let r = req.into_inner();
        let out = blocking(&self.0, move |s| {
            // A session that is no signup may be an ORDER's (g-refund): the
            // same verb, the same operator bearer, written in the ledger.
            let out = match crate::signup::refund(
                s,
                &r.vendor,
                &r.session,
                r.amount_minor,
                &r.reason,
                r.force,
            ) {
                Err(crate::signup::RefundRefusal::Unknown) => crate::reversal::refund_order(
                    s,
                    &r.vendor,
                    &r.session,
                    r.amount_minor,
                    &r.reason,
                ),
                other => other,
            }
            .map_err(|e| refund_refusal(&r.vendor, &r.session, e))?;
            Ok(refund_to_pb(&r.session, &out))
        })
        .await?;
        Ok(Response::new(out))
    }

    /// **Close out a row refunded by hand.** See
    /// [`crate::signup::settle_by_hand`]; OPERATOR BEARER ONLY.
    async fn settle(
        &self,
        req: Request<pb::SettleSignupRequest>,
    ) -> Result<Response<pb::RefundSignupResponse>, Status> {
        operator_only(&req, "Settle")?;
        let r = req.into_inner();
        let out = blocking(&self.0, move |s| {
            let out = crate::signup::settle_by_hand(s, &r.vendor, &r.session, &r.note)
                .map_err(|e| refund_refusal(&r.vendor, &r.session, e))?;
            Ok(refund_to_pb(&r.session, &out))
        })
        .await?;
        Ok(Response::new(out))
    }
}

/// **The money verbs take the OPERATOR bearer, never the service one**
/// (g-refund-verb). The service bearer is held by the console backends —
/// gunnar-ui's customer-facing BFF among them — and anything holding it could
/// otherwise give any payment back. [`crate::auth::signup_admin_interceptor`]
/// marks a call that carried the operator bearer; everything else is refused
/// here, whichever bearer let it past the door.
fn operator_only<T>(req: &Request<T>, verb: &str) -> Result<(), Status> {
    if req.extensions().get::<crate::auth::Operator>().is_some() {
        return Ok(());
    }
    Err(Status::permission_denied(format!(
        "SignupAdmin.{verb} takes the OPERATOR bearer ({} or <data_dir>/{}), not the service bearer; a server with none configured refuses it to everybody",
        crate::config::OPERATOR_TOKEN_ENV,
        crate::config::OPERATOR_TOKEN_FILE
    )))
}

fn refund_refusal(vendor: &str, session: &str, e: crate::signup::RefundRefusal) -> Status {
    use crate::signup::RefundRefusal as R;
    match e {
        R::Unknown => Status::not_found(format!(
            "no signup and no order {vendor}:{session} in this deployment"
        )),
        R::NotRefundable(why) => Status::failed_precondition(why),
        R::Invalid(why) => Status::invalid_argument(why),
        R::Unavailable(why) => Status::unavailable(why),
    }
}

/// The wire state of a refund row; `UNSPECIFIED` is "none recorded".
fn refund_state_of(r: Option<&crate::signup::SignupRefund>) -> pb::RefundState {
    use crate::signup::SignupRefund as F;
    match r {
        None => pb::RefundState::Unspecified,
        Some(F::Requested { .. }) => pb::RefundState::Requested,
        Some(F::Done { .. }) => pb::RefundState::Done,
        Some(F::SettledByHand { .. }) => pb::RefundState::SettledByHand,
    }
}

fn refund_to_pb(session: &str, r: &crate::signup::SignupRefund) -> pb::RefundSignupResponse {
    use crate::signup::SignupRefund as F;
    let state = refund_state_of(Some(r)) as i32;
    match r {
        F::Requested {
            amount,
            reason,
            at_unix_ms,
            ..
        } => pb::RefundSignupResponse {
            // Not yet confirmed; the key it is (being) sent under.
            refund_id: crate::signup::refund_key(session, amount.minor),
            amount: Some(crate::convert::money_to_pb(*amount)),
            state,
            reason: reason.clone(),
            requested_at_unix_ms: *at_unix_ms,
            done_at_unix_ms: 0,
        },
        F::Done {
            refund_id,
            amount,
            reason,
            requested_at_unix_ms,
            at_unix_ms,
            ..
        } => pb::RefundSignupResponse {
            refund_id: refund_id.clone(),
            amount: Some(crate::convert::money_to_pb(*amount)),
            state,
            reason: reason.clone(),
            requested_at_unix_ms: *requested_at_unix_ms,
            done_at_unix_ms: *at_unix_ms,
        },
        F::SettledByHand { note, at_unix_ms } => pb::RefundSignupResponse {
            refund_id: String::new(),
            amount: None,
            state,
            reason: note.clone(),
            requested_at_unix_ms: 0,
            done_at_unix_ms: *at_unix_ms,
        },
    }
}

/// The wire spelling of [`crate::signup::Owed`]. `UNSPECIFIED` for a row that
/// is not a refusal, which is what proto3's zero value means here — exactly as
/// [`refusal_of`] uses it.
fn owed_to_pb(owed: Option<crate::signup::Owed>) -> pb::signup_row::Owed {
    use crate::signup::Owed as O;
    use pb::signup_row::Owed as W;
    match owed {
        None => W::Unspecified,
        Some(O::Unrecorded) => W::Unrecorded,
        Some(O::Refund) => W::Refund,
        Some(O::RefundAndTheNameMayBeSpent) => W::RefundAndTheNameMayBeSpent,
        Some(O::RenameOrRefund) => W::RenameOrRefund,
    }
}

/// One store row as the console reads it. The refusal reason is carried
/// verbatim: it is the operator's answer to "why did this customer's money
/// arrive and their account not". A PENDING row carries the sink's last "not
/// now" in the same field — the clock skew, the timeout — which is the one
/// place that sentence is allowed to be read.
fn row_to_pb(store: &crate::signup::SignupStore, rec: &SignupRecord) -> pb::SignupRow {
    let (username, namespace, reason) = match &rec.state {
        SignupState::Pending => (
            rec.signup.username.clone(),
            String::new(),
            store
                .waiting_on(&rec.signup.vendor, &rec.signup.session)
                .unwrap_or_default(),
        ),
        SignupState::Created {
            namespace,
            username,
            ..
        } => (username.clone(), namespace.clone(), String::new()),
        // A refused row still shows what the customer ASKED to be called —
        // "the name was rejected" is unreadable without the name.
        SignupState::Refused { reason, .. } => (
            rec.signup.username.clone(),
            String::new(),
            crate::signup::legacy_price_refusal(reason).unwrap_or_else(|| reason.clone()),
        ),
    };
    // The money's own field, and the sentence that goes with it. Built from the
    // record and not from `reason`: a console that had to read prose to know
    // whether a name was spent would be one rewording away from being wrong.
    let owed = rec.state.owed();
    pb::SignupRow {
        owed: owed_to_pb(owed) as i32,
        remedy: owed.map(|o| o.remedy().to_owned()).unwrap_or_default(),
        vendor: rec.signup.vendor.clone(),
        session: rec.signup.session.clone(),
        state: state_of(rec) as i32,
        username,
        namespace,
        reason,
        product: rec.signup.product.clone(),
        plan: rec.signup.plan.clone(),
        amount: Some(crate::convert::money_to_pb(rec.signup.amount)),
        paid_at_unix_ms: rec.signup.paid_at_unix_ms,
        recorded_at_unix_ms: rec.recorded_at_unix_ms,
        decided_at_unix_ms: rec.state.decided_at_unix_ms(),
        email: rec.signup.email.clone(),
        livemode: monetize_pay::livemode_of(&rec.signup.vendor, &rec.signup.session),
        refund: refund_state_of(
            store
                .refund_of(&rec.signup.vendor, &rec.signup.session)
                .ok()
                .flatten()
                .as_ref(),
        ) as i32,
    }
}

/// ★ g-currencies (money 2026-09-28): the Danish company sells the signup in
/// the customer's own currency — one plan per market, and a request that
/// names no plan but names a MARKET gets that market's plan. Two plans and
/// neither a plan nor a market is still a refusal that lists them.
#[cfg(test)]
mod plan_by_market_tests {
    use super::*;
    use monetize_pay::{Currency, Market};

    fn plans() -> std::collections::BTreeMap<String, crate::config::SignupPlan> {
        let p = |minor, currency| crate::config::SignupPlan {
            amount_minor: minor,
            currency,
            cap_bytes: 10 << 30,
            period_days: 30,
        };
        [
            ("gunnar/10gb-1m".to_string(), p(10_000, Currency::Sek)),
            ("gunnar/10gb-1m-fi".to_string(), p(870, Currency::Eur)),
            ("gunnar/10gb-1m-dk".to_string(), p(7_500, Currency::Dkk)),
        ]
        .into()
    }

    #[test]
    fn a_market_picks_its_own_plan_and_no_market_with_several_plans_is_refused() {
        let ps = plans();
        assert_eq!(
            plan_for_market(&ps, "", Some(Market::Dk), Market::Se)
                .unwrap()
                .0,
            "gunnar/10gb-1m-dk"
        );
        assert_eq!(
            plan_for_market(&ps, "", Some(Market::Fi), Market::Se)
                .unwrap()
                .1
                .currency,
            Currency::Eur
        );
        assert_eq!(
            plan_for_market(&ps, "", Some(Market::Se), Market::Se)
                .unwrap()
                .0,
            "gunnar/10gb-1m"
        );
        assert_eq!(
            plan_for_market(&ps, "gunnar/10gb-1m-fi", Some(Market::Dk), Market::Se)
                .unwrap()
                .0,
            "gunnar/10gb-1m-fi",
            "a named plan wins"
        );
        let one: std::collections::BTreeMap<_, _> = plans().into_iter().take(1).collect();
        assert_eq!(
            plan_for_market(&one, "", Some(Market::Dk), Market::Se)
                .unwrap()
                .0,
            "gunnar/10gb-1m",
            "one plan is THE plan, whatever the market"
        );
    }

    /// ★ release-3 (MEASURED on the dwarf mock 2026-09-29, install-orig-8): a
    /// signup naming no plan and no market — the functest, and every console
    /// whose browser language names no market (en-US) — was refused 409 once
    /// money sold a plan per market. With exactly ONE plan per market, no market
    /// is the DEFAULT market's plan; two plans in one market stay a named refusal.
    #[test]
    fn no_market_takes_the_default_markets_plan_when_each_market_has_one() {
        let ps = plans();
        assert_eq!(
            plan_for_market(&ps, "", None, Market::Se).unwrap().0,
            "gunnar/10gb-1m",
            "no market: the default market's one plan"
        );
        assert_eq!(
            plan_for_market(&ps, "", None, Market::Dk).unwrap().0,
            "gunnar/10gb-1m-dk",
            "the deployment's default market decides"
        );
        let mut two_in_se = plans();
        let p = two_in_se["gunnar/10gb-1m"];
        two_in_se.insert("gunnar/50gb-1m".into(), p);
        let refused = plan_for_market(&two_in_se, "", None, Market::Se).unwrap_err();
        assert!(
            refused.message().contains("named none"),
            "two plans in one market and no name: refused, never a pick: {refused:?}"
        );
        assert_eq!(
            plan_for_market(&two_in_se, "", Some(Market::Dk), Market::Se)
                .unwrap()
                .0,
            "gunnar/10gb-1m-dk",
            "a market with ONE plan still picks it"
        );
    }
}

#[cfg(test)]
mod plans_on_offer_tests {
    //! **`Signup.Plans`** (the sign-up page, 2026-10-07): what a new account
    //! costs, before anybody types a name — the page shows these words and
    //! writes no price of its own.
    use std::sync::atomic::AtomicU64;
    use std::sync::Arc;

    use monetize_pay::{Currency, Market};

    use super::*;
    use crate::signup::tests::{state_with, CountingSink};

    fn plans() -> std::collections::BTreeMap<String, crate::config::SignupPlan> {
        let p = |minor, currency, gib: u64, days| crate::config::SignupPlan {
            amount_minor: minor,
            currency,
            cap_bytes: gib << 30,
            period_days: days,
        };
        [
            (
                "gunnar/10gb-1m".to_string(),
                p(10_000, Currency::Sek, 10, 30),
            ),
            (
                "gunnar/50gb-1m".to_string(),
                p(40_000, Currency::Sek, 50, 30),
            ),
            (
                "gunnar/10gb-1m-dk".to_string(),
                p(7_500, Currency::Dkk, 10, 30),
            ),
            (
                "gunnar/100gb-1y".to_string(),
                p(400_000, Currency::Sek, 100, 365),
            ),
            (
                "holger/10gb-1m".to_string(),
                p(9_900, Currency::Sek, 10, 30),
            ),
        ]
        .into()
    }

    /// ★ **The plans on offer, smallest first, each as words** — the
    /// product's own, in the customer's market where it has any.
    #[test]
    fn the_plans_on_offer_are_the_markets_own_smallest_first_as_words() {
        let shown = plans_on_offer(&plans(), "gunnar", Some(Market::Se), Market::Se);
        assert_eq!(
            shown.iter().map(|o| o.id.as_str()).collect::<Vec<_>>(),
            ["gunnar/10gb-1m", "gunnar/50gb-1m", "gunnar/100gb-1y"]
        );
        let ten = &shown[0];
        assert_eq!(
            (ten.name.as_str(), ten.price_words.as_str()),
            ("10 GB", "100.00 SEK a month")
        );
        assert_eq!(
            ten.resources_words,
            "10 GB of room, kept on the server and its replica"
        );
        assert_eq!(ten.cap_bytes, 10 << 30);
        assert_eq!(shown[2].price_words, "4000.00 SEK a year");
        // A Dane sees the Danish plan; holger's plans are holger's.
        let dk = plans_on_offer(&plans(), "gunnar", Some(Market::Dk), Market::Se);
        assert_eq!(
            dk.iter().map(|o| o.id.as_str()).collect::<Vec<_>>(),
            ["gunnar/10gb-1m-dk"]
        );
        assert!(plans_on_offer(&plans(), "", None, Market::Se)
            .iter()
            .all(|o| o.id.starts_with("gunnar/") || o.id.starts_with("holger/")));
    }

    /// The kit's own `[signups.<product>.plans]` (private-gunnar-ops deploy/monetize.toml.tmpl):
    /// ONE 10 GB plan per market, in its currency, and the account at the shop.
    fn the_kits_plans() -> std::collections::BTreeMap<String, crate::config::SignupPlan> {
        let p = |minor, currency, gib: u64, days| crate::config::SignupPlan {
            amount_minor: minor,
            currency,
            cap_bytes: gib << 30,
            period_days: days,
        };
        [
            (
                "gunnar/10gb-1m".to_string(),
                p(11_000, Currency::Sek, 10, 30),
            ),
            (
                "gunnar/10gb-1m-fi".to_string(),
                p(1_000, Currency::Eur, 10, 30),
            ),
            (
                "gunnar/10gb-1m-dk".to_string(),
                p(7_460, Currency::Dkk, 10, 30),
            ),
            ("gunnar/account".to_string(), p(0, Currency::Sek, 0, 0)),
        ]
        .into()
    }

    fn currencies(shown: &[PlanOnOffer]) -> std::collections::BTreeSet<String> {
        shown
            .iter()
            .map(|o| {
                o.price_words
                    .split_whitespace()
                    .nth(1)
                    .unwrap_or_default()
                    .to_owned()
            })
            .collect()
    }

    /// ★ **ONE market's plans, never a mix of currencies** (test2, owner
    /// 2026-10-08: on `/signup?plan=10gb` every press of + changed the
    /// CURRENCY — `Signup.Plans` answered every market's plans to a browser
    /// whose language names no market, and the page stepped 110 SEK → 10 EUR →
    /// 74.60 DKK). No market, or one with nothing on offer: the deployment's
    /// DEFAULT market's, and the answer names the market it is.
    #[test]
    fn the_plans_on_offer_are_one_markets_never_a_mix_of_currencies() {
        let kit = the_kits_plans();
        let none = plans_on_offer(&kit, "gunnar", None, Market::Se);
        assert_eq!(
            none.iter().map(|o| o.id.as_str()).collect::<Vec<_>>(),
            ["gunnar/10gb-1m"],
            "no market: the default market's one plan, not three currencies"
        );
        assert_eq!(
            market_on_offer(&kit, "gunnar", None, Market::Se),
            Some(Market::Se)
        );
        let dk_home = plans_on_offer(&kit, "gunnar", None, Market::Dk);
        assert_eq!(
            dk_home.iter().map(|o| o.id.as_str()).collect::<Vec<_>>(),
            ["gunnar/10gb-1m-dk"],
            "the deployment's default market decides"
        );
        assert_eq!(
            plans_on_offer(&kit, "gunnar", Some(Market::Fi), Market::Se)[0].price_words,
            "10.00 EUR a month",
            "a Finn sees the Finnish plan"
        );
        // A market with nothing on offer is the default market's, whole.
        let fi = plans_on_offer(&plans(), "gunnar", Some(Market::Fi), Market::Se);
        assert_eq!(
            fi.iter().map(|o| o.id.as_str()).collect::<Vec<_>>(),
            ["gunnar/10gb-1m", "gunnar/50gb-1m", "gunnar/100gb-1y"]
        );
        assert_eq!(
            market_on_offer(&plans(), "gunnar", Some(Market::Fi), Market::Se),
            Some(Market::Se)
        );
        // A default market with nothing on offer: the first market that has some.
        let only_dk: std::collections::BTreeMap<_, _> = kit
            .iter()
            .filter(|(id, _)| id.ends_with("-dk"))
            .map(|(k, v)| (k.clone(), *v))
            .collect();
        assert_eq!(
            market_on_offer(&only_dk, "gunnar", None, Market::Se),
            Some(Market::Dk)
        );
        for (market, default) in [
            (None, Market::Se),
            (Some(Market::Fi), Market::Se),
            (Some(Market::Dk), Market::Se),
            (None, Market::Dk),
        ] {
            for table in [kit.clone(), plans()] {
                let shown = plans_on_offer(&table, "gunnar", market, default);
                assert!(
                    currencies(&shown).len() <= 1,
                    "{market:?}/{default:?}: one currency, never {:?}",
                    currencies(&shown)
                );
            }
        }
        assert_eq!(
            market_on_offer(&Default::default(), "gunnar", None, Market::Se),
            None,
            "nothing on offer is no market"
        );
    }

    /// ★ **Over the wire: one market, and its name** — the answer to a page
    /// that names no market is the default market's plans, said as `SE`.
    #[tokio::test]
    async fn the_plans_answer_one_market_over_the_wire_and_name_it() {
        use monetize_proto::signup_server::Signup as _;
        let state = state_with(CountingSink::creating(), Arc::new(AtomicU64::new(5)));
        state.signup_plans.set(the_kits_plans(), Default::default());
        let out = SignupService(state.clone())
            .plans(Request::new(pb::SignupPlansRequest {
                product: "gunnar".into(),
                market: 0,
            }))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(
            out.plans
                .iter()
                .map(|p| p.price_words.as_str())
                .collect::<Vec<_>>(),
            ["110.00 SEK a month"],
            "{out:?}"
        );
        assert_eq!(
            out.market,
            pb::Market::Se as i32,
            "the answer names its market"
        );
        let dk = SignupService(state)
            .plans(Request::new(pb::SignupPlansRequest {
                product: "gunnar".into(),
                market: pb::Market::Dk as i32,
            }))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(
            (dk.plans.len(), dk.plans[0].id.as_str(), dk.market),
            (1, "gunnar/10gb-1m-dk", pb::Market::Dk as i32)
        );
    }

    /// **Over the wire**, and refused by name where no account can be made.
    #[tokio::test]
    async fn the_plans_answer_over_the_wire_and_nothing_is_offered_where_no_account_can_be_made() {
        use monetize_proto::signup_server::Signup as _;
        let state = state_with(CountingSink::creating(), Arc::new(AtomicU64::new(5)));
        let out = SignupService(state)
            .plans(Request::new(pb::SignupPlansRequest {
                product: "gunnar".into(),
                market: pb::Market::Se as i32,
            }))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(out.plans.len(), 1);
        assert_eq!(
            (
                out.plans[0].id.as_str(),
                out.plans[0].name.as_str(),
                out.plans[0].price_words.as_str()
            ),
            ("gunnar/10gb-1m", "10 GB", "100.00 SEK a month")
        );
        // No sink that makes an account: none is offered.
        let mut bare = crate::state::AppState::in_memory(crate::registry::Registry::new());
        bare.signup_sink = Arc::new(crate::signup::NoSink);
        bare.signup_plans = plans().into();
        let refused = SignupService(Arc::new(bare))
            .plans(Request::new(pb::SignupPlansRequest {
                product: "gunnar".into(),
                market: 0,
            }))
            .await
            .unwrap_err();
        assert_eq!(refused.code(), tonic::Code::Unimplemented, "{refused:?}");
    }
}

#[cfg(test)]
mod tests {
    use std::sync::atomic::AtomicU64;
    use std::sync::Arc;

    use monetize_pay::signup::SignupError;

    use super::*;
    use crate::signup::tests::{a_signup, state_with, CountingSink};
    use crate::signup::{settle, words};

    /// ★ **One line per `Signup.Start`, with the total and every stage** — test2
    /// 2026-09-30 had 25 s with NOTHING logged between two lines, and the time
    /// could not be put anywhere. Past [`START_BUDGET`] it says FAILED, which the
    /// front raises to WARN.
    #[test]
    fn a_signup_start_says_its_total_and_every_stage_once() {
        static SAID: std::sync::Mutex<Vec<String>> = std::sync::Mutex::new(Vec::new());
        {
            let mut t = StartTimings::saying("henrik", |l| SAID.lock().unwrap().push(l.to_owned()));
            t.mark("name");
            t.mark("capacity");
            t.mark("sold-capacity");
            t.mark_owned("vendor stripe".into());
            t.outcome = "minted";
        }
        let said = SAID.lock().unwrap().clone();
        assert_eq!(said.len(), 1, "{said:?}");
        let l = &said[0];
        assert!(l.contains("signup start \"henrik\": minted in "), "{l}");
        for stage in ["name ", "capacity ", "sold-capacity ", "vendor stripe "] {
            assert!(l.contains(stage), "{stage:?} missing: {l}");
        }
        assert!(!l.contains("FAILED"), "a fast start is not a warning: {l}");
        let t = StartTimings::saying("olle", |_| {});
        let slow = t.line(START_BUDGET + std::time::Duration::from_millis(1));
        assert!(
            slow.contains("not minted in ") && slow.contains("FAILED"),
            "{slow}"
        );
    }

    /// **What `Signup.Status` puts on the wire for a signup pending on a clock
    /// skew: the settling sentence, and none of the skew.** The operator's
    /// `SignupAdmin.List` row for the same session carries gunnar's words.
    #[test]
    fn a_skew_pending_status_carries_customer_words_and_the_admin_row_carries_the_skew() {
        let skew = "gunnar Access.ListPrincipals -> Unauthenticated: the credential is 412000 ms away from this server's clock; the window is ±300000 ms";
        let state = state_with(
            CountingSink::answering(Err(SignupError::Unavailable(skew.into()))),
            Arc::new(AtomicU64::new(1_000)),
        );
        settle(&state, &a_signup("cs_skew", "bob"));
        let rec = state.signups.get("mockpay", "cs_skew").unwrap().unwrap();

        let wire = status_response(&state.signups, &rec, state.now() as i64);
        assert_eq!(wire.state(), pb::signup_status_response::State::Pending);
        assert_eq!(
            wire.words,
            words::BEING_CREATED,
            "a skew is a settle, never maintenance (PAID-WORDS)"
        );
        let customer = format!("{} {}", wire.words, wire.reason).to_lowercase();
        for banned in ["clock", "skew", "credential", "unauthenticated", "ms away"] {
            assert!(
                !customer.contains(banned),
                "the customer reads {banned:?}: {customer}"
            );
        }

        let row = row_to_pb(&state.signups, &rec);
        assert_eq!(row.reason, skew, "the operator reads what gunnar said");
        // A signup still being tried owes nobody anything YET: it may still
        // become an account.
        assert_eq!(row.owed(), pb::signup_row::Owed::Unspecified);
        assert!(row.remedy.is_empty());
    }

    /// (r) **`SignupAdmin.ListOwedBack` serves the queue, with the job on each
    /// row** — money taken, account not created, and the sentence that says what
    /// a human must do about it.
    ///
    /// The count on the response is the same number the poll line prints, so a
    /// console and a journal cannot disagree about how many people are waiting
    /// for their money.
    #[tokio::test]
    async fn list_owed_back_serves_the_payments_no_account_was_made_for() {
        use monetize_proto::signup_admin_server::SignupAdmin as _;
        let state = state_with(
            CountingSink::answering(Err(SignupError::Refused(
                "Entitlement.Set: quota rejected".into(),
            ))),
            Arc::new(AtomicU64::new(5)),
        );
        settle(&state, &crate::signup::tests::a_signup("cs_owed", "bob"));

        let svc = SignupAdminService(state.clone());
        let out = svc
            .list_owed_back(Request::new(pb::ListOwedBackRequest {}))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(out.total, 1);
        let row = &out.signups[0];
        assert_eq!(row.session, "cs_owed");
        assert_eq!(row.owed(), pb::signup_row::Owed::RefundAndTheNameMayBeSpent);
        assert!(
            row.remedy.to_lowercase().contains("refund"),
            "{}",
            row.remedy
        );
        assert_eq!(
            row.amount.as_ref().map(|m| m.minor),
            Some(10_000),
            "the queue carries the money, not only the name"
        );
        assert_eq!(
            row.email, "bob@example.com",
            "an operator who cannot see whom to pay back cannot pay anybody back"
        );

        // A CREATED signup is not on the queue and carries no remedy.
        let created = state_with(CountingSink::creating(), Arc::new(AtomicU64::new(6)));
        settle(&created, &crate::signup::tests::a_signup("cs_made", "bob"));
        let out = SignupAdminService(created)
            .list_owed_back(Request::new(pb::ListOwedBackRequest {}))
            .await
            .unwrap()
            .into_inner();
        assert_eq!((out.total, out.signups.len()), (0, 0));
    }

    // ── g-refund-verb (2026-09-28): the refund, by the operator, once ─────────

    /// A deployment whose `mockpay` vendor is the testing double, so a refund
    /// reaches a vendor that keeps Stripe's idempotency promise and records
    /// every call it was sent.
    fn refund_rig(
        sink: Arc<dyn monetize_pay::signup::SignupSink>,
    ) -> (Arc<AppState>, crate::testing::CallbackPay) {
        let pay = crate::testing::CallbackPay::new("whsec_test_only");
        let mut state =
            AppState::in_memory(crate::registry::Registry::new().sells("gunnar", pay.clone()));
        state.signup_sink = sink;
        state.signup_plans = crate::signup::tests::plans().into();
        let tick = Arc::new(AtomicU64::new(1_788_436_900_000));
        state.clock = Box::new(move || tick.load(std::sync::atomic::Ordering::SeqCst));
        (Arc::new(state), pay)
    }

    /// A signup the CHECKS refused (a plan nobody sells): `Owed::Refund`,
    /// money taken, nothing made.
    fn refused_for_a_refund(state: &AppState, pay: &crate::testing::CallbackPay, session: &str) {
        let mut s = a_signup(session, "bob");
        s.plan = "gunnar/not-sold".into();
        pay.took_signup(session);
        let out = settle(state, &s);
        assert!(
            matches!(
                out,
                SignupState::Refused {
                    owed: crate::signup::Owed::Refund,
                    ..
                }
            ),
            "{out:?}"
        );
    }

    fn as_operator<T>(msg: T) -> Request<T> {
        let mut r = Request::new(msg);
        r.extensions_mut().insert(crate::auth::Operator);
        r
    }

    fn refund_req(session: &str, amount_minor: u64) -> pb::RefundSignupRequest {
        pb::RefundSignupRequest {
            vendor: "mockpay".into(),
            session: session.into(),
            amount_minor,
            reason: "S10: refused at signup".into(),
            force: false,
        }
    }

    /// (r) **g-refund-verb: a refused signup's money goes back ONCE, and the
    /// alarm settles.** Before: `Owed::Refund` rows could only be refunded by
    /// hand in the vendor's dashboard, and nothing could take one off the
    /// owed-back queue, so `owed_back=` stayed red for ever.
    ///
    /// `Refund` twice: exactly one vendor call, under the key Stripe keys a
    /// refund by (`<session>:refund:<amount>`), the whole payment when the
    /// amount is 0, the record DONE, the queue empty. And a request without the
    /// operator bearer's mark is refused and calls nobody.
    #[tokio::test]
    async fn refund_gives_a_refused_signups_money_back_once_and_settles_the_owed_back_queue() {
        use monetize_proto::signup_admin_server::SignupAdmin as _;
        let (state, pay) = refund_rig(CountingSink::creating());
        refused_for_a_refund(&state, &pay, "cs_owed");
        let svc = SignupAdminService(state.clone());

        // The service bearer's call carries no operator mark: refused, and the
        // vendor is never asked.
        let denied = svc
            .refund(Request::new(refund_req("cs_owed", 0)))
            .await
            .unwrap_err();
        assert_eq!(denied.code(), tonic::Code::PermissionDenied, "{denied:?}");
        assert!(
            pay.refund_calls().is_empty(),
            "a refused caller reached the vendor"
        );

        let first = svc
            .refund(as_operator(refund_req("cs_owed", 0)))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(first.state(), pb::RefundState::Done);
        assert_eq!(
            first.amount.as_ref().map(|m| m.minor),
            Some(10_000),
            "0 is the whole payment"
        );
        assert_eq!(first.refund_id, "cs_owed:refund:10000");
        assert!(first.done_at_unix_ms > 0);

        let second = svc
            .refund(as_operator(refund_req("cs_owed", 0)))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(second, first, "the second call answers the first refund");
        assert_eq!(
            pay.refund_calls(),
            vec!["cs_owed:refund:10000".to_string()],
            "exactly one vendor refund call"
        );
        assert_eq!(pay.refunds_made(), 1);

        assert!(
            state.signups.owed_back().unwrap().is_empty(),
            "a DONE refund is not owed back any more"
        );
        let out = svc
            .list_owed_back(Request::new(pb::ListOwedBackRequest {}))
            .await
            .unwrap()
            .into_inner();
        assert_eq!((out.total, out.signups.len()), (0, 0));
        // The row is still in the store, and says it was refunded.
        let rows = svc
            .list(Request::new(pb::ListSignupsRequest { limit: 0 }))
            .await
            .unwrap()
            .into_inner()
            .signups;
        assert_eq!(rows[0].refund(), pb::RefundState::Done);
    }

    /// (r) **The crash between the vendor's yes and our record of it.** The
    /// refund is REQUESTED, the vendor makes it, and the reply never arrives
    /// (a lost connection; the process dying is the same state on disk). The
    /// row stays on the queue as REQUESTED. The retry calls the vendor AGAIN
    /// under the SAME key — so the vendor refunds nothing twice — and the
    /// record completes.
    #[tokio::test]
    async fn a_refund_whose_reply_was_lost_is_finished_by_the_retry_under_the_same_key() {
        use monetize_proto::signup_admin_server::SignupAdmin as _;
        let (state, pay) = refund_rig(CountingSink::creating());
        refused_for_a_refund(&state, &pay, "cs_lost");
        let svc = SignupAdminService(state.clone());

        pay.lose_next_refund_reply();
        let lost = svc
            .refund(as_operator(refund_req("cs_lost", 4_000)))
            .await
            .unwrap_err();
        assert_eq!(lost.code(), tonic::Code::Unavailable, "{lost:?}");
        assert_eq!(pay.refunds_made(), 1, "the vendor did refund");
        let owed = svc
            .list_owed_back(Request::new(pb::ListOwedBackRequest {}))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(
            owed.total, 1,
            "REQUESTED is still owed: nobody heard the vendor say yes"
        );
        assert_eq!(owed.signups[0].refund(), pb::RefundState::Requested);

        // The retry names 0 ("the whole"), and still sends the RECORDED amount:
        // a different amount would be a different key, and a second refund.
        let done = svc
            .refund(as_operator(refund_req("cs_lost", 0)))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(done.state(), pb::RefundState::Done);
        assert_eq!(done.amount.as_ref().map(|m| m.minor), Some(4_000));
        assert_eq!(
            pay.refund_calls(),
            vec!["cs_lost:refund:4000".to_string(); 2],
            "the retry re-sent the same key"
        );
        assert_eq!(pay.refunds_made(), 1, "one refund at the vendor");
        assert!(state.signups.owed_back().unwrap().is_empty());
    }

    /// (r) **What the verb refuses, by name.** A PENDING signup (it may still
    /// become an account) even with `force`; a CREATED one without `force`;
    /// more than was paid; a vendor this server does not have; a session
    /// nobody has heard of. None of them reaches a vendor.
    #[tokio::test]
    async fn refund_refuses_what_is_not_owed_back_by_name() {
        use monetize_proto::signup_admin_server::SignupAdmin as _;
        let (state, pay) = refund_rig(CountingSink::creating());
        let svc = SignupAdminService(state.clone());

        refused_for_a_refund(&state, &pay, "cs_over");
        let over = svc
            .refund(as_operator(refund_req("cs_over", 10_001)))
            .await
            .unwrap_err();
        assert_eq!(over.code(), tonic::Code::InvalidArgument, "{over:?}");

        state
            .signups
            .record_pending(&a_signup("cs_pending", "carol"), 1)
            .unwrap();
        let pending = svc
            .refund(as_operator(pb::RefundSignupRequest {
                force: true,
                ..refund_req("cs_pending", 0)
            }))
            .await
            .unwrap_err();
        assert_eq!(
            pending.code(),
            tonic::Code::FailedPrecondition,
            "{pending:?}"
        );

        pay.took_signup("cs_made");
        settle(&state, &a_signup("cs_made", "bob"));
        let made = svc
            .refund(as_operator(refund_req("cs_made", 0)))
            .await
            .unwrap_err();
        assert_eq!(made.code(), tonic::Code::FailedPrecondition, "{made:?}");
        assert!(
            made.message().contains("force"),
            "the refusal names the way through: {}",
            made.message()
        );

        let mut ghost = a_signup("cs_ghost", "dave");
        ghost.vendor = "ghostpay".into();
        ghost.plan = "gunnar/not-sold".into();
        settle(&state, &ghost);
        let ghosted = svc
            .refund(as_operator(pb::RefundSignupRequest {
                vendor: "ghostpay".into(),
                ..refund_req("cs_ghost", 0)
            }))
            .await
            .unwrap_err();
        assert_eq!(
            ghosted.code(),
            tonic::Code::FailedPrecondition,
            "{ghosted:?}"
        );
        assert!(
            ghosted.message().contains("ghostpay"),
            "{}",
            ghosted.message()
        );

        let unknown = svc
            .refund(as_operator(refund_req("cs_nobody", 0)))
            .await
            .unwrap_err();
        assert_eq!(unknown.code(), tonic::Code::NotFound, "{unknown:?}");

        assert!(
            pay.refund_calls().is_empty(),
            "a refused refund called a vendor: {:?}",
            pay.refund_calls()
        );
        assert_eq!(
            state.signups.owed_back().unwrap().len(),
            2,
            "cs_over and cs_ghost are still owed"
        );
    }

    /// (r) **`force` refunds a CREATED signup, and the tax export credits it
    /// back.** The account stays (removing it is `Entitlement`'s, by hand);
    /// what the customer got back is not a sale — a correction nets it out
    /// (stinky row 17: the sale itself is never rewritten).
    #[tokio::test]
    async fn a_forced_refund_of_a_created_signup_is_credited_back_in_full() {
        use monetize_proto::signup_admin_server::SignupAdmin as _;
        let (state, pay) = refund_rig(CountingSink::creating());
        pay.took_signup("cs_made");
        settle(&state, &a_signup("cs_made", "bob"));
        let books = state.books.read().unwrap().clone();
        assert_eq!(
            crate::signup::tax_sales(&state.signups, &books)
                .unwrap()
                .len(),
            1
        );

        let svc = SignupAdminService(state.clone());
        let done = svc
            .refund(as_operator(pb::RefundSignupRequest {
                force: true,
                ..refund_req("cs_made", 0)
            }))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(done.state(), pb::RefundState::Done);
        let lines = crate::signup::tax_sales(&state.signups, &books).unwrap();
        assert_eq!(
            lines.iter().map(|s| s.credit).collect::<Vec<_>>(),
            [false, true],
            "the sale, then its credit: {lines:?}"
        );
        assert_eq!(
            lines.iter().map(|s| s.signed_net().minor).sum::<i64>(),
            0,
            "a sale refunded in full nets to nothing"
        );
        assert!(
            state.signups.owed_back().unwrap().is_empty(),
            "a created signup was never owed back"
        );
    }

    /// Stinky row 17 (VAT, 2026-10-10): **a forced refund a quarter after the
    /// signup is a correction in the REFUND's quarter.** The signup's quarter is
    /// a return that may already be filed; it must read the same after the
    /// money goes back.
    #[tokio::test]
    async fn a_forced_refund_a_quarter_later_is_a_correction_there_and_the_signups_quarter_never_moves(
    ) {
        use monetize::tax::{Amount, Declared, LedgerView, PeriodKind, TaxReport as _};
        use monetize_pay::{Currency, Money};
        use monetize_proto::signup_admin_server::SignupAdmin as _;
        use std::sync::atomic::Ordering::SeqCst;
        let pay = crate::testing::CallbackPay::new("whsec_test_only");
        let mut state =
            AppState::in_memory(crate::registry::Registry::new().sells("gunnar", pay.clone()));
        state.signup_sink = CountingSink::creating();
        state.signup_plans = crate::signup::tests::plans().into();
        let tick = Arc::new(AtomicU64::new(1_788_436_900_000));
        let clock = Arc::clone(&tick);
        state.clock = Box::new(move || clock.load(SeqCst));
        let state = Arc::new(state);

        let mut paid = a_signup("cs_made", "bob");
        paid.amount = Money {
            minor: 12_500,
            currency: Currency::Sek,
        };
        paid.tax = Money {
            minor: 2_500,
            currency: Currency::Sek,
        };
        pay.took_signup("cs_made");
        assert!(matches!(
            settle(&state, &paid),
            crate::signup::SignupState::Created { .. }
        ));

        let books = state.books.read().unwrap().clone();
        let view = || LedgerView {
            home_country: "SE".into(),
            sales: crate::signup::tax_sales(&state.signups, &books).unwrap(),
        };
        let quarter_of = |at: u64| {
            PeriodKind::Quarterly
                .periods(2026)
                .into_iter()
                .find(|p| p.contains(at))
                .unwrap()
        };
        let se = Declared {
            country: "SE".into(),
            basis_points: 2500,
            period: PeriodKind::Quarterly,
            currency: Some(Currency::Sek),
        };
        let box_of = |r: &monetize::tax::Report, id: &str| {
            r.lines
                .iter()
                .find(|l| l.box_id == id)
                .and_then(|l| l.amount)
                .map(|a: Amount| a.minor)
        };
        let q_sale = quarter_of(paid.paid_at_unix_ms as u64);
        let filed = se.report(&view(), &q_sale).unwrap();
        assert_eq!(box_of(&filed, "sales"), Some(10_000));

        let refund_at = q_sale.to_unix_ms + 10 * 86_400_000;
        tick.store(refund_at, SeqCst);
        let svc = SignupAdminService(state.clone());
        let done = svc
            .refund(as_operator(pb::RefundSignupRequest {
                force: true,
                ..refund_req("cs_made", 5_000)
            }))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(done.state(), pb::RefundState::Done);

        assert_eq!(
            se.report(&view(), &q_sale).unwrap().lines,
            filed.lines,
            "the signup's filed quarter is untouched by a refund a quarter later"
        );
        let corrected = se.report(&view(), &quarter_of(refund_at)).unwrap();
        assert_eq!(
            box_of(&corrected, "sales"),
            Some(-4_000),
            "the net that went back, in the refund's quarter"
        );
        assert_eq!(
            box_of(&corrected, "output-tax"),
            Some(-1_000),
            "and its tax"
        );
    }

    /// (r) **A row refunded BY HAND is settled with the operator's note**, and
    /// leaves the queue. It moves no money; a row with a refund already
    /// recorded is not settled over it.
    #[tokio::test]
    async fn settle_closes_a_row_refunded_by_hand_and_moves_no_money() {
        use monetize_proto::signup_admin_server::SignupAdmin as _;
        let (state, pay) = refund_rig(CountingSink::creating());
        refused_for_a_refund(&state, &pay, "cs_hand");
        let svc = SignupAdminService(state.clone());
        let settle_req = |note: &str| pb::SettleSignupRequest {
            vendor: "mockpay".into(),
            session: "cs_hand".into(),
            note: note.into(),
        };

        assert_eq!(
            svc.settle(Request::new(settle_req("re_123 by rickard")))
                .await
                .unwrap_err()
                .code(),
            tonic::Code::PermissionDenied
        );
        assert_eq!(
            svc.settle(as_operator(settle_req("")))
                .await
                .unwrap_err()
                .code(),
            tonic::Code::InvalidArgument,
            "a settle says what was done"
        );
        let out = svc
            .settle(as_operator(settle_req("re_123 by rickard")))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(out.state(), pb::RefundState::SettledByHand);
        assert_eq!(out.reason, "re_123 by rickard");
        assert!(state.signups.owed_back().unwrap().is_empty());
        assert!(pay.refund_calls().is_empty(), "settling moves no money");
        // And a settled row is not then refunded a second time by the verb.
        assert_eq!(
            svc.refund(as_operator(refund_req("cs_hand", 0)))
                .await
                .unwrap_err()
                .code(),
            tonic::Code::FailedPrecondition
        );
        assert!(pay.refund_calls().is_empty());
    }

    /// (r) **On the wire: the service bearer — the one the customer-facing
    /// console backend holds — cannot refund.** `ListOwedBack` still takes it;
    /// `Refund` answers PERMISSION_DENIED to it and takes only the operator's.
    #[tokio::test]
    async fn the_service_bearer_is_refused_on_refund_and_the_operator_bearer_is_not() {
        let (state, pay) = refund_rig(CountingSink::creating());
        refused_for_a_refund(&state, &pay, "cs_wire");
        let server = crate::testing::TestServer::spawn_with_operator(
            state.clone(),
            "svc-bearer",
            "op-bearer",
        )
        .await;
        let channel = tonic::transport::Endpoint::from_shared(server.endpoint())
            .unwrap()
            .connect()
            .await
            .unwrap();
        let mut client = monetize_proto::signup_admin_client::SignupAdminClient::new(channel);
        let with = |bearer: &str, msg: pb::RefundSignupRequest| {
            let mut r = Request::new(msg);
            r.metadata_mut()
                .insert("authorization", format!("Bearer {bearer}").parse().unwrap());
            r
        };

        let mut list = Request::new(pb::ListOwedBackRequest {});
        list.metadata_mut()
            .insert("authorization", "Bearer svc-bearer".parse().unwrap());
        assert_eq!(
            client
                .list_owed_back(list)
                .await
                .unwrap()
                .into_inner()
                .total,
            1,
            "the service bearer still reads the queue"
        );

        let denied = client
            .refund(with("svc-bearer", refund_req("cs_wire", 0)))
            .await
            .unwrap_err();
        assert_eq!(denied.code(), tonic::Code::PermissionDenied, "{denied:?}");
        let stranger = client
            .refund(with("nobody", refund_req("cs_wire", 0)))
            .await
            .unwrap_err();
        assert_eq!(
            stranger.code(),
            tonic::Code::Unauthenticated,
            "{stranger:?}"
        );
        assert!(pay.refund_calls().is_empty());

        let done = client
            .refund(with("op-bearer", refund_req("cs_wire", 0)))
            .await
            .unwrap()
            .into_inner();
        assert_eq!(done.state(), pb::RefundState::Done);
        assert_eq!(pay.refund_calls().len(), 1);
        server.stop().await;
    }
}

#[cfg(test)]
mod site_tests {
    use super::site_refusal;

    /// ★ **A site's signup returns to that site** (owner 2026-10-11: two sites, one product,
    /// one box): a success or cancel page on another host — another site, or a look-alike — is
    /// refused by name; on the site's own https origin it passes.
    #[test]
    fn a_sites_signup_pages_are_on_that_site() {
        let site = "test2.gunnar.rs";
        assert_eq!(
            site_refusal(
                site,
                "https://test2.gunnar.rs/welcome?session={session}",
                "https://test2.gunnar.rs/signup"
            ),
            None
        );
        assert_eq!(site_refusal(site, "", ""), None, "the vendor's own pages");
        // WWW-CANON (owner 2026-10-30): the site is www.<site>; its console asks from that origin.
        assert_eq!(
            site_refusal(
                site,
                "https://www.test2.gunnar.rs/welcome?session={session}",
                "https://www.test2.gunnar.rs/signup"
            ),
            None,
            "the site's www origin is the site"
        );
        for (ok, cancel) in [
            ("https://www.gunnar.rs/welcome", ""),
            ("https://www.test2.gunnar.rs.evil.example/welcome", ""),
            ("http://www.test2.gunnar.rs/welcome", ""),
            ("https://gunnar.rs/welcome", ""),
            ("https://test2.gunnar.rs.evil.example/welcome", ""),
            ("http://test2.gunnar.rs/welcome", ""),
            ("https://test2.gunnar.rs/w", "https://gunnar.rs/signup"),
        ] {
            let e = site_refusal(site, ok, cancel).expect("another site's page");
            assert!(e.contains(site), "{e}");
        }
    }
}

#[cfg(test)]
mod estate_signup_tests {
    //! ★ **A signup makes its account on the estate it CAME FROM** (ONE box, two sites of
    //! gunnar, owner 2026-10-11): the caller's own bearer ([`crate::auth::CallerEstate`]) for
    //! an account at the shop, the account its money went through for a paid one — never the
    //! product's home estate by default.

    use std::sync::atomic::AtomicU64;
    use std::sync::{Arc, Mutex};

    use monetize_pay::signup::{NameVerdict, PaidSignup, SignupError, SignupOutcome, SignupSink};
    use monetize_proto::signup_server::Signup as _;

    use super::*;

    const TEST2: &str = "test2-gunnar-rs";

    /// Says on which estate each account was asked for and each name checked.
    #[derive(Default)]
    struct Sited {
        paid: Mutex<Vec<(String, Option<String>)>>,
        named: Mutex<Vec<(String, Option<String>)>>,
        queue_first: Mutex<bool>,
    }

    impl SignupSink for Sited {
        fn paid(&self, s: &PaidSignup) -> Result<SignupOutcome, SignupError> {
            self.paid_on(s, None)
        }
        fn paid_on(
            &self,
            s: &PaidSignup,
            estate: Option<&str>,
        ) -> Result<SignupOutcome, SignupError> {
            self.paid
                .lock()
                .unwrap()
                .push((s.username.clone(), estate.map(str::to_owned)));
            if std::mem::take(&mut *self.queue_first.lock().unwrap()) {
                return Err(SignupError::Unavailable(format!(
                    "{}the estate's main makes it",
                    crate::signup_pull::QUEUED
                )));
            }
            Ok(SignupOutcome::Created {
                namespace: s.username.clone(),
                username: s.username.clone(),
            })
        }
        fn name_verdict(&self, username: &str) -> Result<NameVerdict, SignupError> {
            self.name_verdict_on("", username, None)
        }
        fn name_verdict_on(
            &self,
            _: &str,
            username: &str,
            estate: Option<&str>,
        ) -> Result<NameVerdict, SignupError> {
            self.named
                .lock()
                .unwrap()
                .push((username.to_owned(), estate.map(str::to_owned)));
            Ok(NameVerdict::Free)
        }
    }

    fn state(reg: crate::registry::Registry, sink: Arc<Sited>) -> Arc<AppState> {
        let mut s = AppState::in_memory(reg);
        s.signup_sink = sink;
        let mut plans = crate::signup::tests::plans();
        plans.insert(
            "gunnar/account".into(),
            crate::config::SignupPlan {
                amount_minor: 0,
                currency: monetize_pay::Currency::Sek,
                cap_bytes: 0,
                period_days: 0,
            },
        );
        s.signup_plans = plans.into();
        let tick = Arc::new(AtomicU64::new(1_788_436_800_000));
        s.clock = Box::new(move || tick.load(std::sync::atomic::Ordering::SeqCst));
        Arc::new(s)
    }

    fn from_test2<T>(body: T) -> Request<T> {
        let mut req = Request::new(body);
        req.extensions_mut()
            .insert(crate::auth::CallerEstate(TEST2.into()));
        req
    }

    /// An account at the shop asked for from test2's console is made on test2 — at once,
    /// and again when it was queued and the poll settles it later (the estate is kept with
    /// the record); its name is checked on test2.
    #[tokio::test]
    async fn an_account_from_an_estates_console_is_made_on_that_estate() {
        let sink = Arc::new(Sited::default());
        *sink.queue_first.lock().unwrap() = true;
        let s = state(crate::registry::Registry::new(), sink.clone());
        let req = pb::StartSignupRequest {
            username: "nina".into(),
            product: "gunnar".into(),
            plan: "gunnar/account".into(),
            email: "nina@example.com".into(),
            success_url: "https://test2.gunnar.rs/welcome?session={session}".into(),
            ..Default::default()
        };
        let out = SignupService(s.clone())
            .start(from_test2(req))
            .await
            .expect("a queued account is started")
            .into_inner();
        assert_eq!(
            sink.named.lock().unwrap().clone(),
            vec![("nina".to_string(), Some(TEST2.to_string()))],
            "the name is checked on test2"
        );
        assert_eq!(
            sink.paid.lock().unwrap().clone(),
            vec![("nina".to_string(), Some(TEST2.to_string()))],
            "asked on test2"
        );
        let rec = s
            .signups
            .get(crate::signup::ACCOUNT_VENDOR, &out.session)
            .unwrap()
            .expect("kept pending");
        assert_eq!(
            rec.estate.as_deref(),
            Some(TEST2),
            "the record keeps where it began"
        );
        crate::signup::settle(&s, &rec.signup);
        assert_eq!(
            sink.paid.lock().unwrap().last().cloned(),
            Some(("nina".to_string(), Some(TEST2.to_string()))),
            "the later settle asks test2 again, never the home"
        );

        let checked = SignupService(s.clone())
            .check_name(from_test2(pb::CheckNameRequest {
                username: "olle".into(),
                product: "gunnar".into(),
            }))
            .await
            .unwrap()
            .into_inner();
        assert!(checked.free);
        assert_eq!(
            sink.named.lock().unwrap().last().cloned(),
            Some(("olle".to_string(), Some(TEST2.to_string()))),
            "CheckName asks test2"
        );
    }

    /// ★ ST-11: **a site's signup asks ITS OWN estate whether the room is there** (STINKY
    /// 2026-10-11): a priced plan started from test2's console asks the capacity of test2's
    /// main (the brand-new tenant `@test2-gunnar-rs/<name>` routes there), never gunnar.rs's;
    /// the home site still asks the brand-new-tenant question with no name.
    #[tokio::test]
    async fn a_sites_signup_asks_the_room_of_that_sites_own_estate() {
        let product = Arc::new(monetize::testing::MockProduct::gunnar());
        product.absorbs_on_hand();
        let site = |vendor: &str, site: &str| crate::config::EstateConfig {
            product: "gunnar".into(),
            vendor: vendor.into(),
            site: site.into(),
            ..Default::default()
        };
        let reg = crate::registry::Registry::new()
            .sells("gunnar", monetize::testing::MockPay::new())
            .shared_product(product.clone())
            .home("gunnar", "gunnar-rs")
            .estate("gunnar-rs", site("mockpay", "gunnar.rs"))
            .estate(TEST2, site("mockpay", "test2.gunnar.rs"));
        let s = state(reg, Arc::new(Sited::default()));
        let ask = |name: &str, host: &str| pb::StartSignupRequest {
            username: name.into(),
            product: "gunnar".into(),
            plan: crate::signup::tests::PLAN.into(),
            email: format!("{name}@example.invalid"),
            success_url: format!("https://{host}/welcome?session={{session}}"),
            cancel_url: format!("https://{host}/signup"),
            ..Default::default()
        };
        let _ = SignupService(s.clone())
            .start(from_test2(ask("nina", "test2.gunnar.rs")))
            .await;
        assert_eq!(
            product.absorb_tenants().last().map(String::as_str),
            Some("@test2-gunnar-rs/nina"),
            "test2's own main is asked: {:?}",
            product.absorb_tenants()
        );
        let mut home = Request::new(ask("olle", "gunnar.rs"));
        home.extensions_mut()
            .insert(crate::auth::CallerEstate("gunnar-rs".into()));
        let _ = SignupService(s.clone()).start(home).await;
        assert_eq!(
            product.absorb_tenants().last().map(String::as_str),
            Some(""),
            "the home asks the brand-new-tenant question: {:?}",
            product.absorb_tenants()
        );
    }

    /// ★ ST-6: **one address, one account PER SITE** (owner 2026-10-11): an address with an
    /// account on gunnar.rs signs up on test2.gunnar.rs (no account exists there), and is
    /// refused a second account on the site where it already has one — never told "sign in"
    /// on a site it has no account on.
    #[tokio::test]
    async fn an_address_with_an_account_on_one_site_signs_up_on_the_other() {
        let sink = Arc::new(Sited::default());
        let s = state(crate::registry::Registry::new(), sink.clone());
        let ask = |name: &str| pb::StartSignupRequest {
            username: name.into(),
            product: "gunnar".into(),
            plan: "gunnar/account".into(),
            email: "Nina@Example.invalid".into(),
            success_url: "https://test2.gunnar.rs/welcome?session={session}".into(),
            ..Default::default()
        };
        SignupService(s.clone())
            .start(Request::new(ask("nina")))
            .await
            .expect("an account on the home site");
        SignupService(s.clone())
            .start(from_test2(ask("nina2")))
            .await
            .expect("the same address on test2: no account there yet");
        let again = SignupService(s.clone())
            .start(from_test2(ask("nina3")))
            .await
            .expect_err("test2 already has its account");
        assert_eq!(again.message(), crate::signup::words::EMAIL_HAS_ACCOUNT);
        let home = SignupService(s.clone())
            .start(Request::new(ask("nina4")))
            .await
            .expect_err("the home already has its account");
        assert_eq!(home.message(), crate::signup::words::EMAIL_HAS_ACCOUNT);
    }

    /// A paid signup's webhook names no caller: the account its money went through
    /// (`[estates.<estate>] vendor`) names the estate it is made on.
    #[test]
    fn a_paid_signup_is_made_on_the_estate_whose_account_took_the_money() {
        let sink = Arc::new(Sited::default());
        let reg = crate::registry::Registry::new().estate(
            TEST2,
            crate::config::EstateConfig {
                product: "gunnar".into(),
                vendor: "mockpay".into(),
                ..Default::default()
            },
        );
        let s = state(reg, sink.clone());
        crate::signup::settle(&s, &crate::signup::tests::a_signup("cs_t2", "bob"));
        assert_eq!(
            sink.paid.lock().unwrap().clone(),
            vec![("bob".to_string(), Some(TEST2.to_string()))]
        );
        // A vendor no estate bills through: the product's home, as before.
        let home = Arc::new(Sited::default());
        let s = state(crate::registry::Registry::new(), home.clone());
        crate::signup::settle(&s, &crate::signup::tests::a_signup("cs_home", "bob"));
        assert_eq!(
            home.paid.lock().unwrap().clone(),
            vec![("bob".to_string(), None)]
        );
    }
}

#[cfg(test)]
mod card_check_tests {
    //! ★ **A free account only after a card check, one per card per site** (owner
    //! 2026-10-15): the vendor checks a card with nothing charged; the account is made when
    //! the welcome page asks `Signup.Status` and the vendor says the card is checked; a card
    //! that already has a free account on the site is refused in plain words; paid plans are
    //! untouched.

    use std::sync::atomic::AtomicU64;
    use std::sync::{Arc, Mutex};

    use monetize_pay::signup::{NameVerdict, PaidSignup, SignupError, SignupOutcome, SignupSink};
    use monetize_proto::signup_server::Signup as _;

    use super::*;
    use crate::testing::CallbackPay;

    const HOME: &str = "gunnar-rs";
    const TEST2: &str = "test2-gunnar-rs";

    /// Makes every account it is asked for, and says which.
    #[derive(Default)]
    struct Made(Mutex<Vec<(String, Option<String>)>>);

    impl SignupSink for Made {
        fn paid(&self, s: &PaidSignup) -> Result<SignupOutcome, SignupError> {
            self.paid_on(s, None)
        }
        fn paid_on(
            &self,
            s: &PaidSignup,
            estate: Option<&str>,
        ) -> Result<SignupOutcome, SignupError> {
            self.0
                .lock()
                .unwrap()
                .push((s.username.clone(), estate.map(str::to_owned)));
            Ok(SignupOutcome::Created {
                namespace: s.username.clone(),
                username: s.username.clone(),
            })
        }
        fn name_verdict(&self, _: &str) -> Result<NameVerdict, SignupError> {
            Ok(NameVerdict::Free)
        }
    }

    struct World {
        s: Arc<AppState>,
        pay: CallbackPay,
        sink: Arc<Made>,
    }

    fn world() -> World {
        let pay = CallbackPay::with_checkout("whsec", "https://pay.example/c/");
        let site = |site: &str| crate::config::EstateConfig {
            product: "gunnar".into(),
            vendor: "mockpay".into(),
            site: site.into(),
            ..Default::default()
        };
        let reg = crate::registry::Registry::new()
            .sells("gunnar", pay.clone())
            .home("gunnar", HOME)
            .estate(HOME, site("gunnar.rs"))
            .estate(TEST2, site("test2.gunnar.rs"));
        let sink = Arc::new(Made::default());
        let mut s = AppState::in_memory(reg);
        s.signup_sink = sink.clone();
        let mut plans = crate::signup::tests::plans();
        plans.insert(
            "gunnar/account".into(),
            crate::config::SignupPlan {
                amount_minor: 0,
                currency: monetize_pay::Currency::Sek,
                cap_bytes: 0,
                period_days: 0,
            },
        );
        s.signup_plans = plans.into();
        let tick = Arc::new(AtomicU64::new(1_788_436_800_000));
        s.clock = Box::new(move || tick.load(std::sync::atomic::Ordering::SeqCst));
        World {
            s: Arc::new(s),
            pay,
            sink,
        }
    }

    fn on<T>(estate: &str, body: T) -> Request<T> {
        let mut req = Request::new(body);
        req.extensions_mut()
            .insert(crate::auth::CallerEstate(estate.into()));
        req
    }

    fn host(estate: &str) -> &'static str {
        if estate == TEST2 {
            "test2.gunnar.rs"
        } else {
            "gunnar.rs"
        }
    }

    fn free(name: &str, estate: &str) -> pb::StartSignupRequest {
        pb::StartSignupRequest {
            username: name.into(),
            product: "gunnar".into(),
            plan: "gunnar/account".into(),
            vendor: "mockpay".into(),
            email: format!("{name}@example.com"),
            success_url: format!("https://{}/welcome?session={{session}}", host(estate)),
            cancel_url: format!("https://{}/signup", host(estate)),
            ..Default::default()
        }
    }

    impl World {
        async fn start(&self, name: &str, estate: &str) -> Result<pb::StartSignupResponse, Status> {
            SignupService(self.s.clone())
                .start(on(estate, free(name, estate)))
                .await
                .map(Response::into_inner)
        }
        async fn status(&self, session: &str, estate: &str) -> pb::SignupStatusResponse {
            SignupService(self.s.clone())
                .status(on(
                    estate,
                    pb::SignupStatusRequest {
                        vendor: "mockpay".into(),
                        session: session.into(),
                    },
                ))
                .await
                .expect("status answers")
                .into_inner()
        }
        /// Start a free account, check `card` at the vendor, and read the welcome page's poll.
        async fn sign_up_with(
            &self,
            name: &str,
            estate: &str,
            card: &str,
        ) -> pb::SignupStatusResponse {
            let page = self
                .start(name, estate)
                .await
                .expect("a card check is minted");
            self.pay.check_card(&page.session, card);
            self.status(&page.session, estate).await
        }
        fn made(&self) -> Vec<String> {
            self.sink
                .0
                .lock()
                .unwrap()
                .iter()
                .map(|(n, _)| n.clone())
                .collect()
        }
    }

    use pb::signup_status_response::State;

    /// The free account is NOT made at Start: the buyer is sent to the vendor's card check
    /// (nothing charged), and the account is made once the vendor says the card is checked —
    /// with the card's fingerprint on its record, never more of the card.
    #[tokio::test]
    async fn a_free_account_is_made_only_after_the_card_check() {
        let w = world();

The file goes on; the console shows all of it.