apple
Emulated Sign in with Apple / Apple OIDC for local development and testing. Use when the user needs to test Apple sign-in locally, emulate Apple OIDC…
Emulated Stripe API for local development and testing. Use when the user needs to process payments locally, test checkout flows, create customers, manage products and prices, handle payment intents, work with webhooks, or use the Stripe SDK without hitting real Stripe servers.
$ npx -y skills add vercel-labs/emulate --skill stripe --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/stripeContext preview
The summary Claude sees to decide when to auto-load this skill.
Emulated Stripe API for local development and testing. Use when the user needs to process payments locally, test checkout flows, create customers, manage products and prices, handle payment intents, work with webhooks, or use the Stripe SDK without hitting real Stripe servers.
name: stripe description: Emulated Stripe API for local development and testing. Use when the user needs to process payments locally, test checkout flows, create customers, manage products and prices, handle payment intents, work with webhooks, or use the Stripe SDK without hitting real Stripe servers. Triggers include "Stripe API", "emulate Stripe", "test payments locally", "checkout flow", "payment intent", "Stripe webhook", "Stripe SDK", "STRIPE_API_KEY", or any task requiring a local Stripe API. allowed-tools: Bash(npx emulate:*), Bash(curl:*)
Fully stateful Stripe API emulation. Customers, products, prices, checkout sessions, payment intents, charges, and payment methods persist in memory. Webhooks fire on state changes. The hosted checkout UI lets you complete payments in the browser.
No real payments are processed. Every Stripe SDK call hits the emulator and produces realistic responses.
# Stripe only npx emulate --service stripe # Default port (when run alone) # http://localhost:4000
Or programmatically:
import { createEmulator } from 'emulate'
const stripe = await createEmulator({ service: 'stripe', port: 4000 })
// stripe.url === 'http://localhost:4000'The Stripe Node.js SDK does not read an environment variable for the base URL. You must pass it when constructing the client:
import Stripe from 'stripe'
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2024-12-18.acacia',
host: 'localhost',
port: 4000,
protocol: 'http',
})When using `@emulators/adapter-next`, the emulator runs inside your Next.js app at `/emulate/stripe`. The SDK needs to point at `localhost` with a proxy route to forward `/v1/*` calls to `/emulate/stripe/v1/*`:
// next.config.ts
import { withEmulate } from '@emulators/adapter-next'
export default withEmulate({
env: {
STRIPE_SECRET_KEY: 'sk_test_emulated',
},
})// lib/stripe.ts
import Stripe from 'stripe'
const port = process.env.PORT ?? '3000'
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2024-12-18.acacia',
host: 'localhost',
port: parseInt(port, 10),
protocol: 'http',
})// app/emulate/[...path]/route.ts
import { createEmulateHandler } from '@emulators/adapter-next'
import * as stripe from '@emulators/stripe'
export const { GET, POST, PUT, PATCH, DELETE } = createEmulateHandler({
services: {
stripe: {
emulator: stripe,
seed: {
products: [
{ id: 'prod_widget', name: 'Widget', description: 'A useful widget' },
],
prices: [
{ id: 'price_widget', product_name: 'Widget', currency: 'usd', unit_amount: 1000 },
],
webhooks: [
{
url: `http://localhost:${process.env.PORT ?? '3000'}/api/webhooks/stripe`,
events: ['*'],
},
],
},
},
},
})// app/v1/[...path]/route.ts (proxy for Stripe SDK)
const STRIPE_URL = `http://localhost:${process.env.PORT ?? '3000'}/emulate/stripe`
async function handler(req: Request, ctx: { params: Promise<{ path: string[] }> }) {
const { path } = await ctx.params
const url = new URL(req.url)
const target = `${STRIPE_URL}/v1/${path.join('/')}${url.search}`
const res = await fetch(target, {
method: req.method,
headers: req.headers,
body: req.body,
duplex: 'half',
} as any)
return new Response(res.body, {
status: res.status,
statusText: res.statusText,
headers: res.headers,
})
}
export { handler as GET, handler as POST, handler as PUT, handler as PATCH, handler as DELETE }curl http://localhost:4000/v1/customers \ -H "Authorization: Bearer sk_test_emulated"
Seed data is optional. All entities support an optional `id` field for deterministic IDs that survive server restarts.
stripe:
customers:
- id: cus_demo
email: demo@example.com
name: Demo User
products:
- id: prod_tshirt
name: T-Shirt
description: A comfortable tee
prices:
- id: price_tshirt
product_name: T-Shirt
currency: usd
unit_amount: 2500
webhooks:
- url: http://localhost:3000/api/webhooks/stripe
events: ['*']
secret: whsec_testThe `product_name` field in prices links to the product by name. Use `events: ['*']` to receive all webhook events, or specify individual event types.
# Create customer curl -X POST http://localhost:4000/v1/customers \ -d "email=user@example.com" -d "name=Jane Doe" # Retrieve customer curl http://localhost:4000/v1/customers/cus_xxx # Update customer curl -X POST http://localhost:4000/v1/customers/cus_xxx \ -d "name=Updated Name" # Delete customer curl -X DELETE http://localhost:4000/v1/customers/cus_xxx # List customers curl http://localhost:4000/v1/customers
# Create product curl -X POST http://localhost:4000/v1/products \ -d "name=Widget" -d "description=A useful widget" # Retrieve product curl http://localhost:4000/v1/products/prod_xxx # List products curl "http://localhost:4000/v1/products?active=true"
# Create price curl -X POST http://localhost:4000/v1/prices \ -d "product=prod_xxx" -d "currency=usd" -d "unit_amount=1000" # Retrieve price curl http://localhost:4000/v1/prices/price_xxx # List prices curl "http://localhost:4000/v1/prices?active=true"
# Create checkout session
curl -X POST http://localhost:4000/v1/checkout/sessions \
-d "mode=payment" \
-d "line_items[0][price]=price_xxx" \
-d "line_items[0][quantity]=1" \
-d "success_url=http://localhost:3000/success?session_id={CHECKOUT_SESSION_ID}" \
-d "cancel_url=http://localhostLocal drop-in replacement services for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation. Not mocks.
Repo: vercel-labs/emulate
Emulated Sign in with Apple / Apple OIDC for local development and testing. Use when the user needs to test Apple sign-in locally, emulate Apple OIDC…
Emulated AWS cloud services (S3, SQS, IAM, STS) for local development and testing. Use when the user needs to interact with AWS API endpoints locally, test S3…
Local drop-in API emulator for Vercel, GitHub, Google, Slack, Apple, Microsoft, AWS, Clerk, Linear, Twilio, and other developer APIs. Use when the user needs…
Emulated GitHub REST API for local development and testing. Use when the user needs to interact with GitHub API endpoints locally, test GitHub integrations,…
Emulated Google OAuth 2.0, OpenID Connect, Gmail, Calendar, and Drive for local development and testing. Use when the user needs to test Google sign-in…
Emulated Linear GraphQL API for local development and testing. Use when the user needs to test Linear integrations locally, emulate Linear issues, comments,…