Salta al contenuto
Supastack
IT
Tema
AccediOttieni l'accesso a vita
Tutti gli articoli

Condividere autenticazione e 8 gateway di pagamento tra Next.js, Expo mobile e Tauri v2

Le due cuciture più dure del SaaS multipiattaforma: il callback di login via deep link su mobile e un unico entitlement per pagamenti web, RevenueCat IAP e checkout desktop. Come un monorepo risolve entrambe.

Noah Zixin Zhang3 min di lettura

Come si condividono auth e pagamenti tra Next.js, Expo e Tauri?

Dipende dalla capacità di mantenere un solo modello di identità e un solo archivio di entitlement. Il web usa sessioni con cookie HttpOnly; Expo salva un bearer token in expo-secure-store dopo il callback OAuth via deep link; Tauri riusa la sessione web dentro la sua webview — tutte validate dalla stessa istanza Better Auth. I pagamenti seguono la stessa regola: 8 gateway web e RevenueCat IAP mobile confluiscono in un ledger di webhook idempotente che scrive entitlement a livello di workspace letti da ogni superficie.

Le due cuciture dove il SaaS multipiattaforma si strappa

Chiedi a un team che ha saldato un'app mobile su un SaaS web dove fa davvero male — la risposta non è mai la UI. Sono identità e denaro: il flusso OAuth che ritorna pulito nel browser deve tornare nell'app via deep link, e il cliente che ha pagato sul web si aspetta il suo entitlement sul telefono all'istante.

I team di solito lo scoprono dopo aver rilasciato due mezze soluzioni: logica di cookie che fallisce in silenzio dentro WKWebView e un entitlement RevenueCat che litiga con l'abbonamento Stripe nel database web. La riparazione è architetturale — ed è due volte la stessa: un modello di identità, un archivio di entitlement.

Un'istanza Better Auth, tre trasporti di sessione

supastack mantiene un'unica configurazione Better Auth in @supastack/auth con punti d'ingresso per superficie. Le due app web (Next.js 16 e TanStack Start) usano sessioni con cookie HttpOnly SameSite=Lax — sicure contro CSRF di default e amichevoli con i Server Components. L'app Expo scambia il completamento dell'OAuth o del magic link alla fine del callback deep link con un bearer token, lo persiste in expo-secure-store (iOS Keychain / Android Keystore) e lo invia come header Authorization, validato dallo stesso middleware di auth.

La shell desktop di Tauri è una webview singola che punta all'app web, quindi eredita direttamente la sessione web — niente terzo flusso di auth da mantenere. La guida auth mobile e la guida ai deep link documentano il contratto di callback; la nostra guida al monorepo web + mobile mostra il codice client condiviso.

// packages/auth/src/client.ts — one client, two storages
import { createAuthClient } from "better-auth/react";
import { expoClient } from "@better-auth/expo/client";

export function createCrossPlatformAuthClient(baseURL: string, storage?: any) {
  return createAuthClient({
    baseURL,
    plugins: storage ? [expoClient({ scheme: "myapp", storage })] : [],
  });
}

// Web: cookie session.  Mobile: bearer token in SecureStore.
// Desktop: the web app's own session inside the Tauri webview.

Otto gateway di pagamento, un contratto

Ogni provider di pagamento web — Stripe, Lemon Squeezy, Polar, Creem, Dodo, Paddle, Whop e PayPal — si innesta nello stesso contratto @supastack/billing, e ogni webhook firmato atterra prima in un ledger webhook_event idempotente prima di poter toccare gli entitlement. I retry dei provider e le consegne fuori ordine diventano no-op innocui al confine del database, non ticket di supporto.

Gli acquisti in-app mobile entrano nello stesso ledger via RevenueCat: le ricevute degli store sono verificate lato server e gli entitlement scritti sul workspace, non sul dispositivo — chi paga su iOS è subito pagato anche su web e desktop. La guida RevenueCat copre il cablaggio App Store / Play; i webhook di billing idempotenti spiegano perché il ledger è il pezzo portante.

Il modello di entitlement che rende noiosa la sincronizzazione

Perché resta noioso: gli entitlement vivono sul workspace e vengono risolti lato server. Nessun client trattiene lo stato «pagato» — il web chiede alla sessione, il mobile all'API, il desktop all'app web — e tutti e tre ricevono la stessa risposta perché c'è un solo record che può rispondere.

Ripristino acquisti su un telefono nuovo, rinnovo Stripe sul web, una postazione Agency aggiunta nella dashboard — ciascuna è una scrittura nelle stesse righe di entitlement che ogni superficie legge alla prossima richiesta. Non c'è motore di sync da costruire perché non c'è nulla da sincronizzare.

SuperficieTrasporto sessionePercorso di pagamentoEntitlement letti da
Next.js 16 webCookie HttpOnlyUno qualsiasi degli 8 gateway → ledger webhookRighe entitlement Postgres condivise
TanStack Start webCookie HttpOnlyStessi adapter, stesso ledgerRighe entitlement Postgres condivise
Expo iOS / AndroidBearer token in expo-secure-storeRevenueCat IAP → ricevuta verificata serverStesse righe (via API tipizzata)
Tauri 2 desktopSessione web nella webviewCheckout web dentro la shellStesse righe (via app web)
Estensione MV3Chiave API workspace— (legge dati workspace)Stesse righe (via /api/v1)

Cosa non devi più costruire

Tradotto in serate di lavoro, questa è la differenza tra fondamenta e lista di feature: il ritorno di auth via deep link, la persistenza del token in SecureStore, otto integrazioni webhook a prova di replay, la verifica delle ricevute App Store e un modello di entitlement che non si contraddice mai tra dispositivi. Tutto consegnato, testato (693+ test senza credenziali) e documentato.

Il Full Bundle da $299 contiene tutte le superfici in un repo — postazioni e livelli agency nella pagina dei prezzi.

FAQ: condividere auth e pagamenti tra piattaforme

Le domande che i team fanno prima di impegnarsi sullo stack unificato:

  • Gli utenti mobile fanno login separato dal web?, No. Il flusso OAuth o magic link torna nell'app via deep link ed emette la stessa sessione; chi emette è la stessa istanza Better Auth, quindi web e mobile rispondono allo stesso modo su «chi sei».
  • E chi paga su iOS ma usa l'app web?, RevenueCat consegna l'acquisto lato server; l'entitlement è scritto nelle stesse righe di workspace che il web legge, e l'app web mostra «pagato» alla richiesta successiva.
  • Si può partire solo col web e aggiungere le app dopo?, Sì — auth e billing vivono nei package condivisi, quindi le app mobile e desktop li ereditano nel momento in cui attivi quelle superfici.
  • L'app Tauri ha bisogno di un checkout proprio?, No — la shell desktop riusa sessione e checkout dell'app web dentro la sua webview; non c'è una seconda superficie di pagamento da difendere.

Il tuo prossimo prodotto inizia qui.

Paga una volta. Continua a creare prodotti redditizi.