Skip to content
Agentmart
Submit a tool

payment-integration

Stripe, RevenueCat, subscription billing, webhooks, PCI compliance, and tax.

Skill by travisjneuman

IndexedMIT★ 106
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/travisjneuman-payment-integration

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Stripe, RevenueCat, subscription billing, webhooks, PCI compliance, and tax. Use when integrating payments or subscriptions, handling payment webhooks, or reviewing billing and PCI scope.

Use cases: security, finance

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/payment-integration

What's inside

Skill name
payment-integration
Description
Stripe, RevenueCat, subscription billing, webhooks, PCI compliance, and tax. Use when integrating payments or subscriptions, handling payment webhooks, or reviewing billing and PCI scope.
License
MIT
Instructions
471 lines in SKILL.md · view on GitHub

Before installing

  • Instructions call the network

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Payment Integration

## Overview

This skill covers implementing payment processing and subscription billing in web and mobile applications. It addresses Stripe integration (Checkout, Elements, PaymentIntents), subscription lifecycle management, webhook handling with idempotency, PCI compliance, metered and usage-based billing, tax calculation, refund processing, and RevenueCat for mobile subscriptions.

Use this skill when adding payment processing, building subscription billing, handling Stripe webhooks, implementing pricing pages, managing payment failures, or integrating mobile in-app purchases.

---

## Core Principles

1. **Never handle raw card data** - Use Stripe Elements or Checkout to keep card numbers off your servers entirely. This keeps you at PCI SAQ-A (the simplest compliance level) rather than SAQ-D.
2. **Webhooks are the source of truth** - Never trust client-side payment confirmation. A successful PaymentIntent on the client means nothing until your webhook handler confirms `payment_intent.succeeded`. Build your system around webhook events.
3. **Idempotency everywhere** - Webhooks can be delivered multiple times. Every webhook handler must be idempotent. Use Stripe's event ID as a deduplication key.
4. **Handle failure gracefully** - Payments fail for many reasons (insufficient funds, expired cards, fraud detection). Build retry flows, dunning emails, and graceful degradation into the subscription lifecycle.
5. **Test with Stripe's test mode** - Use test API keys, test card numbers, and test clocks for subscription lifecycle testing. Never test with real payment methods.

---

## Key Patterns

### Pattern 1: Stripe Checkout for Subscriptions

**When to use:** When you want Stripe to handle the entire checkout UI, including payment form, coupon codes, and tax calculation.

**Implementation:**

```typescript
// Server - Create Checkout Session
// app/api/checkout/route.ts
import Stripe from "stripe";
import { NextRequest, NextResponse } from "next/server";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: "2024-06-20",
});

export async function POST(req: NextRequest) {
  const { priceId, userId, email } = await req.json();

  // Get or create Stripe customer
  let customerId = await getStripeCustomerId(userId);
  if (!customerId) {
    const customer = await stripe.customers.create({
      email,
      metadata: { userId },
    });
    customerId = customer.id;
    await saveStripeCustomerId(userId, customerId);
  }

  const session = await stripe.checkout.sessions.create({
    customer: customerId,
    mode: "subscription",
    line_items: [{ price: priceId, quantity: 1 }],
    success_url: `${process.env.NEXT_PUBLIC_URL}/dashboard?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`,
    subscription_data: {
      metadata: { userId },
      trial_period_days: 14,
    },
    // Enable automatic tax calculation
    automatic_tax: { enabled: true },
    // Allow promo codes
    allow_promotion_codes: true,
    // Collect billing address for tax
    billing_address_collection: "required",
    // Customer portal for self-service management
    customer_update: {
      address: "auto",
      name: "auto",
    },
    // Auto-renewal disclosure next to the pay button + express consent
    // (California ARL, FTC ROSCA). terms_of_service needs a ToS URL set in the Dashboard.
    custom_text: {
      submit: { message: "Renews automatically each month at the listed price after your 14-day trial until you cancel. Cancel anytime online in Billing settings." },
    },
    consent_collection: { terms_of_service: "required" },
  });

  return NextResponse.json({ url: session.url });
}
```

```tsx
// Client - Redirect to Checkout
function PricingCard({ plan }: { plan: PricingPlan }) {
  const [loading, setLoading] = useState(false);

  const handleSubscribe = async () => {
    setLoading(true);
    try {
      const res = await fetch("/api/checkout", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          priceId: plan.stripePriceId,
          userId: user.id,
          email: user.email,
        }),
      });

      const { url } = await res.json();
      window.location.href = url; // Redirect to Stripe Checkout
    } catch (error) {
      toast.error("Failed to start checkout");
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="pricing-card">
      <h3>{plan.name}</h3>
      <p className="price">${plan.price}/mo</p>
      <ul>
        {plan.features.map((f) => (
          <li key={f}>{f}</li>

From travisjneuman/.claude, MIT.

More from travisjneuman/.claude

Compare and alternatives

    Featured in

    Signals

    Stars
    106
    Forks
    26
    Open issues
    2
    Last commit (this folder)
    Oct 6, 2026 (21 days ago)

    From GitHub (fetched Oct 24, 2026).

    Details

    License
    MIT
    First seen
    Oct 24, 2026
    Last checked
    Oct 24, 2026

    More from travisjneuman

    Cite this page

    payment-integration skill. Agent Mart. https://agentmart.dev/skills/travisjneuman-payment-integration (last updated 2026-10-24)