展示HN:我们构建了一个开源、零webhook的支付处理器。
Show HN: We built an open source, zero webhooks payment processor

原始链接: https://github.com/flowglad/flowglad

## Flowglad:为开发者简化的计费方案 Flowglad 旨在通过提供简化的自助计费解决方案,彻底改变开发者支付方式。它消除了传统支付系统的复杂性——不再需要 Webhooks、手动 ID 映射或复杂的数据库设置。相反,Flowglad 直接与您的现有身份验证系统集成(使用您的用户/组织 ID),并为客户计费数据提供单一的事实来源。 主要功能包括可通过用户友好的仪表板进行配置的自适应定价模式(订阅、基于用量、分层等),以及适用于 React 和 Node.js 的全栈 SDK。开发者可以轻松地在前端(使用 `useBilling()`)和后端(`flowglad(userId).getBilling()`)检查功能访问权限和用量余额。 Flowglad 优先考虑无缝的开发者体验,目标是在一分钟内完成设置并尽量减少持续维护。它的设计理念是让开发者专注于构建,而不是管理支付,并承诺未来解锁更多支付提供商选项。

## Flowglad:为开发者简化支付 Flowglad (github.com/flowglad) 是一款新的开源支付处理器,旨在改善开发者集成支付的体验,目前是*基于* Stripe 构建的。 开发者在使用 Stripe 十年后,发现它功能强大,但对于常见用例和复杂的 webhook 管理(250+ 事件类型!)需要大量的“胶水代码”。 Flowglad 提供了一种类似 React 的响应式编程范式来处理支付,允许开发者快速启动定价模型——包括使用计量表和功能门禁——这些模型定义在 `pricing.yaml` 文件中(类似于 Terraform)。 这旨在使 AI 编码代理更容易集成支付。 目前,Flowglad 利用 Stripe 进行实际的支付处理(需要 Stripe Connect 账户),但计划最终更接近银行卡网络。 关键特性包括简化的定价模型设置、实时客户使用情况跟踪以及无需数据库模式更改的集成。 该项目正在寻求反馈,特别是关于所需功能和用例的反馈,并采用混合许可方式(某些包采用 MIT 许可,平台采用 AGPLv3 许可)。 虽然有些人争论专注于开发者体验而非核心支付功能的价值,但创建者认为更流畅的 DX 是向前迈出的关键一步。
相关文章

原文

Flowglad Banner

The easiest way to make internet money.
Get Started

· Quickstart · Website · Issues · Discord

Join Discord Community Follow @flowglad Backed by YC

Infinite pricing models, one source of truth, zero webhooks.

nav-demo

  • Default Stateless Say goodbye to webhooks, "subscriptions" db tables, customer_id columns, PRICE_ID env variables, or manually mapping your plans to prices to features and back.
  • Single Source of Truth: Read your latest customer billing state from Flowglad, including feature access and usage meter credits
  • Access Data Using Your Ids: Query customer state by your auth's user ids. Refer to prices, features, and usage meters via slugs you define.
  • Full-Stack SDK: Access your customer's data on the backend using flowgladServer.getBilling(), or in your React frontend using our useBilling() hook
  • Adaptable: Iterate on new pricing models in testmode, and push them to prod in a click. Seamlessly rotate pricing models in your app without any redeployment.

First, install the packages necessary Flowglad packages based on your project setup:

# Next.js Projects
bun add @flowglad/nextjs

# React + Express projects:
bun add @flowglad/react @flowglad/express

# All other React + Node Projects
bun add @flowglad/react @flowglad/server

Flowglad integrates seamlessly with your authentication system and requires only a few lines of code to get started in your Next.js app. Setup typically takes under a minute:

  1. Configure Your Flowglad Server Client

Create a utility to generate your Flowglad server instance. Pass your own customer/user/organization IDs—Flowglad never requires its own customer IDs to be managed in your app:

// utils/flowglad.ts
import { FlowgladServer } from '@flowglad/nextjs/server'

export const flowglad = (customerExternalId: string) => {
  return new FlowgladServer({
    customerExternalId,
    getCustomerDetails: async (externalId) => {
      // e.g. Fetch user info from your DB using your user/org/team ID
      const user = await db.users.findOne({ id: externalId })
      if (!user) throw new Error('User not found')
      return { email: user.email, name: user.name }
    },
  })
}
  1. Expose the Flowglad API Handler

Add an API route so the Flowglad client can communicate securely with your backend:

// app/api/flowglad/[...path]/route.ts
import { nextRouteHandler } from '@flowglad/nextjs/server'
import { flowglad } from '@/utils/flowglad'

