@convex-dev/stripe

中文文档
0.1.7发布于 2026/10/10Apache-2.0TypeScriptES Module近 30 天下载 50.3万

Convex的条纹组件.

中文使用文档
文档目录28 节
  1. 特征
  2. 快速启动
  3. 1. 安装组件
  4. 2. 添加到您的 Convex 应用程序
  5. 3. 设置环境变量
  6. 4. 配置花纹 Webhooks
  7. 5. 登记Webhook路线
  8. 6. 使用本构成部分
  9. API 参考
  10. 条纹订阅客户端
  11. 创建检查会议
  12. 组件查询
  13. 可用的公共查询
  14. Webhook 事件
  15. 自定义 Webhook 处理器
  16. 数据库Schema
  17. 客户
  18. 订阅
  19. 检查出会话( s)
  20. 付款
  21. 发票
  22. 示例应用
  23. 认证
  24. 解决问题
  25. 退职后表格为空
  26. “ 未验证” 错误
  27. Webhooks 返回 400/500
  28. 许可证

@ convex-dev/ stripe (英语)

Integrate Stripe with Convex in 10 mins (Stripe Component)

用于整合面额支付、订阅和计费的Convex组件 输入您的 Convex 应用程序 .

npm version

需要节点.js 18 或以后, 匹配 Strede 节点 SDK v22 运行时间 页:1.

特征

  • 🛒 退出会话 - 建立一次性付款和订阅结账制度
  • 📦 订阅管理 - 创建、更新、取消订阅
  • 👥 客户管理 - 自动创建客户和链接
  • 💳 客户端门户 - 让用户管理账单
  • 🪑 基于座位的定价 - 更新团队账单的订阅数量
  • 🔗 用户/操作链接 - 连接用户的付款和订阅 组织
  • 🔔 Webhook 处理 - 将条纹数据自动同步到您的 Convex 数据库
  • 📊 实时数据 - 实时查询付款、订阅和发票

快速启动

1. 安装组件

npm install @convex-dev/stripe

2. 添加到您的 Convex 应用程序

创建或更新 convex/convex.config.ts数字 :

import { defineApp } from "convex/server";
import stripe from "@convex-dev/stripe/convex.config.js";

const app = defineApp();
app.use(stripe);

export default app;

3. 设置环境变量

把这些添加到您的 凸起板 环境变量:

变量说明
STRIPE_SECRET_KEY您的条纹密钥( E)sk_test_... 或者说 sk_live_...(中文(简体) )
STRIPE_WEBHOOK_SECRETWebhook 签名秘密( Namewhsec_...- 见步骤4

4. 配置花纹 Webhooks

  1. 转到 Frape Dashboard – 开发者 – Webhooks 页面存档备份,存于互联网档案馆
  2. 点击 “添加终点”
  3. 输入您的 Webhook URL :
    https://<your-convex-deployment>.convex.site/stripe/webhook
    
    (在Convex仪表板上找到您的部署名称 - 这是之前的部分) .convex.cloud 在您的 URL 中)
  4. 选择这些事件 :
    • checkout.session.completed
    • customer.created
    • customer.updated
    • customer.deleted
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.created
    • invoice.finalized
    • invoice.updated
    • invoice.paid
    • invoice.payment_failed
    • payment_intent.succeeded
    • payment_intent.payment_failed
  5. 点击 “添加终点”
  6. 复制 签名秘密 并添加为 STRIPE_WEBHOOK_SECRET 在凸起处

5. 登记Webhook路线

创建 convex/http.ts数字 :

import { httpRouter } from "convex/server";
import { components } from "./_generated/api";
import { registerRoutes } from "@convex-dev/stripe";

const http = httpRouter();

// Register Stripe webhook handler at /stripe/webhook
registerRoutes(http, components.stripe, {
  webhookPath: "/stripe/webhook",
  apiVersion: "2026-04-22.dahlia", // Optional
});

