展示HN:Stripe-no-webhooks – 将你的Stripe数据同步到你的Postgres数据库
Show HN: Stripe-no-webhooks – Sync your Stripe data to your Postgres DB

原始链接: https://github.com/pretzelai/stripe-no-webhooks

## Stripe-No-Webhooks:简化的 Stripe 集成 Stripe-no-webhooks 是一个具有明确观点的库,旨在简化 Stripe 支付的实施,特别是对于使用 PostgreSQL 数据库的 Next.js 应用程序。它通过自动将 Stripe 数据同步到数据库来消除手动处理 webhook 的需要。 **主要特性:** * **代码定义计划:** 直接在代码中定义订阅计划,然后将其同步到 Stripe 帐户。 * **简化的 API:** 易于使用的 API,用于订阅、积分、钱包余额、充值和基于用量的计费。支持基于座位的计费、税务征收和计划管理。 * **自动 Webhook:** 自动处理 webhook,保持数据库同步。 * **可定制的回调:** 使用可选的回调(例如 `onSubscriptionCreated`)实现自定义逻辑。 * **定价页面生成:** 自动生成可定制的定价页面,包含计划选择和结账功能。 **设置:** 1. 通过 npm 安装:`npm install stripe-no-webhooks stripe` & `npx stripe-no-webhooks init`(提供 Stripe 密钥、数据库 URL 和站点 URL)。 2. 运行迁移:`npx stripe-no-webhooks migrate` 以创建数据库模式。 3. 在 `billing.config.ts` 中配置计划。 4. 将计划同步到 Stripe:`npx stripe-no-webhooks sync`。 5. 在 `lib/billing.ts` 中实现用户解析。 该库还提供用于管理订阅、处理积分/钱包/用量以及提供客户门户的工具。它旨在简化复杂的计费场景并减少开发开销。完整文档请访问 [https://github.com/pretzelai/stripe-no-webhooks](https://github.com/pretzelai/stripe-no-webhooks)。

## Stripe-no-webhooks:将Stripe数据同步到Postgres Stripe-no-webhooks是一个新的开源库,旨在通过直接同步到Postgres数据库来简化Stripe数据的使用。它消除了管理Stripe webhook或担心API速率限制的需要,为开发者提供了一种更简化的方法。 该库处理webhook处理、模式创建和数据同步,允许开发者在TypeScript中定义计费计划,并自动创建相应的Stripe产品和价格。它支持复杂的计费模式,包括预付积分、账户钱包和基于用量的计费。 主要优势包括更轻松的自定义分析、AI代理的安全访问(无需完全访问Stripe仪表板)以及对Stripe API的简化抽象层。一个演示应用程序可用(目前由于第三方身份验证提供商的问题而遇到问题),该项目欢迎贡献和错误报告。它的目标是通过处理权利跟踪、续订和故障恢复的复杂性来降低构建订阅支付系统的复杂性。 [https://github.com/pretzelai/stripe-no-webhooks](https://github.com/pretzelai/stripe-no-webhooks)
相关文章

原文

This is an opinionated library to help you implement payments with Stripe.

  1. Define plans in code which sync to your Stripe account
  2. No manual webhook setup - the library handles webhooks and syncs Stripe data to your DB
  3. Simple APIs for subscriptions, credits, wallet balances, top-ups, and usage-based billing
  4. Support for seat based billing, tax collection, plan upgrades and downgrades (including sane handling of credits)
  5. Optional callbacks (onSubscriptionCreated, etc.) for custom logic

This guide assumes you have a Next.js app and a PostgreSQL database. We recommend starting with a test mode Stripe API key so you can test your setup locally in your dev environment. Then, the guide will walk you through how to set up your app for production.

npm install stripe-no-webhooks stripe
npx stripe-no-webhooks init

