mcpField
C
convex-billing

convex-billing

github.com/get-convex開発6931.2k 回インストール1 日前に更新
リポジトリ

convex-billing について

convex-billing は、@convex-dev/stripe を使って Convex アプリに Stripe 決済を追加するスキルです。チェックアウト、署名検証付き Webhook、保存されたサブスクリプション状態、サーバー側のアクセス判定を設定できます。

主な機能

  1. 01Stripe コンポーネントの導入と設定
  2. 02サブスクリプション用チェックアウトアクション
  3. 03署名検証付き Webhook の登録
  4. 04コンポーネントテーブルへの状態保存
  5. 05サーバー側クエリによるアクセス制御

活用シーン

  1. 01Convex アプリへの Stripe サブスクリプション追加
  2. 02チェックアウトとサブスクリプションの Webhook 処理
  3. 03サブスクリプション状態に応じたサーバー側機能制限

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/get-convex/agent-skills --skill convex-billing

インストール後、Claude Code で/convex-billingを入力して読み込まれたか確認します。

詳細

請求と決済を追加する

@convex-dev/stripe を使って Stripe を Convex に接続します。チェックアウトアクション、コンポーネントによって登録される httpAction Webhook(署名は自動的に検証されます)、コンポーネントのテーブルに保存されるサブスクリプションの状態、クエリによるサーバー側のアクセス制御を設定します。

ワークフロー

  1. コンポーネントをインストールします:npm install @convex-dev/stripe。
  2. 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 キーを Convex の env に保存します(env マイクロパワーを使用します):STRIPE_SECRET_KEY(sk_test_… / sk_live_…)と STRIPE_WEBHOOK_SECRET(whsec_…)。
  4. Webhook ルートを登録するために convex/http.ts を作成します(署名検証はコンポーネントが自動的に処理します):
    import { httpRouter } from 'convex/server';
    import { components } from './_generated/api';
    import { registerRoutes } from '@convex-dev/stripe';
    const http = httpRouter();
    registerRoutes(http, components.stripe, { webhookPath: '/stripe/webhook' });
    export default http;
    
  5. チェックアウトアクションとサブスクリプションを確認するクエリを含む convex/billing.ts を作成します:
    import { action, query } 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, {});
    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');
        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: 'subscription', successUrl: `${process.env.SITE_URL ?? 'http://localhost:3000'}/?success=true`, cancelUrl: `${process.env.SITE_URL ?? 'http://localhost:3000'}/?canceled=true`, subscriptionMetadata: { userId: identity.subject } });
      },
    });
    export const isSubscribed = query({
      args: {},
      returns: v.boolean(),
      handler: async (ctx) => {
        const identity = await ctx.auth.getUserIdentity();
        if (!identity) return false;
        const subscriptions = await ctx.runQuery(components.stripe.public.listSubscriptionsByUserId, { userId: identity.subject });
        return subscriptions.some((sub) => sub.status === 'active' || sub.status === 'trialing');
      },
    });
    
  6. npx convex dev --once を実行します。コンポーネントがインストールされ、関数がプッシュされます。出力に ✔ Installed component stripe. と表示されることを確認します。
  7. Stripe Dashboard → Webhooks で、エンドポイント https://<deployment>.convex.site/stripe/webhook を追加し、checkout.session.completed、customer.subscription.*、invoice.*、payment_intent.* を登録します。署名シークレットをコピーし、STRIPE_WEBHOOK_SECRET に設定します。

ルール

  • @convex-dev/stripe(npm: @convex-dev/stripe@^0.1.4)を使用してください。registerRoutes を介して Webhook の署名検証を内部で処理するため、独自の constructEvent Webhook は作成しないでください。
  • Stripe キーは Convex の env に保存します(env マイクロパワーを使用します):STRIPE_SECRET_KEY と STRIPE_WEBHOOK_SECRET。
  • クライアント側の申告ではなく、サーバーに保存されたサブスクリプションの状態を isSubscribed クエリ(コンポーネントのテーブルを読み取ります)で確認し、アクセスを制御します。
  • convex/convex.config.ts では '@convex-dev/stripe/convex.config.js' からインポートする必要があります(.ts ではありません)。Convex バンドラーで .js 拡張子が必要です。

コメント