agentsclimarketplace

Stripe billing

Skill ComeOnOliver/skillshub/skills/TerminalSkills/skills/stripe-billing

🧠 The right skill, one API call. AI agent skills registry with token-efficient skill resolution. 5,000+ skills from 500+ top repos.

Install
npx -y skills add ComeOnOliver/skillshub --skill stripe-billing

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

5.1 KB, as published. Nobody here has run it

Stripe Billing β€” SaaS Subscription & Usage-Based Billing

You are an expert in Stripe Billing, the complete billing platform for SaaS businesses. You help developers implement subscription management, usage-based billing, metered pricing, free trials, proration, invoicing, customer portal, and webhook-driven lifecycle management β€” building everything from simple monthly plans to complex per-seat + usage hybrid pricing.

Core Capabilities

Subscription Setup

import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

// Create product + price
const product = await stripe.products.create({
  name: "Pro Plan",
  description: "Full access with API usage",
});

// Fixed recurring price
const monthlyPrice = await stripe.prices.create({
  product: product.id,
  unit_amount: 2900,                      // $29.00
  currency: "usd",
  recurring: { interval: "month" },
});

// Usage-based price (metered)
const apiPrice = await stripe.prices.create({
  product: product.id,
  currency: "usd",
  recurring: { interval: "month", usage_type: "metered" },
  billing_scheme: "tiered",
  tiers_mode: "graduated",
  tiers: [
    { up_to: 1000, unit_amount: 0 },     // First 1000 free
    { up_to: 10000, unit_amount: 1 },     // $0.01 per call (1K-10K)
    { up_to: "inf", unit_amount: 0.5 },   // $0.005 per call (10K+)
  ],
});

// Create checkout session
const session = await stripe.checkout.sessions.create({
  mode: "subscription",
  customer_email: user.email,
  line_items: [
    { price: monthlyPrice.id, quantity: 1 },
    { price: apiPrice.id },               // Metered β€” no quantity
  ],
  subscription_data: {
    trial_period_days: 14,
    metadata: { userId: user.id },
  },
  success_url: "https://app.example.com/billing/success?session_id={CHECKOUT_SESSION_ID}",
  cancel_url: "https://app.example.com/billing/cancel",
});
// Redirect to session.url

Usage Reporting

// Report API usage for metered billing
async function reportUsage(subscriptionItemId: string, quantity: number) {
  await stripe.subscriptionItems.createUsageRecord(subscriptionItemId, {
    quantity,
    timestamp: Math.floor(Date.now() / 1000),
    action: "increment",                  // Adds to current period total
  });
}

// In your API middleware
app.use(async (req, res, next) => {
  next();
  // After response, report usage
  const user = req.user;
  if (user.stripeSubscriptionItemId) {
    await reportUsage(user.stripeSubscriptionItemId, 1);
  }
});

Webhook Handler

app.post("/api/webhooks/stripe", async (req, res) => {
  const event = stripe.webhooks.constructEvent(
    req.body, req.headers["stripe-signature"]!, process.env.STRIPE_WEBHOOK_SECRET!,
  );

  switch (event.type) {
    case "checkout.session.completed": {
      const session = event.data.object as Stripe.Checkout.Session;
      await db.users.update(session.metadata!.userId, {
        plan: "pro",
        stripeCustomerId: session.customer as string,
        stripeSubscriptionId: session.subscription as string,
      });
      break;
    }
    case "invoice.paid": {
      const invoice = event.data.object as Stripe.Invoice;
      await db.invoices.create({
        userId: await getUserByStripeCustomer(invoice.customer as string),
        amount: invoice.amount_paid,
        pdfUrl: invoice.invoice_pdf,
      });
      break;
    }
    case "customer.subscription.deleted": {
      const sub = event.data.object as Stripe.Subscription;
      await db.users.update({ stripeSubscriptionId: sub.id }, { plan: "free" });
      break;
    }
    case "invoice.payment_failed": {
      const invoice = event.data.object as Stripe.Invoice;
      await sendPaymentFailedEmail(invoice.customer as string);
      break;
    }
  }

  res.json({ received: true });
});

Customer Portal

// Let customers manage their own subscription
app.post("/api/billing/portal", async (req, res) => {
  const session = await stripe.billingPortal.sessions.create({
    customer: req.user.stripeCustomerId,
    return_url: "https://app.example.com/settings",
  });
  res.json({ url: session.url });
});
// Customer can: change plan, update payment method, cancel, view invoices

Installation

npm install stripe

Best Practices

  1. Webhooks are truth β€” Don't rely on checkout redirects alone; webhooks handle edge cases (failed payments, renewals)
  2. Customer portal β€” Use Stripe's hosted portal for plan changes, cancellation, invoices; saves weeks of development
  3. Metered billing β€” Report usage incrementally via createUsageRecord; Stripe aggregates and invoices at period end
  4. Trial periods β€” Set trial_period_days on subscription; no payment collected until trial ends
  5. Proration β€” Stripe auto-prorates when customers upgrade/downgrade mid-cycle; no manual calculations
  6. Idempotency keys β€” Pass idempotencyKey on creates to prevent duplicate charges on retries
  7. Test mode β€” Use sk_test_ key for development; Stripe provides test card numbers for all scenarios
  8. Tax automation β€” Enable Stripe Tax for automatic tax calculation and collection; handles global tax compliance

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.