Document merchant profiles (multi-business / multi-provider) in docs

Add a Merchant profiles concept section to index.html: the default profile, per-profile branding and payment accounts, product routing, and the Pro/Patron multi-business capability. Wire it into the Concepts nav across all pages and the index TOC. Conforms to the brand contract (design-checker: compliant).
This commit is contained in:
Keysat
2026-06-18 12:19:13 -05:00
parent 5df25df375
commit f99d4a4998
8 changed files with 37 additions and 0 deletions
+1
View File
@@ -27,6 +27,7 @@
<div class="glabel">Concepts</div> <div class="glabel">Concepts</div>
<a href="index.html#architecture">Architecture</a> <a href="index.html#architecture">Architecture</a>
<a href="index.html#products-policies">Products &amp; policies</a> <a href="index.html#products-policies">Products &amp; policies</a>
<a href="index.html#merchant-profiles">Merchant profiles</a>
<a href="index.html#discounts">Discount codes</a> <a href="index.html#discounts">Discount codes</a>
<a href="index.html#revocation">Revocation strategy</a> <a href="index.html#revocation">Revocation strategy</a>
</div> </div>
+30
View File
@@ -27,6 +27,7 @@
<div class="glabel">Concepts</div> <div class="glabel">Concepts</div>
<a href="index.html#architecture">Architecture</a> <a href="index.html#architecture">Architecture</a>
<a href="index.html#products-policies">Products &amp; policies</a> <a href="index.html#products-policies">Products &amp; policies</a>
<a href="index.html#merchant-profiles">Merchant profiles</a>
<a href="index.html#discounts">Discount codes</a> <a href="index.html#discounts">Discount codes</a>
<a href="index.html#revocation">Revocation strategy</a> <a href="index.html#revocation">Revocation strategy</a>
</div> </div>
@@ -110,6 +111,34 @@
<p>A product can have <strong>one policy or many</strong>. Multi-tier ladders (think Basic / Pro / Max) are first-class: when a product has two or more public policies, the buy page renders a tier picker and the buyer chooses before paying. The displayed tier is selected from a <code>?policy=&lt;slug&gt;</code> URL hint, then the <code>highlighted</code> ("most popular") policy if any, then the cheapest. Tier ordering on the picker is operator-controlled via drag-and-drop in the admin UI (or <code>tier_rank</code> in the API).</p> <p>A product can have <strong>one policy or many</strong>. Multi-tier ladders (think Basic / Pro / Max) are first-class: when a product has two or more public policies, the buy page renders a tier picker and the buyer chooses before paying. The displayed tier is selected from a <code>?policy=&lt;slug&gt;</code> URL hint, then the <code>highlighted</code> ("most popular") policy if any, then the cheapest. Tier ordering on the picker is operator-controlled via drag-and-drop in the admin UI (or <code>tier_rank</code> in the API).</p>
<p>You can also attach <strong>private policies</strong> for manual issuance, e.g. a longer-duration "Lifetime" comp for conferences, a richer-entitlement "Internal" tier for support cases. Private policies don&rsquo;t appear on the buy page; the admin API issues them directly.</p> <p>You can also attach <strong>private policies</strong> for manual issuance, e.g. a longer-duration "Lifetime" comp for conferences, a richer-entitlement "Internal" tier for support cases. Private policies don&rsquo;t appear on the buy page; the admin API issues them directly.</p>
<h2 id="merchant-profiles">Merchant profiles</h2>
<p>By default a Keysat instance sells for one business. On first boot it creates a single <strong>default merchant profile</strong> from your operator name, and every product you create attaches to it. If you only ever run one business, you can ignore profiles entirely: everything works against the default.</p>
<p>On the <strong>Pro</strong> and <strong>Patron</strong> tiers you can run more than one business from the same instance. A <strong>merchant profile</strong> is one business identity, and it owns:</p>
<ul>
<li><strong>Branding</strong>: display name, brand color, and the support URL / email shown on that business&rsquo;s buy pages.</li>
<li><strong>Payment accounts</strong>: its own BTCPay and Zaprite connections (one, the other, or both). Payments for that business settle to that business&rsquo;s wallet, never a shared one.</li>
<li><strong>A post-purchase redirect</strong>: where buyers land after paying (with <code>{invoice_id}</code> substituted), or the Keysat receipt page if you leave it blank.</li>
<li><strong>Products</strong>: each product attaches to exactly one profile. Buyers see that profile&rsquo;s brand on the buy page, and their payment routes to that profile&rsquo;s providers.</li>
</ul>
<p>So one operator, on one Start9, can sell Recaps under the Recaps brand (settling to the Recaps wallet) and Aurora under the Aurora brand (settling to the Aurora wallet) side by side, with separate checkout branding and separate books. Keysat is still not a shared SaaS: two independent sellers each run their own box. What profiles add is multiple businesses under one operator.</p>
<table class="t">
<thead><tr><th>Concept</th><th>What it is</th></tr></thead>
<tbody>
<tr><td>Default profile</td><td>Auto-created on first boot, exactly one per instance. A product with no explicit profile resolves to it.</td></tr>
<tr><td>Payment provider</td><td>One configured BTCPay or Zaprite account, attached to a profile. A profile can have more than one.</td></tr>
<tr><td>Rail</td><td>A buyer-facing payment method: Lightning, on-chain, or card. BTCPay serves Lightning and on-chain; Zaprite adds card.</td></tr>
<tr><td>Rail preference</td><td>A tie-breaker for when a profile has two providers that both serve the same rail: it sets which one wins.</td></tr>
</tbody>
</table>
<p>Manage all of this in the admin UI under <strong>Merchant profiles</strong>: create a profile, set its branding, connect BTCPay or Zaprite to it, mark one as the default, and attach products. Connecting a provider to a profile uses the same one-click authorize handshake as <a href="install.html#connect-btcpay">Connect BTCPay</a> in setup, just scoped to the profile you start it from.</p>
<div class="callout">
<i data-lucide="store"></i>
<p><strong>Running one business? Skip this.</strong> The default profile is created for you and every product uses it automatically. Merchant profiles only start to matter when you want a second brand or a second wallet on the same instance, which is a Pro and Patron capability.</p>
</div>
<h2 id="discounts">Discount codes</h2> <h2 id="discounts">Discount codes</h2>
<p>Four kinds:</p> <p>Four kinds:</p>
@@ -182,6 +211,7 @@
<div class="label">On this page</div> <div class="label">On this page</div>
<a href="#architecture">Architecture</a> <a href="#architecture">Architecture</a>
<a href="#products-policies">Products &amp; policies</a> <a href="#products-policies">Products &amp; policies</a>
<a href="#merchant-profiles">Merchant profiles</a>
<a href="#discounts">Discount codes</a> <a href="#discounts">Discount codes</a>
<a href="#revocation">Revocation strategy</a> <a href="#revocation">Revocation strategy</a>
<a href="#operator-tiers">Operator tiers</a> <a href="#operator-tiers">Operator tiers</a>
+1
View File
@@ -27,6 +27,7 @@
<div class="glabel">Concepts</div> <div class="glabel">Concepts</div>
<a href="index.html#architecture">Architecture</a> <a href="index.html#architecture">Architecture</a>
<a href="index.html#products-policies">Products &amp; policies</a> <a href="index.html#products-policies">Products &amp; policies</a>
<a href="index.html#merchant-profiles">Merchant profiles</a>
<a href="index.html#discounts">Discount codes</a> <a href="index.html#discounts">Discount codes</a>
<a href="index.html#revocation">Revocation strategy</a> <a href="index.html#revocation">Revocation strategy</a>
</div> </div>
+1
View File
@@ -27,6 +27,7 @@
<div class="glabel">Concepts</div> <div class="glabel">Concepts</div>
<a href="index.html#architecture">Architecture</a> <a href="index.html#architecture">Architecture</a>
<a href="index.html#products-policies">Products &amp; policies</a> <a href="index.html#products-policies">Products &amp; policies</a>
<a href="index.html#merchant-profiles">Merchant profiles</a>
<a href="index.html#discounts">Discount codes</a> <a href="index.html#discounts">Discount codes</a>
<a href="index.html#revocation">Revocation strategy</a> <a href="index.html#revocation">Revocation strategy</a>
</div> </div>
+1
View File
@@ -27,6 +27,7 @@
<div class="glabel">Concepts</div> <div class="glabel">Concepts</div>
<a href="index.html#architecture">Architecture</a> <a href="index.html#architecture">Architecture</a>
<a href="index.html#products-policies">Products &amp; policies</a> <a href="index.html#products-policies">Products &amp; policies</a>
<a href="index.html#merchant-profiles">Merchant profiles</a>
<a href="index.html#discounts">Discount codes</a> <a href="index.html#discounts">Discount codes</a>
<a href="index.html#revocation">Revocation strategy</a> <a href="index.html#revocation">Revocation strategy</a>
</div> </div>
+1
View File
@@ -27,6 +27,7 @@
<div class="glabel">Concepts</div> <div class="glabel">Concepts</div>
<a href="index.html#architecture">Architecture</a> <a href="index.html#architecture">Architecture</a>
<a href="index.html#products-policies">Products &amp; policies</a> <a href="index.html#products-policies">Products &amp; policies</a>
<a href="index.html#merchant-profiles">Merchant profiles</a>
<a href="index.html#discounts">Discount codes</a> <a href="index.html#discounts">Discount codes</a>
<a href="index.html#revocation">Revocation strategy</a> <a href="index.html#revocation">Revocation strategy</a>
</div> </div>
+1
View File
@@ -90,6 +90,7 @@
<div class="glabel">Concepts</div> <div class="glabel">Concepts</div>
<a href="index.html#architecture">Architecture</a> <a href="index.html#architecture">Architecture</a>
<a href="index.html#products-policies">Products &amp; policies</a> <a href="index.html#products-policies">Products &amp; policies</a>
<a href="index.html#merchant-profiles">Merchant profiles</a>
<a href="index.html#discounts">Discount codes</a> <a href="index.html#discounts">Discount codes</a>
<a href="index.html#revocation">Revocation strategy</a> <a href="index.html#revocation">Revocation strategy</a>
</div> </div>
+1
View File
@@ -27,6 +27,7 @@
<div class="glabel">Concepts</div> <div class="glabel">Concepts</div>
<a href="index.html#architecture">Architecture</a> <a href="index.html#architecture">Architecture</a>
<a href="index.html#products-policies">Products &amp; policies</a> <a href="index.html#products-policies">Products &amp; policies</a>
<a href="index.html#merchant-profiles">Merchant profiles</a>
<a href="index.html#discounts">Discount codes</a> <a href="index.html#discounts">Discount codes</a>
<a href="index.html#revocation">Revocation strategy</a> <a href="index.html#revocation">Revocation strategy</a>
</div> </div>