Brak wyników.

Tryb reseller (B2B-z-B2B-z-B2B)

Buduj SaaS / PaaS w którym Twoi klienci mogą sprzedawać Twoją apkę dalej swoim klientom końcowym. WolfieAuth dostarcza prymitywy + SDK.

Tryb reseller — budowa B2B-z-B2B przy użyciu WolfieAuth

TL;DR: każda aplikacja zarejestrowana w WolfieAuth może opt-in włączyć tryb reseller. Po włączeniu admin owner-orga apki może oznaczać organizacje-klientów jako resellery — dostają seat-pack, dedykowany signup-link (i opcjonalnie własną domenę), oraz panel do prowizjonowania własnych end-customer-orgów. Trzy-poziomowa polityka fee dzieli przychód między platformę (Wolfie), owner-orga apki i resellera. SDK w każdym frameworku wystawiają isResellerOf(), useReseller(), drop-in komponenty + typowanego klienta API — własne admin UI Twojej apki ma potrzebne 5 linii kodu.

Hierarchia

                 WolfieAuth Platform (Wolfie)
                          │  Stripe Connect onboarding
                          │  + 5% platform-fee od reseller-subskrypcji
                    ┌──── Owner-org OidcClient-a ─────────┐
                    │       (Twoja apka, np. acme-cloud)  │
                    │                                     │
                    │   Sprzedaje seat-packi resellerom   │
                    │   (Stripe Connect na owner-orgu)    │
                    │                                     │
                    └──┬──────────────────────────────┬───┘
                       │                              │
                       ▼                              ▼
              Reseller-org A             Reseller-org B
              (Big Reseller Polska)      (inny partner)
                       │                              │
                       │  Rozdaje seaty                │
                       │  end-customer-om              │
                       │  (out-of-band invoicing —     │
                       │  wolfieauth nie pośredniczy   │
                       │  w transakcjach reseller→     │
                       │  klient)                      │
                       ▼                              ▼
              ┌─ Bob's Pizza GmbH       ┌─ Inny end-customer
              ├─ Tom's Café             └─ ...
              └─ Foo's Bar Sp. z o.o.

Trzech aktorów, trzy odpowiedzialności

AktorCo posiadaCo decyduje
Platforma (Wolfie)WolfieAuthDomyślny platform-fee BPS/flat dla wszystkich reseller-subskrypcji; per-app i per-resellerstwo override; emergency suspend
Owner-org apkiOidcClient (acme-cloud-product)Czy w ogóle włączać tryb reseller; które customer-orgi zostają resellerami; seat-limity; per-reseller fee; signup-tokeny; custom domeny
Reseller-orgSwoja seat-pack subskrypcja + child-orgiKtórych end-customerów provisionować (w limicie); kiedy ich suspendować; czy fakturować out-of-band

Trzy-poziomowa polityka fee

WolfieAuth rozwiązuje per-payment fee tą hierarchią (najściślejszy wygrywa):

  1. Per-resellerstwo override (AppReseller.platformFeeBpsOverride) — Wolfie umówił się ze konkretnym resellerem.
  2. Per-app override (OidcClient.platformResellerFeeBpsOverride) — Wolfie umówił się z owner-orgiem (np. Acme Cloud ma 7% zamiast 5%).
  3. Platform default (PlatformConfig.platformResellerFeeBps) — globalny default Wolfie, 500 bps (5%) z pudełka.

Owner-org-owe fee na seat-pack subskrypcji (cena którą reseller płaci za pakiet) siedzi osobno w OidcClient.resellerFeeBps / AppReseller.feeBps. Oba fee aplikuje się addytywnie — reseller płaci cenę seat-pack-a (= revenue owner-orga) + niewielki kawałek platform-fee który idzie do Wolfie.

Checklist setupu (admin owner-orga)

  1. Otwórz /admin/clients/<your-app-id> → zakładka Overview.
  2. Włącz toggle 🤝 Tryb reseller / Reseller mode. Zapisz.
  3. Pojawi się nowa zakładka Resellers.
  4. Ustaw default resellerFeeBps / resellerFeeFlatCents (lub zostaw 0 dla “darmowych seat-packów”).
  5. Klik + Dodaj resellera, wybierz customer-orgę z dropdown-a, ustaw seat-limit. Generuje się signup-token i pokazuje raz — skopiuj go.
  6. (Opcjonalnie) Ustaw custom domenę dla resellera (np. cloud.acme.com). Dodaj wskazany TXT record, klik ✓ Verify, gotowe.
  7. Przekaż signup-token (lub URL custom-domeny) resellerowi.

Co się zmienia dla end-customera resellera

User rejestrując się przez:

https://auth.wolfieguard.com/signup?client_id=acme-cloud-product&reseller_token=<token>

…lub przez verified custom domain:

https://cloud.acme.com/signup?client_id=acme-cloud-product

…dostaje świeży Organization row z parentId = <orgId-resellera>. Jego OIDC tokeny niosą:

  • wolfieauth_org_parentId = "<reseller-orgId>" (apki rozpoznają że ten end-customer jest “pod” resellerem)
  • wolfieauth_org_id = id nowo utworzonej child-orgi (jego własny scope danych)

Adminowie resellera logują się do admin UI owner-orga (Twojej apki — np. Acme Cloud admin panel zbudowany z SDK helpery poniżej). Ich tokeny niosą:

  • wolfieauth_reseller_apps[] = [{ client_id: "acme-cloud-product", org_id: "<reseller-orgId>", seat_limit: 100, seats_allocated: 17, status: "ACTIVE" }]