You'll be prompted for:

  • Stripe test key (for eg, sk_test_...) - get it from Stripe dashboard
  • Database URL – PostgreSQL connection string (for example: postgresql://postgres:password@localhost:5432/app_db)
  • Site URL - For eg, http://localhost:3000 for local dev

This will update your .env file with your credentials and create the following files:

  • billing.config.ts: Your config file with your plans
  • lib/billing.ts: Your core billing client instance
  • app/api/stripe/[...all]/route.ts: Your webhook handler and API routes
npx stripe-no-webhooks migrate

This will create the stripe schema in your database with the necessary tables for syncing Stripe data and tracking credits + usage.

Edit billing.config.ts to define your plans for the test environment. Here's an example:

const billingConfig: BillingConfig = {
  test: {
    plans: [
      {
        name: "Free",
        price: [{ amount: 0, currency: "usd", interval: "month" }],
      },
      {
        name: "Pro",
        price: [
          { amount: 2000, currency: "usd", interval: "month" }, // $20/mo
          { amount: 20000, currency: "usd", interval: "year" }, // $200/yr
        ],
      },
    ],
  },
  production: {
    plans: [], // Add when going live
  },
};

Plans can also include credits, wallet, and usage-based billing:

{
  name: "Pro",
  price: [{ amount: 2000, currency: "usd", interval: "month" }],
  features: {
    api_calls: {
      credits: { allocation: 1000 },   // 1000 included/month
      pricePerCredit: 1,               // $0.01 per extra call (used for top-ups and usage billing)
      trackUsage: true,                // enable usage-based billing for overages
    },
  },
  wallet: {
    allocation: 500,                   // $5.00 prepaid balance
  },
}

See Credits, Wallet, and Usage Billing docs for details.

npx stripe-no-webhooks sync

Creates products/prices in Stripe and updates your config with their IDs.

5. Update your billing client

Update lib/billing.ts to specify how to get the userId in the resolveUser function. For example, with Clerk:

import { Billing } from "stripe-no-webhooks";
import { auth } from "@clerk/nextjs/server"; // or your auth
import billingConfig from "../billing.config";

export const billing = new Billing({
  billingConfig,
  successUrl: process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000",
  cancelUrl: process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000",
  resolveUser: async () => {
    const { userId } = await auth();
    return userId ? { id: userId } : null;
  },
});

Start your Next.js app, then in another terminal, forward Stripe webhooks:

stripe listen --forward-to localhost:3000/api/stripe/webhook

Your setup is complete! Now let's use it.


stripe-no-webhooks lets you generate a full pricing page with plan selection, monthly/yearly toggle, and checkout flow built-in. Or you can call checkout() directly:

import { checkout } from "stripe-no-webhooks/client";

<button onClick={() => checkout({ planName: "Pro", interval: "month" })}>
  Upgrade to Pro
</button>;

Test card: 4242 4242 4242 4242, any future MM/YY expiry, any CVC.

Check subscription status

import { billing } from "@/lib/billing";

const subscription = await billing.subscriptions.get({ userId });

if (subscription?.status === "active") {
  console.log("Plan:", subscription.plan?.name);
}

What happens behind the scenes

When a user completes checkout:

  1. Stripe sends a webhook to your app
  2. The library receives it and syncs the data to your database. If credits / wallet are enabled, it will also update the credits / wallet balances
  3. billing.subscriptions.get({ userId }) now returns the subscription based on the Stripe data that's synced to your database
  4. Credits / wallet are tracked automatically through a credit balance and a ledger of transactions via the library's internal APIs. These APIs are all idempotent and you don't have to worry about double counting or missing transactions

You can verify this by checking your database's stripe.subscriptions and stripe.credit_balances and stripe.credit_ledger.

Use credits, wallet, or usage billing

// Credits: consume included units
if (await billing.credits.hasCredits({ userId, key: "api_calls", amount: 1 })) {
  await billing.credits.consume({ userId, key: "api_calls", amount: 1 });
}

// Wallet: deduct from prepaid balance (in cents)
await billing.wallet.consume({
  userId,
  amount: 50,
  description: "AI generation",
});

// Usage: record for end-of-period billing
await billing.usage.record({ userId, key: "api_calls", amount: 1 });

See the full set of features in the Credits, Wallet, and Usage docs.

Let users manage their subscription:

import { customerPortal } from "stripe-no-webhooks/client";

<button onClick={() => customerPortal()}>
  Manage Billing
</button>
export const billing = new Billing({
  billingConfig,
  callbacks: {
    onSubscriptionCreated: async (subscription) => {
      // Send welcome email
    },
    onSubscriptionCancelled: async (subscription) => {
      // Clean up resources
    },
    // List of full callbacks in docs/reference.md
  },
});

npx stripe-no-webhooks generate pricing-page

This creates a fully customizable pricing page component at components/PricingPage.tsx:

// in your pricing page, for eg /pricing
import { PricingPage } from "@/components/PricingPage";

export default function Pricing() {
  return <PricingPage />;
}

Automatically handles: plan fetching, current subscription detection, monthly/yearly toggle, checkout flow, redirect handling, error handling, and more.


  1. Add plans to the production section of billing.config.ts
  2. Run npx stripe-no-webhooks sync and choose "Set up for production". This will:
  • Sync your plans to Stripe live mode
  • Create a webhook endpoint for your app in Stripe
  • Display the webhook URL and secret in the CLI output
  1. Add the webhook secret to your production environment (for eg, Vercel environment variables):
    STRIPE_WEBHOOK_SECRET=whsec_...
    STRIPE_SECRET_KEY=sk_live_... # IMPORTANT: Your live Stripe secret key
    DATABASE_URL=postgresql://[username]:[password]@[production-db-url]:5432/[production-db-name]
    NEXT_PUBLIC_APP_URL=https://your-production-app.com
    

Feature Use Case
Credits "1000 API calls/month included" - consumable units
Wallet "$5/month for AI usage" - prepaid spending balance
Top-ups Let users buy more credits on demand
Usage Billing "Pay $0.10 per API call" - post-paid metered billing
Team Billing Bill organizations, per-seat pricing
Tax Collection Automatic VAT/GST calculation and ID collection
Payment Failures Handle declined cards, retry logic

Command Description
init Set up config files and .env
migrate Create database tables
sync Sync plans to Stripe
generate pricing-page Generate pricing component
backfill Import existing Stripe data

See docs/reference.md for the complete API.

If you are an LLM, full documentation is at https://github.com/pretzelai/stripe-no-webhooks/blob/main/docs/llms.txt

联系我们 contact @ memedata.com