Stripe Handler

Handle Stripe payments, custom checkouts, and webhook fulfillment outside of standard plans/credits.

Installs: 0
Used in: 1 repos
Updated: 2d ago
$npx ai-builder add skill AayushBaniya2006/stripe-handler

Installs to .claude/skills/stripe-handler/

# Stripe Handler

Use this skill when you need to implement payment logic using Stripe, specifically for use cases that are **NOT** standard SaaS subscription plans or standard Credit packages (which are handled by `plans-handler` and `credits-handler` respectively).

## When to use
- Implementing "Buy One-time Product" flows (e.g., Courses, Digital Goods).
- Creating custom "Service" payments.
- Handling `checkout.session.completed` for custom metadata.
- Customizing `src/app/api/webhooks/stripe/route.ts` for non-standard events.
- Offloading heavy webhook processing to background tasks (via Inngest).

## Process

### 1. Identify Payment Type
Before writing code, determine the nature of the payment:
- **Is it a Subscription Plan?** -> Use `plans-handler`.
- **Is it a Credit Package?** -> Use `credits-handler`.
- **Is it a Custom One-time or Recurring Product?** -> **Continue with this skill.**

### 2. Create Checkout Session (API/Action)
You need a server-side endpoint to create the Stripe Checkout Session.
- **File**: Create a new route (e.g., `src/app/api/app/orders/create/route.ts`) or Server Action.
- **Import**: `import stripe from "@/lib/stripe";`
- **Metadata**: **CRITICAL**. Always attach `metadata` to the session to identify the purchase type in the webhook.
  ```typescript
  metadata: {
    type: "my_custom_feature",
    userId: user.id,
    customId: "..."
  }
  ```
- **URLs**: Use the standard success/error pages or custom ones if needed.
  - Success: `${process.env.NEXT_PUBLIC_APP_URL}/app/subscribe/success?session_id={CHECKOUT_SESSION_ID}`
  - Error: `${process.env.NEXT_PUBLIC_APP_URL}/app/subscribe/error`

### 3. Handle Webhook Fulfillment
All Stripe events go to `src/app/api/webhooks/stripe/route.ts`.
- **File**: `src/app/api/webhooks/stripe/route.ts`
- **Locate**: `onCheckoutSessionCompleted` (for one-time) or `handleOutsidePlanManagementProductInvoicePaid` (for invoices).
- **Implement**:
  1. Extract `metadata` from the event object.
  2. Check if `metadata.type` matches your custom feature.
  3. **If yes**: Run your fulfillment logic.
     - **Simple Logic**: Update DB directly.
     - **Heavy Logic**: Dispatch an Inngest event to handle it in the background.
  4. **If no**: Let the function fall through to standard plan/credit handling.

### 4. Background Processing (Inngest)
**Recommended for production**: If your fulfillment logic involves multiple DB calls, external APIs, or could timeout (Stripe expects a response in < 3s):
- Use `inngest-handler` to create a new function.
- In the webhook, just dispatch the event:
  ```typescript
  await inngest.send({ name: "app/payment.custom_succeeded", data: { sessionId: object.id, metadata } });
  ```
- Handle the actual logic in `src/inngest/functions/...`.

### 5. Database Updates
- If the purchase grants access to a resource, update the corresponding schema (e.g., `orders`, `courses`).
- Ensure the fulfillment is idempotent (handle duplicate webhook events gracefully).

### 6. Frontend Integration
- Use a simple Button or Form to call your API/Action.
- Redirect the user to the returned `url` (Stripe Checkout).

## Best Practices
- **Idempotency**: Webhooks can fire multiple times. Ensure your logic checks if the order is already fulfilled.
- **Metadata**: Rely on metadata, not just product IDs, for cleaner logic separation.
- **Timeouts**: Stripe webhooks must respond quickly. Use Inngest for anything taking > 2 seconds.
- **Testing**: Use `stripe listen` to test webhooks locally.

## Reference
See `reference.md` for code snippets on creating sessions, handling webhooks, and using Inngest.

Quick Install

$npx ai-builder add skill AayushBaniya2006/stripe-handler

Details

Type
skill
Slug
AayushBaniya2006/stripe-handler
Created
6d ago