To jest mechanizm gating — Twoja apka czyta claim i pokazuje panel “Reseller portfolio”.

Wpięcie panelu w aplikacji — per SDK

React / Next.js

import { RequireResellerAdmin, ResellerChildrenTable, useReseller } from "@wolfieauth/sdk-react";

// Drop-in (działa od ręki):
<RequireResellerAdmin clientId="acme-cloud-product"
  fallback={<p>Strona dla reseller-adminów.</p>}>
  <ResellerChildrenTable clientId="acme-cloud-product" />
</RequireResellerAdmin>

// Albo własne UI z hook-a:
function MyResellerDashboard() {
  const { isReseller, resellership, children, billing,
          provisionChild, suspendChild } = useReseller("acme-cloud-product");
  if (!isReseller) return null;
  return <div>{resellership.seats_allocated}/{resellership.seat_limit} seats  </div>;
}

Hook oczekuje że Twoja apka wystawi proxy pod /api/wolfieauth/resellers/... które forwarduje do auth.wolfieguard.com/api/admin/resellers/... z OIDC bearer-em. SDK middleware (handle.ts w SvelteKit, middleware w Next.js) zwykle ma już ten wzorzec — sprawdź per-stack guide.

SvelteKit

// +page.server.ts
import { loadResellerContext } from "@wolfieauth/sdk-sveltekit/server";

export const load = async ({ locals, fetch }) => {
  const reseller = await loadResellerContext({
    claims: locals.session?.claims ?? null,
    clientId: "acme-cloud-product",
    fetch,
  });
  return { reseller };
};
<!-- +page.svelte -->
<script>
  let { data } = $props();
</script>

{#if data.reseller.isReseller}
  <h1>Twoi klienci ({data.reseller.children.length})</h1>
  {#each data.reseller.children as c}
    <div>{c.name}{c._count.members} userów</div>
  {/each}
{/if}

Laravel / PHP

use WolfieAuth\Sdk\Resellers\Resellers;

public function dashboard(Request $request)
{
    $claims = $request->attributes->get('wolfieauth')['claims'] ?? null;
    if (!Resellers::isResellerOf($claims, 'acme-cloud-product')) {
        abort(403);
    }
    $seats = Resellers::getResellerSeatStatus($claims, 'acme-cloud-product');
    return view('reseller.dashboard', compact('seats'));
}

W Blade:

@if(\WolfieAuth\Sdk\Resellers\Resellers::isResellerOf($wolfieauth['claims'], 'acme-cloud-product'))
  <a href="/reseller">Zarządzaj swoimi klientami</a>
@endif

Django / DRF

from wolfieauth.resellers import IsResellerAdmin, is_reseller_of, wolfieauth_reseller_admin

# DRF
class ResellerDashboard(APIView):
    permission_classes = [IsResellerAdmin("acme-cloud-product")]
    def get(self, request):
        ...

# Plain Django
@wolfieauth_reseller_admin("acme-cloud-product")
def reseller_dashboard(request):
    ...

Budowanie “PaaS-z-PaaS” przy użyciu WolfieAuth

Mając te prymitywy, szerszy wzorzec to: wszystko co budujesz na WolfieAuth może być multi-tier SaaS-em. Przykłady:

  • WolfieCloud (managed hosting): Wolfie prowadzi platformę; resellery to agencje pakujące hosting dla swoich klientów; end-customery to klienci agencji (każdy ma własną orgę z własną bazą, mailboxami itp.)
  • Branżowy CRM (np. CRM dla gabinetów dentystycznych): Wolfie prowadzi WolfieAuth; owner-org platformy sprzedaje “Dental Network” seat-pack dużym network operator-om; każdy network ma reseller-status pozwalający spawnować orgę per gabinet; staff każdego gabinetu loguje się przez branded subdomenę network-a.
  • White-label e-learning: Ten sam wzorzec — corporate trainers kupują seat-packi i rozdają dostęp swoim “kursantom” w osobnych org-ach.

Kombinacja:

  • per-OidcClient theme + reseller-scoped defaultChildTheme cascade,
  • per-org Stripe Connect dla owner-orga,
  • per-resellerstwo signup tokenów + opcjonalnie custom domeny,
  • gating przez claim-y w SDK,

oznacza że operator platformy nie musi pisać trzech warstw kodu żeby wspierać B2B-z-B2B-z-B2C — WolfieAuth ogarnie tożsamość, branding, fee, seaty i lifecycle. Twoja apka skupia się tylko na swoim produkcie.

Ograniczenia / caveats

  • Sub-resellery (3+ poziomy w głąb) są gated przez AppReseller.allowSubResellers i włącza je tylko SUPER_ADMIN platformy. Większość przypadków to płaska hierarchia: platforma → reseller → end-customer.
  • Każdy reseller-org potrzebuje własnego Stripe Connect konta jeśli chce fakturować swoich end-customerów przez WolfieAuth — ale transakcje reseller → end-customer są poza scope billingu WolfieAuth (reseller fakturuje swoich klientów sam, np. przez własne wolfiecrm). WolfieAuth tracking tylko seat-pack subskrypcję (reseller → owner-org).
  • KSeF dla reseller → end-customer jest odpowiedzialnością resellera — jego wolfiecrm albo zewnętrzna księgowość.

Ostatnia aktualizacja: