← ClaudeAtlas

ekx-stripelisted

Fiat payments with Stripe — Checkout Sessions, Payment Element, subscriptions and price IDs, webhook signature verification, and the test-vs-live key split. Use when accepting a card payment, building a booking or subscription flow, handling a webhook, reconciling a payment to a database row, or debugging a webhook signature failure.
Ekinoxis-evm/claude-skills · ★ 0 · AI & Automation · score 60
Install: claude install-skill Ekinoxis-evm/claude-skills
# Stripe Our fiat rail everywhere except Colombia. (Onchain payments are USDC — see [`../ekx-circle-usdc/SKILL.md`](../ekx-circle-usdc/SKILL.md); for Colombia see [`../ekx-mercadopago/SKILL.md`](../ekx-mercadopago/SKILL.md).) Authoritative: the **`stripe` MCP server** plus the bundled `stripe-best-practices` skill. Docs: https://docs.stripe.com --- ## Environment ```bash NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY= # pk_test_… / pk_live_… STRIPE_SECRET_KEY= # SECRET sk_test_… / sk_live_… STRIPE_WEBHOOK_SECRET= # SECRET whsec_… STRIPE_PREMIUM_PRICE_ID= # price_… ``` The webhook secret is **per endpoint**. Local (Stripe CLI), preview and production each have their own. Using production's secret against a CLI-forwarded event fails signature verification — the most common Stripe bug we hit. --- ## Checkout Session — the default Prefer a hosted Checkout Session over a custom Payment Element unless the design genuinely requires an embedded form. It handles SCA, wallets, tax, and receipts for free. ```ts // app/api/checkout/route.ts import Stripe from "stripe"; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!); export async function POST(req: Request) { const { bookingId } = await req.json(); const session = await stripe.checkout.sessions.create({ mode: "payment", line_items: [{ price: process.env.STRIPE_PREMIUM_PRICE_ID!, quantity: 1 }], success_url: `${process.env.NEXT_PUBLIC_URL}/booking/success?session