export default http;

6. 使用本构成部分

创建 convex/stripe.ts数字 :

import { action } from "./_generated/server";
import { components } from "./_generated/api";
import { StripeSubscriptions } from "@convex-dev/stripe";
import { v } from "convex/values";

const stripeClient = new StripeSubscriptions(components.stripe, {});

// Create a checkout session for a subscription
export const createSubscriptionCheckout = action({
  args: { priceId: v.string() },
  returns: v.object({
    sessionId: v.string(),
    url: v.union(v.string(), v.null()),
  }),
  handler: async (ctx, args) => {
    const identity = await ctx.auth.getUserIdentity();
    if (!identity) throw new Error("Not authenticated");

    // Get or create a Stripe customer
    const customer = await stripeClient.getOrCreateCustomer(ctx, {
      userId: identity.subject,
      email: identity.email,
      name: identity.name,
    });

    // Create checkout session
    return await stripeClient.createCheckoutSession(ctx, {
      priceId: args.priceId,
      customerId: customer.customerId,
      mode: "subscription",
      successUrl: "http://localhost:5173/?success=true",
      cancelUrl: "http://localhost:5173/?canceled=true",
      subscriptionMetadata: { userId: identity.subject },
    });
  },
});

// Create a checkout session for a one-time payment
export const createPaymentCheckout = action({
  args: { priceId: v.string() },
  returns: v.object({
    sessionId: v.string(),
    url: v.union(v.string(), v.null()),
  }),
  handler: async (ctx, args) => {
    const identity = await ctx.auth.getUserIdentity();
    if (!identity) throw new Error("Not authenticated");

    const customer = await stripeClient.getOrCreateCustomer(ctx, {
      userId: identity.subject,
      email: identity.email,
      name: identity.name,
    });

    return await stripeClient.createCheckoutSession(ctx, {
      priceId: args.priceId,
      customerId: customer.customerId,
      mode: "payment",
      successUrl: "http://localhost:5173/?success=true",
      cancelUrl: "http://localhost:5173/?canceled=true",
      paymentIntentMetadata: { userId: identity.subject },
    });
  },
});

API 参考

条纹订阅客户端

import { StripeSubscriptions } from "@convex-dev/stripe";

const stripeClient = new StripeSubscriptions(components.stripe, {
  STRIPE_SECRET_KEY: "sk_...", // Optional, defaults to process.env.STRIPE_SECRET_KEY
  apiVersion: "2026-04-22.dahlia", // Optional Stripe API version
});

方法

方法说明
createCheckoutSession()创建条纹检查会话
createCustomerPortalSession()生成客户端 URL
createCustomer()创建新条纹客户端
getOrCreateCustomer()获取已有客户或创建新客户
cancelSubscription()取消订阅
reactivateSubscription()重新启动要取消的订阅集
updateSubscriptionQuantity()更新座位数

创建检查会议

await stripeClient.createCheckoutSession(ctx, {
  priceId: "price_...",
  customerId: "cus_...",           // Optional
  mode: "subscription",             // "subscription" | "payment" | "setup"
  successUrl: "https://...",
  cancelUrl: "https://...",
  quantity: 1,                      // Optional, default 1
  metadata: {},                     // Optional, session metadata
  subscriptionMetadata: {},         // Optional, attached to subscription
  paymentIntentMetadata: {},        // Optional, attached to payment intent
  params: {
    allow_promotion_codes: true,
    ui_mode: "embedded_page",
    return_url: "https://...",
  },                                // Optional Stripe Checkout Session params
});

params 是 Strefe 取出会话字段的打出通过 组件不直接建模。 域数 params 覆盖已构建 默认,但 mode继续由高层控制 mode 参数。 对于非托管的UI 模式,组件省略 successUrl 财务报告和审定财务报表 cancelUrl 从 Strade 请求并期望提供重定向行为 通过条纹支持的参数,例如 return_url。 。 。 .

