Skip to content
Back to skills

Stripe Standard

ASecurity

Scaffolds a Stripe **Standard account** integration (no Connect) in Supabase + React/Flutter projects. Generates US-STRIPE-CHECKOUT with up to 12 UCs covering the 4 canonical billing modalities (single subscription, tiered subscriptions, metered billing, one-shot checkout) in the project's spec backend, backend Edge Functions + SQL migrations with RLS, frontend templates with Payment Element/Sheet + Apple/Google Pay + Express Checkout, Stitch designs (if VEG configured), reuses the stripe-saf...

  • 16 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added June 1, 2026
developmentpythongobashsqlreactvueexpressfastapitestingapi

Works with

  • terminal
  • cli
  • api
  • mcp

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 20 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add EmbedBuild/specbox-engine --skill stripe-standard --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Stripe Standard?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Stripe Standard
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/embedbuild-stripe-standard/badge)](https://www.skillsdirectory.com/skills/embedbuild-stripe-standard)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: stripe-standard
description: >
  Scaffolds a Stripe **Standard account** integration (no Connect) in
  Supabase + React/Flutter projects. Generates US-STRIPE-CHECKOUT with up to
  12 UCs covering the 4 canonical billing modalities (single subscription,
  tiered subscriptions, metered billing, one-shot checkout) in the project's
  spec backend, backend Edge Functions + SQL migrations with RLS, frontend
  templates with Payment Element/Sheet + Apple/Google Pay + Express Checkout,
  Stitch designs (if VEG configured), reuses the stripe-safety-guard hook,
  events catalog, and wires the official Stripe MCP. Use when the user says
  "stripe standard", "stripe sin connect", "subscriptions saas",
  "checkout one-shot", "billing saas", "monta pagos saas", "monta pagos
  e-commerce". v1 scope: Supabase only, the 4 modalities are flags so the
  user opts in.
context: direct
allowed-tools: Read, Grep, Glob, Bash(*), Write, Edit, mcp__specbox-engine__*, mcp__stitch__*
---

# /stripe-standard — Stripe billing scaffolder for normal (non-Connect) accounts

The companion of `/stripe-connect` for the 80% of Stripe consumers that don't
need a marketplace: SaaS subscriptions, e-commerce one-shot, B2B invoicing,
metered billing, donations, paywalls. Generates the same kind of bundle
(spec + Edge Functions + SQL + RLS + frontend templates + Stitch designs +
safety hook) but tuned for **a single Stripe account** with **a single
webhook endpoint** and zero Connect machinery.

## When to use this vs /stripe-connect

| Use case | Skill |
|----------|-------|
| You sell access to your own product (SaaS, app, content) | **`/stripe-standard`** |
| You run an e-commerce shop selling your own goods | **`/stripe-standard`** |
| You have one-shot purchases (donations, lifetime deals) | **`/stripe-standard`** |
| You need metered billing (usage-based pricing) | **`/stripe-standard`** |
| You operate a marketplace where other sellers receive money | `/stripe-connect` |
| You take a cut from third-party transactions | `/stripe-connect` |

If unsure, default to `/stripe-standard`. Adding Connect later is a refactor
but supported by the same `setup_webhook_endpoints(account_mode='connect')`
of the underlying MCP — no data loss.

## Uso

```
/stripe-standard
```

Sin argumentos por defecto activa **las 4 modalidades**. Para acotar:

```
/stripe-standard --modes=single_sub,one_shot
/stripe-standard --modes=metered
```

Modalidades válidas:

| Flag | Qué genera |
|------|-----------|
| `single_sub` | 1 sola suscripción mensual o anual fija (caso SaaS clásico) |
| `tiered_sub` | Múltiples planes con upgrade/downgrade y proration |
| `metered` | Facturación por uso (usage records + reporting) |
| `one_shot` | Pagos únicos sin recurrencia (e-commerce, donaciones, lifetime) |

---

## Alcance v1 (opinionado)

| Dimensión | Decisión |
|-----------|----------|
| Backend | **Supabase únicamente** (Neon/Firestore/FastAPI → v2) |
| Frontend | React 19 o Flutter 3.38+ |
| Account type | **Stripe Standard** (la cuenta normal — sin Connect) |
| Charge model | Direct charges sobre la propia cuenta |
| Subscriptions | 4 modalidades disponibles, opt-in vía flags |
| Checkout UX | Embedded-only: Payment Element (React) + Payment Sheet (Flutter). Hosted Checkout queda como fallback opcional vía `stripe-create-checkout-session` |
| Apple/Google Pay | Default on |
| Customer Portal | **Sí** (en Standard sí podemos abrir el portal — el customer vive en nuestra propia cuenta) |
| Webhook endpoints | **1 solo** (vs 2 de Connect) |
| MCP underneath | `specbox-stripe-mcp` v0.2 con `account_mode='standard'` |

---

## Paso 0 — Preflight: detectar entorno del proyecto

### 0.1 Validar que estamos en un proyecto SpecBox onboardeado

```bash
test -f .claude/settings.local.json || test -f .claude/settings.json || {
  echo "ERROR: Este directorio no parece un proyecto SpecBox. Ejecuta 'onboard_project' primero."
  exit 1
}
```

### 0.2 Detectar stack frontend

```bash
# React
if [ -f package.json ] && grep -q '"react"' package.json; then STACK="react"; fi

# Flutter
if [ -f pubspec.yaml ] && grep -q "flutter:" pubspec.yaml; then
  if [ -d ios ] || [ -d android ]; then STACK="flutter-mobile"; else STACK="flutter-web"; fi
fi
```

Si no detecta ni React ni Flutter → abortar: *"v1 solo soporta React o Flutter. Otros stacks no están cubiertos."*

### 0.3 Detectar backend Supabase (obligatorio en v1)

```bash
test -d supabase && test -f supabase/config.toml || {
  echo "ERROR: v1 de /stripe-standard requiere Supabase CLI inicializado."
  echo "Ejecuta 'supabase init' antes de continuar, o espera a v2 para otros backends."
  exit 0
}
```

### 0.4 Detectar spec backend activo (Trello / Plane / FreeForm)

Leer `.claude/settings.local.json`:
- `trello.boardId` → Trello
- `plane.defaultProject` → Plane
- Sin ninguno → FreeForm en `doc/tracking/`

### 0.5 Detectar presencia de VEG

```bash
test -d doc/veg && test -f doc/design/brand-kit.md && VEG_PRESENT=true || VEG_PRESENT=false
```

### 0.6 Parsear flag `--modes`

```bash
MODES_INPUT="${1:---modes=single_sub,tiered_sub,metered,one_shot}"
MODES=$(echo "$MODES_INPUT" | sed 's/--modes=//')

# Validate every mode is in the supported set.
VALID="single_sub tiered_sub metered one_shot"
for m in $(echo "$MODES" | tr ',' ' '); do
  echo "$VALID" | grep -qw "$m" || {
    echo "ERROR: modalidad '$m' no soportada. Válidas: single_sub, tiered_sub, metered, one_shot."
    exit 1
  }
done
```

### 0.7 Detectar specbox-stripe-mcp instalado

```bash
# Either as a globally registered MCP or as a workspace package.
test -d packages/specbox-stripe-mcp || command -v specbox-stripe-mcp >/dev/null || {
  echo "WARN: specbox-stripe-mcp no detectado. La skill puede continuar pero los tools de"
  echo "      setup-as-code (verify_account_setup, setup_webhook_endpoints, etc.) no estarán"
  echo "      disponibles para el proyecto. Instálalo con: pip install specbox-stripe-mcp"
}
```

---

## Paso 1 — Confirmar plan con el usuario

Antes de tocar el filesystem, presentar:

```
📋 Stripe Standard scaffolder — plan de generación

  Stack detectado:    {STACK}
  Spec backend:       {Trello|Plane|FreeForm}
  VEG presente:       {sí|no}
  Modalidades:        {modes activadas}

  Va a crear:
  - 1 US-STRIPE-CHECKOUT + N UCs en {spec_backend}
  - Edge Functions Supabase ({lista funciones})
  - Migraciones SQL ({lista migraciones})
  - Templates frontend en {src/billing|lib/billing}/
  - {N} pantallas Stitch (si VEG activo)
  - 1 PRD en doc/prd/stripe_standard_prd.md

  Va a NO crear:
  - Cuenta Stripe (debes tenerla ya, en test mode)
  - Secrets en .env (los pegas tú; la skill solo guía con el placeholder)

¿Continuar? (s/n)
```

Si responde `n` → exit 0 sin tocar nada.

---

## Paso 2 — Crear US-STRIPE-CHECKOUT + UCs en spec backend (AC-01..AC-06)

El catálogo canónico de los 12 UCs vive en `templates/uc-catalog.json`. La skill
filtra por `MODES` activadas y llama `import_spec` con el subset.

```python
# Pseudocódigo de la skill — la implementación real es Bash + jq.
catalog = json.load(open(".claude/skills/stripe-standard/templates/uc-catalog.json"))
selected_ucs = [
    uc for uc in catalog["ucs"]
    if any(m in uc["modes"] for m in MODES.split(","))
    or "always" in uc["modes"]   # webhook handler, customer creation, paywall siempre van
]

spec = {
    "user_stories": [{
        "us_id": "US-STRIPE-CHECKOUT",
        "name": "Integración de pagos Stripe (cuenta Standard, modalidades activadas: " + MODES + ")",
        "description": "...",
        "hours": sum(u["hours"] for u in selected_ucs),
        "use_cases": selected_ucs,
    }]
}

import_spec(board_id=board_id, spec=spec)
```

### 2.1 Re-run idempotente (AC-05)

Si `list_us(board_id)` ya devuelve un US-STRIPE-CHECKOUT:

```
⚠ Ya existe US-STRIPE-CHECKOUT en este board.
  ¿Qué quieres hacer?
  (1) skip — no cambiar nada en el spec backend
  (2) update — añadir las UCs nuevas (las modalidades que faltan)
  (3) replace — borrar la US existente y crearla desde cero (destructivo)
```

Por defecto la skill elige (1) si no hay TTY interactivo.

### 2.2 Fallback si el spec backend está offline

Try/catch sobre `import_spec`. Si falla:

```
⚠ Spec backend {Trello|Plane} no responde. Guardando como FreeForm local en doc/tracking/.
```

Llamar `set_auth_token(backend_type="freeform", root_path="doc/tracking")` y reintentar.

---

## Paso 3 — Generar PRD adjunto (AC-07)

Escribir `doc/prd/stripe_standard_prd.md` desde
`templates/docs/stripe_standard_prd.md.template` con las secciones por modalidad
activada. Cada modalidad incluye:

- **Caso de uso** (resumen de 2-3 frases)
- **Flujo principal** (numerado)
- **Casos de error** (lista)
- **Eventos Stripe relevantes** (subset del events catalog)
- **Frontend components afectados**

Si `--modes=single_sub,one_shot`, el PRD solo tiene esas 2 secciones.

---

## Paso 4 — Escribir templates backend Supabase (AC-07/UC-007)

Copiar y parametrizar desde `.claude/skills/stripe-standard/templates/supabase/`:

### 4.1 Edge Functions

Funciones generadas según modalidades activadas:

| Function | Modalidad |
|----------|-----------|
| `stripe-create-customer/index.ts` | always |
| `stripe-webhook/index.ts` | always (1 solo endpoint, sin separar platform/connect) |
| `stripe-create-subscription/index.ts` | si activas `single_sub`, `tiered_sub` o `metered` |
| `stripe-create-payment-intent/index.ts` | si activas `one_shot` |
| `stripe-create-checkout-session/index.ts` | siempre — fallback hosted (con `ui_mode='embedded'` por defecto) |
| `stripe-create-portal-session/index.ts` | always (Customer Portal) |
| `stripe-report-usage/index.ts` | si activas `metered` |

Placeholders: `{project_name}`, `{frontend_url}`, `{currency}` (default `eur`).

### 4.2 Migraciones SQL

3 migraciones copiadas a `supabase/migrations/` con timestamp prefix:

| Migration | Contenido |
|-----------|-----------|
| `NNN_stripe_customers.sql` | tabla `stripe_customers (user_id FK auth.users, stripe_customer_id UNIQUE)` |
| `NNN_stripe_subscriptions.sql` | tabla `stripe_subscriptions (customer_id FK, stripe_subscription_id, price_id, status, current_period_end, cancel_at_period_end, metadata JSONB)` |
| `NNN_stripe_processed_events.sql` | tabla `stripe_processed_events (event_id UNIQUE PK, type, processed_at)` |

RLS policies en una 4ª migración: usuarios solo ven sus propias rows; service_role
lee/escribe todo desde Edge Functions.

Todas con `CREATE ... IF NOT EXISTS` para idempotencia.

---

## Paso 5 — Escribir templates frontend (UC-009 / UC-010)

### 5.1 React (`STACK=react`)

Copiar desde `templates/react/` a `src/billing/` del proyecto:

- `stripe-provider.tsx` — `<Elements>` con `appearance` parametrizada por brand-kit
- `subscription-form.tsx` — `<PaymentElement>` + `<ExpressCheckoutElement>` para single/tiered subs
- `checkout-embedded.tsx` — `loadStripe + initEmbeddedCheckout` para one-shot
- `paywall-gate.tsx` — wrapper que bloquea acceso si no hay sub activa
- `billing-portal-link.tsx` — botón que abre el Customer Portal vía Edge Function
- `usage-meter.tsx` — solo si `metered` activado (componente para mostrar uso)
- `use-billing.ts` — hook centralizado de estado de subs/payments

Mergear dependencias en `package.json`:
```json
{
  "@stripe/stripe-js": "^3",
  "@stripe/react-stripe-js": "^2"
}
```

### 5.2 Flutter (`STACK=flutter-mobile` o `flutter-web`)

Copiar desde `templates/flutter/` a `lib/billing/`:

- `stripe_service.dart` — init + Apple Pay + Google Pay
- `subscription_screen.dart` — PaymentSheet para single/tiered subs
- `one_shot_checkout_sheet.dart` — PaymentSheet para compras únicas
- `paywall_gate.dart` — widget gate que bloquea si no hay sub
- `billing_portal_button.dart` — abre el portal en navegador (`url_launcher`)
- `usage_meter_card.dart` — solo si `metered` activado
- `billing_controller.dart` — estado centralizado

Mergear dependencias en `pubspec.yaml`:
```yaml
flutter_stripe: ^11.0.0
url_launcher: ^6.0.0
```

---

## Paso 6 — Stitch designs (UC-011)

Si `VEG_PRESENT=true`, generar pantallas vía `mcp__stitch__generate_screen_from_text`.

Pantallas según modalidades activadas:

| Pantalla | Modalidades requeridas |
|----------|------------------------|
| `paywall.html` | siempre |
| `billing-portal.html` | siempre |
| `checkout-success.html` | siempre |
| `checkout-cancel.html` | siempre |
| `subscription-management.html` | si hay alguna sub modalidad activa |
| `metered-usage-dashboard.html` | si `metered` activado |

Guardar en `doc/design/stripe_standard/`. Registrar prompts en
`doc/design/stripe_standard/stripe_standard_stitch_prompts.md`.

Si `VEG_PRESENT=false` → saltar este paso silenciosamente.

---

## Paso 7 — Reusar hook stripe-safety-guard (UC-012)

El hook ya existe en `.claude/hooks/stripe-safety-guard.mjs` (vino con
`/stripe-connect`). Detecta los 5 anti-patterns en `src/billing/`,
`lib/billing/` y `supabase/functions/stripe-*`:

1. `sk_live_*` hardcoded
2. Webhook handler sin verificación de firma
3. Webhook handler sin idempotencia (`stripe_processed_events`)
4. `redirectToCheckout` o `ui_mode='hosted'`
5. Payment Links

No tocamos el hook. Solo verificamos que está activado en `.claude/settings.json`:

```bash
grep -q "stripe-safety-guard" .claude/settings.json || {
  echo "WARN: stripe-safety-guard hook no activo. Activa con /compliance --fix."
}
```

---

## Paso 8 — Wire Stripe MCP oficial (idéntico a /stripe-connect Paso 8)

Mergear en `.claude/settings.local.json`:

```json
{
  "mcpServers": {
    "stripe": {
      "command": "npx",
      "args": ["-y", "@stripe/mcp", "--api-key", "${STRIPE_API_KEY}"],
      "env": { "STRIPE_API_KEY": "${STRIPE_SECRET_KEY}" }
    }
  }
}
```

Esto da acceso al **MCP oficial** de Stripe (runtime de negocio: customers,
charges, refunds, etc.) además del `specbox-stripe-mcp` (setup-as-code).

---

## Paso 9 — Inyectar secrets en Supabase Edge Functions (UC-013)

Standard solo necesita **3 secrets** (vs los 4 de Connect):

| Secret | Origen |
|--------|--------|
| `STRIPE_SECRET_KEY` | tu cuenta Stripe (test mode) |
| `STRIPE_WEBHOOK_SECRET` | salida de `stripe listen --forward-to ...` o el dashboard |
| `STRIPE_PUBLISHABLE_KEY` | tu cuenta Stripe |

NO existe `STRIPE_WEBHOOK_SECRET_CONNECT` aquí — Standard solo tiene 1 endpoint.

### 9.1 Detectar specbox-supabase MCP

Intentar `mcp__specbox-supabase__list_edge_secrets_tool({supabase_pat: "...", project_ref: "..."})`.

- Si responde → Paso 9.2 (auto-inyección).
- Si no responde / no está registrado → Paso 9.3 (manual, escribe doc/PENDING_SECRETS.md).

### 9.2 Inyección automática

```
mcp__specbox-supabase__set_edge_secret_tool({
  supabase_pat: env.SUPABASE_PAT,
  project_ref: env.SUPABASE_PROJECT_REF,
  secrets: {
    STRIPE_SECRET_KEY:       env.STRIPE_SECRET_KEY,
    STRIPE_WEBHOOK_SECRET:   env.STRIPE_WEBHOOK_SECRET,
    STRIPE_PUBLISHABLE_KEY:  env.STRIPE_PUBLISHABLE_KEY,
  },
  confirm: true,
  reason: "/stripe-standard initial setup"
})
```

Verificar con `list_edge_secrets({expected_names: [...]})`.

### 9.3 Fallback manual

Si MCP ausente, escribir `doc/PENDING_SECRETS.md`:

```markdown
# Secrets pendientes

specbox-supabase MCP no detectado. Copia estos 3 secrets manualmente en:
https://supabase.com/dashboard/project/{project_ref}/settings/functions

  STRIPE_SECRET_KEY        = <from .env>
  STRIPE_WEBHOOK_SECRET    = <from `stripe listen` output>
  STRIPE_PUBLISHABLE_KEY   = <from .env>
```

Engram observation: registrar éxito/fallo del paso sin valores de secrets.

---

## Paso 10 — Tests + acceptance evidence (UC-015)

Generar `tests/acceptance/` con un test por modalidad activada:

| Test | Modalidad |
|------|-----------|
| `subscribe_single_sub.spec.ts` (React) o `_test.dart` (Flutter) | `single_sub` |
| `switch_tier.spec.ts` | `tiered_sub` |
| `metered_billing.spec.ts` | `metered` |
| `one_shot_checkout.spec.ts` | `one_shot` |

Cada test cubre el happy path + 1-2 error paths (decline, 3DS challenge).

---

## Paso 11 — Próximos pasos (mostrar al usuario)

```
✓ /stripe-standard completado en {duration}.

Siguientes pasos manuales:
  1. {Si Paso 9 fue manual} Copiar los 3 secrets en Supabase dashboard.
  2. Ejecutar `supabase db push` para aplicar las migraciones.
  3. Ejecutar `stripe listen --forward-to <tu-edge-url>/stripe-webhook` en
     terminal separado para testing local.
  4. (Opcional, no bloqueante) Activar Stripe Tax si vas a vender en EU.
  5. /implement US-STRIPE-CHECKOUT — ejecutará los UCs en orden.

📋 Catálogo de eventos relevantes en doc/stripe-standard-events.md.
```

---

## Anexo A — Comparativa Standard vs Connect

| Dimensión | Standard | Connect |
|-----------|----------|---------|
| Webhook endpoints | 1 (platform-scope) | 2 (platform + connect) |
| Tablas SQL | 3 (customers, subs, events) | 4 (riders/sponsorships también) |
| Edge Functions | 5-7 según modos | 5 fijas |
| Customer Portal | sí (built-in) | requiere onboarding del seller |
| `application_fee_percent` | N/A | dinámico por seller |
| Activación dashboard | nada | hay que activar Connect explícitamente |

---

## Errores frecuentes (FAQ rápido)

**Q**: Mi proyecto ya tiene `/stripe-connect`. ¿Puedo añadir `/stripe-standard`?

**A**: Técnicamente sí pero **no recomendado**. El cliente Stripe abstracto no
distingue Standard de Connect en runtime. Si ya tienes Connect Express, los
flujos de Standard van por la cuenta plataforma — funciona pero crea confusión.
Mejor escoge una de las dos modalidades.

**Q**: ¿Puedo migrar de `/stripe-connect` a `/stripe-standard`?

**A**: La parte de spec/templates es regenerar la skill. La parte de Stripe es
otra cosa: si ya cobraste con Direct charges en Connect, no se mueve a la
plataforma. Customers + subscriptions seguirán viviendo en las cuentas
conectadas. Es una migración pesada — pregunta antes de intentarla.

**Q**: `metered` vs `tiered_sub`, ¿cuál escojo?

**A**: `tiered_sub` = N planes con precio fijo, el usuario puede subir/bajar.
`metered` = un plan + se factura por uso (ej: $0.001 por API call). Son
ortogonales: puedes activar las dos.

---

## Referencias

- Plan original: `doc/plans/stripe_standard_plan.md` (auto-generado por `/plan US-STRIPE-STANDARD`)
- MCP underlying: `packages/specbox-stripe-mcp/` v0.2 (`account_mode='standard'`)
- Skill hermana: `/stripe-connect`
- Tracking: SpecBox board `ff-bc73b5d69f91`, US-STRIPE-STANDARD

Files in this skill

  • SKILL.md18.1 KB
  • templates/docs/decision-tree.md4.1 KB
  • templates/docs/getting-started.md5.7 KB
  • templates/docs/stripe_standard_prd.md.template5.5 KB
  • templates/flutter/billing_controller.dart3.5 KB
  • templates/flutter/billing_portal_button.dart2.2 KB
  • templates/flutter/one_shot_checkout_sheet.dart2.1 KB
  • templates/flutter/paywall_gate.dart1.8 KB
  • templates/flutter/pubspec.fragment.yaml267 B
  • templates/flutter/stripe_service.dart1.2 KB
  • templates/flutter/subscription_screen.dart3.9 KB
  • templates/flutter/usage_meter_card.dart3.3 KB
  • templates/react/billing-portal-link.tsx2.3 KB
  • templates/react/checkout-embedded.tsx3.2 KB
  • templates/react/package.json.fragment.json313 B
  • templates/react/paywall-gate.tsx2.2 KB
  • templates/react/stripe-provider.tsx2.3 KB
  • templates/react/subscription-form.tsx5 KB
  • templates/react/usage-meter.tsx2.9 KB
  • templates/react/use-billing.ts3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.