export const { GET, POST } = nextRouteHandler({
  flowglad,
  getCustomerExternalId: async (req) => {
    // Extract your user/org/team ID from session/auth.
    // For B2C: return user.id from your DB
    // For B2B: return organization.id or team.id
    const userId = await getUserIdFromRequest(req)
    if (!userId) throw new Error('User not authenticated')
    return userId
  },
})
  1. Wrap Your App with the Provider

In your root layout (App Router) or _app (Pages Router):

import { FlowgladProvider } from '@flowglad/nextjs'

// App Router example (app/layout.tsx)
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <FlowgladProvider loadBilling={true}>
          {children}
        </FlowgladProvider>
      </body>
    </html>
  )
}

That’s it—Flowglad will use your app’s internal user IDs for all billing logic and integrate billing status into your frontend in real time.

B2C apps: Use user.id as the customer ID.
B2B apps: Use organization.id or team.id as the customer ID.

Flowglad does not require you to change your authentication system or manage Flowglad customer IDs. Just pass your own!

  1. Use useBilling on your frontend, and flowglad(userId).getBilling() on your backend

Frontend Example: Checking Feature Access and Usage

'use client'

import { useBilling } from '@flowglad/nextjs'

export function FeatureGate({ featureSlug, children }) {
  const { loaded, errors, checkFeatureAccess } = useBilling()

  if (!loaded || !checkFeatureAccess) {
    return <p>Loading billing state…</p>
  }

  if (errors?.length) {
    return <p>Unable to load billing data right now.</p>
  }

  return checkFeatureAccess(featureSlug)
    ? children
    : <p>You need to upgrade to unlock this feature.</p>
}
import { useBilling } from '@flowglad/nextjs'

export function UsageBalanceIndicator({ usageMeterSlug }) {
  const { loaded, errors, checkUsageBalance, createCheckoutSession } = useBilling()

  if (!loaded || !checkUsageBalance) {
    return <p>Loading usage…</p>
  }

  const usage = checkUsageBalance(usageMeterSlug)

  return (
    <div>
      <h3>Usage Balance</h3>
      <p>
        Remaining:{' '}
        {usage ? `${usage.availableBalance} credits available` : <button onClick={() => createCheckoutSession({ 
            priceSlug: 'pro_plan',
            autoRedirect: true
          })}
        />}
      </p>
    </div>
  )
}

Backend Example: Server-side Feature and Usage Checks

import { NextResponse } from 'next/server'
import { flowglad } from '@/utils/flowglad'

const hasFastGenerations = async () => {
  // ...
  const user = await getUser()

  const billing = await flowglad(user.id).getBilling()
  const hasAccess = billing.checkFeatureAccess('fast_generations')
  if (hasAccess) {
    // run fast generations
  } else {
    // fall back to normal generations
  }
}
import { flowglad } from '@/utils/flowglad'

const processChatMessage = async (params: { chat: string }) => {
  // Extract your app's user/org/team ID,
  // whichever corresponds to your customer
  const user = await getUser()

  const billing = await flowglad(user.id).getBilling()
  const usage = billing.checkUsageBalance('chat_messages')
  if (usage.availableBalance > 0) {
    // run chat request
  } else {
    throw Error(`User ${user.id} does not have sufficient usage credits`)
  }
}

First, set up a pricing model. You can do so in the dashboard in just a few clicks using a template, that you can then customize to suit your specific needs.

We currently have templates for the following pricing models:

  • Usage-limit + Subscription Hybrid (like Cursor)
  • Unlimited Usage (like ChatGPT consumer)
  • Tiered Access and Usage Credits (like Midjourney)
  • Feature-Gated Subscription (like Linear)

And more on the way. If you don't see a pricing model from our templates that suits you, you can always make one from scratch.

In the last 15 years, the market has given developers more options than ever for every single part of their stack. But when it comes to payments, there have been virtually zero new entrants. The existing options are slim, and almost all of them require us to talk to sales to even set up an account. When it comes to self-serve payments, there are even fewer options.

The result? The developer experience and cost of payments has barely improved in that time. Best in class DX in payments feels eerily suspended in 2015. Meanwhile, we've enjoyed constant improvements in auth, compute, hosting, and practically everything else.

Flowglad wants to change that.

We're building a payments layer that lets you:

  • Think about billing and payments as little as possible
  • Spend as little time on integration and maintenance as possible
  • Get as much out of your single integration as possible
  • Unlock more payment providers from a single integration

Achieving this mission will take time. It will be hard. It might even make some people unhappy. But with AI bringing more and more developers on line and exploding the complexity of startup billing, the need is more urgent than ever.

联系我们 contact @ memedata.com