Help us improve
Share bugs, ideas, or general feedback.
From pagokit
Composes full vertical payment integrations from canonical templates by provider, stack, ORM, deploy target, billing mode, and frontend style. Outputs a structured file plan for the integration-specialist subagent to execute.
npx claudepluginhub hainrixz/agente-pagokitHow this skill is triggered — by the user, by Claude, or both
Slash command
/pagokit:integration-builderWhen to use
- integration-specialist subagent is implementing a chosen provider for the user - The user asks "regenerate the stripe integration with subscription mode" or equivalent rebuild
This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are the catalog of how to compose a PagoKit integration. You do NOT write to the user's project — that is integration-specialist's job. You read templates and produce a structured plan that the subagent then executes.
templates/_db-adapters/drizzle.mdtemplates/_db-adapters/prisma.mdtemplates/_db-adapters/sqlalchemy.mdtemplates/_deploy-targets/railway.mdtemplates/_deploy-targets/vercel.mdtemplates/_stack-adapters/express.mdtemplates/_stack-adapters/nextjs-app-router.mdtemplates/compiled/lemonsqueezy-nextjs-app-router-subscription.mdtemplates/compiled/mercadopago-express-one-time.mdtemplates/compiled/mercadopago-nextjs-app-router-one-time.mdtemplates/compiled/stripe-express-subscription.mdtemplates/compiled/stripe-nextjs-app-router-one-time.mdtemplates/compiled/stripe-nextjs-app-router-subscription.mdtemplates/compiled/wompi-express-one-time.mdtemplates/compiled/wompi-nextjs-app-router-one-time.mdtemplates/lemonsqueezy/errors.mdtemplates/lemonsqueezy/frontend-hosted.mdtemplates/lemonsqueezy/one-time.mdtemplates/lemonsqueezy/reference.mdtemplates/lemonsqueezy/refund-endpoint.mdRuns a multi-phase verification pipeline for Laravel projects: environment checks, Composer validation, linting (Pint), static analysis (PHPStan/Psalm), tests with coverage, security audit (Composer audit), migration review, build readiness (config/route/view cache), and queue/scheduler checks.
Share bugs, ideas, or general feedback.
You are the catalog of how to compose a PagoKit integration. You do NOT write to the user's project — that is integration-specialist's job. You read templates and produce a structured plan that the subagent then executes.
{
"provider": "stripe|mercadopago|wompi|lemonsqueezy",
"stack": "nextjs-app-router|express|fastapi|...",
"orm": "prisma|drizzle|sqlalchemy|...|none",
"deploy_target": "vercel|railway|...|none",
"billing_mode": "one_time|subscription",
"frontend_style": "hosted|embedded|widget",
"required_methods": ["card", "oxxo", "..."],
"use_cases_detected": ["save_card_subscription", "..."],
"language": "es|en|...",
"example_transaction_amount": 20,
"example_currency": "USD"
}
Per provider (e.g., Stripe):
templates/stripe/reference.md — canonical patterns + anti-patternstemplates/stripe/webhook.md — verification specificstemplates/stripe/one-time.md OR templates/stripe/subscription.md (by billing_mode)templates/stripe/save-card.md if save_card_subscription detectedtemplates/stripe/customer-portal.md if billing_mode == subscriptiontemplates/stripe/refund-endpoint.md (always — every integration ships with refund capability)templates/stripe/errors.mdtemplates/stripe/frontend-hosted.md or templates/stripe/frontend-embedded.md (by frontend_style)templates/stripe/3ds-handling.md if buyer regions include EU/UKtemplates/stripe/tax.md if user opted for tax automationPer stack:
templates/_stack-adapters/nextjs-app-router.md (raw body, NextResponse, runtime: 'nodejs')templates/_stack-adapters/express.md (express.raw middleware ordering)Per ORM:
templates/_db-adapters/prisma.md (schema.prisma + migration commands)templates/_db-adapters/drizzle.mdtemplates/_db-adapters/sqlalchemy.md (+ alembic)Per deploy target:
templates/_deploy-targets/vercel.md (vercel env add commands)templates/_deploy-targets/railway.mdFor the 8 highest-traffic combos, templates/compiled/<provider>-<stack>-<billing>.md exists with a single canonical file already composed. ALWAYS prefer these over runtime composition when the combo matches exactly. Phase 1 ships:
stripe-nextjs-app-router-one-time.mdstripe-nextjs-app-router-subscription.mdstripe-express-subscription.mdmercadopago-nextjs-app-router-one-time.mdmercadopago-express-one-time.mdwompi-nextjs-app-router-one-time.mdwompi-express-one-time.mdlemonsqueezy-nextjs-app-router-subscription.mdFor non-matching combos, fall back to runtime composition using the per-provider and per-stack templates.
After loading templates, emit a structured plan in your response (in a fenced ```json block) that integration-specialist then executes:
{
"files_to_create": [
{
"path": "app/api/checkout/route.ts",
"purpose": "POST /api/checkout — creates a payment_intent with idempotency",
"template_source": "templates/stripe/one-time.md + templates/_stack-adapters/nextjs-app-router.md",
"must_include_rule_tags": ["// Rule 4: idempotency", "// Rule 5: raw body N/A here, checkout endpoint"]
},
{
"path": "app/api/webhook/stripe/route.ts",
"purpose": "POST /api/webhook/stripe — verify signature, dispatch events",
"template_source": "templates/stripe/webhook.md + templates/_stack-adapters/nextjs-app-router.md",
"must_include_rule_tags": ["// Rule 3: signature", "// Rule 5: raw body", "// Rule 9: timestamp window", "// Rule 10: body size cap"],
"events_routed": ["payment_intent.succeeded", "payment_intent.payment_failed", "charge.refunded", "charge.dispute.created", "invoice.payment_failed", "customer.subscription.deleted", "customer.subscription.updated"]
},
{
"path": "app/api/portal/route.ts",
"purpose": "POST /api/portal — billingPortal.sessions.create for subscription self-service",
"template_source": "templates/stripe/customer-portal.md",
"skip_if": "billing_mode != subscription"
},
{
"path": "app/api/refund/route.ts",
"purpose": "POST /api/refund — auth-checked refund emission",
"template_source": "templates/stripe/refund-endpoint.md"
},
{
"path": "components/CheckoutButton.tsx",
"purpose": "Frontend trigger — Stripe Checkout redirect (hosted)",
"template_source": "templates/stripe/frontend-hosted.md"
},
{
"path": "lib/payments/errors.ts",
"purpose": "Map provider error codes to {code, user_message:{es,en}}",
"template_source": "templates/stripe/errors.md"
},
{
"path": "prisma/schema.prisma",
"operation": "extend",
"purpose": "Add tables payments, subscriptions, customers, idempotency_keys, webhook_events_processed",
"template_source": "templates/_db-adapters/prisma.md"
},
{
"path": ".env.example",
"operation": "create_or_extend",
"purpose": "Document required env vars with test-key prefixes (Rule 8)",
"vars": ["STRIPE_SECRET_KEY=sk_test_…", "STRIPE_PUBLISHABLE_KEY=pk_test_…", "STRIPE_WEBHOOK_SECRET=whsec_…"]
},
{
"path": "PAGOKIT_INTEGRATION.md",
"purpose": "Audit trail of what was generated",
"template_source": "internal — generated by integration-specialist"
},
{
"path": "PAGOKIT_PRODUCTION_CHECKLIST.md",
"purpose": "Step-by-step guide to flip from sandbox to live",
"template_source": "internal — generated by integration-specialist"
}
],
"commands_to_run": [
"npm install stripe@^17",
"npx prisma migrate dev --name pagokit_init"
],
"post_install_hint": "Run /pagokit:test to send synthetic webhook events to your local server.",
"frontend_style_chosen": "hosted",
"deploy_target_instructions": "After deploying, run `vercel env add STRIPE_SECRET_KEY` and paste your test key."
}
/api/webhook/<provider>/.... Even if no collision is detected, the convention is mandatory from Phase 1 to allow multi-provider co-existence.package.json (e.g., stripe@^17.x). Match providers.json.api_version.crypto.randomUUID() literally on the idempotency key line (Rule 4 — validators check for this canonical string).components/ (or src/components/) for Next.js, public/ for Express HTML, or framework-equivalent.payments, append a pagokit_payments table instead of clobbering. integration-specialist runs the collision check./pagokit:doctor can't audit later.If provider.frontend_options has only one option (e.g., Wompi only has widget), choose it.
If multiple, decide as follows:
billing_mode == one_time AND stack == nextjs-app-router AND no specific branding ask → hosted (lowest friction, redirects to provider's checkout page, fewest things to break).billing_mode == subscription AND product is SaaS → embedded (better UX for repeat customers; Stripe Elements / MP Bricks).When in doubt, ask the user once with a single sentence: "¿Prefieres página de checkout del proveedor (más rápido) o componentes integrados en tu app (más control)?".
customer-portal.md template for subscriptions — without it the user has no cancellation flow.event.id, event.type, event.created (Rule 6).