组件查询

通过组件的公开查询直接访问数据:

import { query } from "./_generated/server";
import { components } from "./_generated/api";

// List subscriptions for a user
export const getUserSubscriptions = query({
  args: {},
  handler: async (ctx) => {
    const identity = await ctx.auth.getUserIdentity();
    if (!identity) return [];

    return await ctx.runQuery(
      components.stripe.public.listSubscriptionsByUserId,
      { userId: identity.subject },
    );
  },
});

// List payments for a user
export const getUserPayments = query({
  args: {},
  handler: async (ctx) => {
    const identity = await ctx.auth.getUserIdentity();
    if (!identity) return [];

    return await ctx.runQuery(components.stripe.public.listPaymentsByUserId, {
      userId: identity.subject,
    });
  },
});

可用的公共查询

查询参数说明
getCustomerstripeCustomerId用花旗身份证明客户
listSubscriptionsstripeCustomerId为客户订阅的列表
listSubscriptionsByUserIduserId用户订阅列表
getSubscriptionstripeSubscriptionId由 ID 订阅
getSubscriptionByOrgIdorgId获取 Org 的订阅
getPaymentstripePaymentIntentId通过身份证明获得付款
listPaymentsstripeCustomerId客户清单付款
listPaymentsByUserIduserId列出用户的付款
listPaymentsByOrgIdorgId列出某矿石的付款
listInvoicesstripeCustomerId列出客户发票
listInvoicesByUserIduserId列出用户发票
listInvoicesByOrgIdorgId列出一矿石的发票

Webhook 事件

该组件自动处理这些 Strade webhook 事件 :

活动行动
customer.created创建客户记录
customer.updated更新客户记录
customer.deleted刷新客户 PII
customer.subscription.created创建订阅记录
customer.subscription.updated更新订阅记录
customer.subscription.deleted将订阅标记为已取消
payment_intent.succeeded创建付款记录
payment_intent.payment_failed更新付款状况
invoice.created创建发票记录
invoice.finalized发票记录
invoice.updated镜像发票元数据更改
invoice.paid预付发票
invoice.payment_failed标记发票失败
checkout.session.completed处理已完成的取出会话

自定义 Webhook 处理器

向 Webhook 事件添加自定义逻辑 :

import { httpRouter } from "convex/server";
import { components } from "./_generated/api";
import { registerRoutes } from "@convex-dev/stripe";
import type Stripe from "stripe";

const http = httpRouter();

registerRoutes(http, components.stripe, {
  events: {
    "customer.subscription.updated": async (ctx, event: Stripe.CustomerSubscriptionUpdatedEvent) => {
      const subscription = event.data.object;
      console.log("Subscription updated:", subscription.id, subscription.status);
      // Add custom logic here
    },
  },
  onEvent: async (ctx, event: Stripe.Event) => {
    // Called for ALL events - useful for logging/analytics
    console.log("Stripe event:", event.type);
  },
});

export default http;

数据库Schema

该组件在其命名空间创建这些表格:

客户

外地类型说明
stripeCustomerId字符串条纹客户身份
email绳子?客户电子邮件
name绳子?客户名称
metadata对象?自定义元数据

订阅

外地类型说明
stripeSubscriptionId字符串字条订阅 ID
stripeCustomerId字符串客户身份
status字符串订阅状态
priceId字符串价格标识
quantity号码?座位数
currentPeriodEnd编号期末时间戳
cancelAtPeriodEnd布尔将在期末取消
userId绳子?链接用户 ID
orgId绳子?链接的 Ong ID
metadata对象?自定义元数据

检查出会话( s)

外地类型说明
stripeCheckoutSessionId字符串退出会话编号
stripeCustomerId绳子?客户身份
status字符串会议状态
mode字符串会话模式(付费/订阅/设置)
metadata对象?自定义元数据

付款

外地类型说明
stripePaymentIntentId字符串付款意向标识
stripeCustomerId绳子?客户身份
amount编号数额(美分)
currency字符串货币代码
status字符串缴款情况
created编号创建时间戳
userId绳子?链接用户 ID
orgId绳子?链接的 Ong ID
metadata对象?自定义元数据

发票

外地类型说明
stripeInvoiceId字符串发票身份证
stripeCustomerId字符串客户身份
stripeSubscriptionId绳子?订阅编号
status字符串发票状况
amountDue编号应付款
amountPaid编号支付金额
created编号创建时间戳
userId绳子?链接用户 ID
orgId绳子?链接的 Ong ID
metadata对象?发票元数据

示例应用

请检查url=值 (帮助) example/ 目录 :

git clone https://github.com/get-convex/convex-stripe
cd convex-stripe
npm install
npm run dev

例子包括:

  • 有产品展示的登陆页面
  • 一次性付款和订阅
  • 有命令历史的用户配置文件
  • 订阅管理(取消,更新席位)
  • 客户门户整合
  • 团队/组织账单

认证

此组件与任何 Convex 认证提供者合作 。 示例使用 办事员数字 :

  1. 在 书记员.com
  2. 添加 VITE_CLERK_PUBLISHABLE_KEY 给您的 .env.local
  3. 创建 convex/auth.config.ts数字 :
export default {
  providers: [
    {
      domain: "https://your-clerk-domain.clerk.accounts.dev",
      applicationID: "convex",
    },
  ],
};

解决问题

退职后表格为空

确保你已经:

  1. 设定 STRIPE_SECRET_KEY 财务报告和审定财务报表 STRIPE_WEBHOOK_SECRET 位于 Convex 环境中 变量
  2. 配置了 Frede 中的 Webhook 端点, 并带有正确的事件
  3. 已添加 invoice.created 财务报告和审定财务报表 invoice.finalized 事件(不仅仅是 invoice.paid(中文(简体) )

“ 未验证” 错误

确保您的认证提供者配置 :

  1. 创建 convex/auth.config.ts 与您的提供者
  2. 运行 npx convex dev 来推动配置
  3. 在调用动作前验证用户签名

Webhooks 返回 400/500

请检查date=中的日期值 (帮助) Convex日志在您的仪表板中查找出错. 共同问题:

  • 失踪 STRIPE_WEBHOOK_SECRET
  • 错误的 Webhook URL( 应该是) https://<deployment>.convex.site/stripe/webhook(中文(简体) )
  • Webhook 配置中缺失的事件

许可证

阿帕奇 - 2.0

版本与发布记录

@convex-dev/stripe 共发布 7 个版本,首次发布于 2025/12/02;过去 12 个月发布了 7 个版本。

版本发布日期距今
0.1.7latest2026/10/101 个月前
0.1.62026/07/114 个月前
0.1.42026/03/137 个月前
0.1.32026/01/179 个月前
0.1.22025/12/2010 个月前
0.1.12025/12/0211 个月前

关于 @convex-dev/stripe 的常见问题

@convex-dev/stripe 是什么?

Convex的条纹组件.

如何安装 @convex-dev/stripe?

在项目目录运行 npm install @convex-dev/stripe,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^18.3.1 || ^19.0.0)、convex(^1.29.3)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@convex-dev/stripe 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@convex-dev/stripe 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@convex-dev/stripe 可以商用吗?

@convex-dev/stripe 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@convex-dev/stripe 的下载量有多少?

根据 npm 官方下载统计,@convex-dev/stripe 在 2026/10/11 – 2026/11/09 这 30 天内被下载 502,616 次,日均约 16,754 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@convex-dev/stripe 还在维护吗?

最新版本 0.1.7 发布于 2026/10/10(1 个月前);至今共发布 7 个版本,其中过去 12 个月发布了 7 个;首次发布于 2025/12/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。