polar-better-auth について
認証フローに Polar の決済とサブスクリプションを組み込む Better Auth プラグインです。課金機能を実装する開発者向けに、チェックアウト、利用量、ポータル、Webhook を提供し、ユーザーや組織との関連付けにも対応します。
主な機能
- 01登録時に Polar 顧客を自動作成
- 02ユーザー削除時に顧客も削除
- 03チェックアウトと顧客ポータルのプラグイン
- 04利用イベントの送信とメーター照会
- 05Polar の Webhook イベント処理
活用シーン
- 01新規登録者の Polar 顧客作成
- 02クライアントから商品購入を開始
- 03利用量の報告と残高の確認
- 04組織サブスクリプションによるアクセス確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tuzzy08/ skills --skill polar-better-authインストール後、Claude Code で/polar-better-authを入力して読み込まれたか確認します。
詳細
Polar + Better Auth の統合
認証フローに Polar の決済とサブスクリプションを統合するための Better Auth プラグインです。
Note: 完全なドキュメントのインデックスは、こちらから取得できます:
https://polar.sh/docs/llms.txt
機能
- 顧客の自動作成:サインアップしたユーザーを Polar の顧客と同期します。
- 削除の同期:ユーザーが削除されると、Polar の顧客も削除します。
- 参照システム:購入を組織やユーザーに関連付けます。
- プラグイン:チェックアウト、使用量(課金)、Webhook、顧客ポータル。
インストール
npm install better-auth @polar-sh/better-auth @polar-sh/sdk
# or
yarn add better-auth @polar-sh/better-auth @polar-sh/sdk
# or
pnpm add better-auth @polar-sh/better-auth @polar-sh/sdk
サーバーの設定
Polar クライアントを初期化し、Better Auth の設定にプラグインを追加します。
環境変数
POLAR_ACCESS_TOKEN=polar_oat_...
POLAR_WEBHOOK_SECRET=...
サーバーの完全なセットアップ
import { betterAuth } from "better-auth";
import {
polar,
checkout,
portal,
usage,
webhooks,
} from "@polar-sh/better-auth";
import { Polar } from "@polar-sh/sdk";
const polarClient = new Polar({
accessToken: process.env.POLAR_ACCESS_TOKEN,
server: "sandbox", // Use 'sandbox' for testing, defaults to 'production'
});
const auth = betterAuth({
plugins: [
polar({
client: polarClient,
createCustomerOnSignUp: true, // Auto-create Polar customer
// Optional: Custom metadata for new customers
getCustomerCreateParams: ({ user }, request) => ({
metadata: { source: "better-auth" },
}),
use: [
// 1. Checkout Plugin
checkout({
products: [{ productId: "prod_123", slug: "pro" }],
successUrl: "/success?checkout_id={CHECKOUT_ID}",
authenticatedUsersOnly: true,
returnUrl: "https://myapp.com",
theme: "dark", // 'light' or 'dark'
}),
// 2. Customer Portal Plugin
portal({
returnUrl: "https://myapp.com",
}),
// 3. Usage Billing Plugin
usage(),
// 4. Webhooks Plugin
webhooks({
secret: process.env.POLAR_WEBHOOK_SECRET,
onOrderPaid: (payload) => console.log("💸 Order Paid:", payload),
onCustomerStateChanged: (payload) =>
console.log("👤 State Changed:", payload),
onPayload: (payload) => console.log("📨 Other Event:", payload),
}),
],
}),
],
});
サーバーオプション一覧
| オプション | 型 | 説明 |
|---|---|---|
client | Polar | 必須。 Polar SDK のインスタンスです。 |
createCustomerOnSignUp | boolean | サインアップ時に Polar の顧客を自動作成します。 |
use | Plugin[] | サブプラグイン(チェックアウト、ポータル、使用量、Webhook)の配列です。 |
getCustomerCreateParams | Function | 操作に必要なメタデータ/パラメーターを返します。 |
クライアントの設定
import { createAuthClient } from "better-auth/react";
import { polarClient } from "@polar-sh/better-auth";
export const authClient = createAuthClient({
plugins: [polarClient()],
});
プラグインの概要
1. チェックアウトプラグイン
クライアントからチェックアウトセッションを直接作成できるようにします。
設定:
products:{ productId, slug }の配列です。スラッグで商品を参照できます。successUrl:決済後のリダイレクト先 URL です。{CHECKOUT_ID}に対応しています。authenticatedUsersOnly:trueにすると、チェックアウト前にユーザーのログインを必須にします。returnUrl:チェックアウト画面の戻るボタンの URL です。theme:lightまたはdarkです。
クライアントでの使用方法:
await authClient.checkout({
// Option A: Use slug defined in config
slug: "pro",
// Option B: Use direct Product ID
products: ["prod_123"],
// Optional: Link to an Organization (B2B)
referenceId: "org_123",
});
2. 使用量プラグイン(課金)
使用量ベースの課金におけるイベントの取り込みとメーターの取得を処理します。
クライアントでの使用方法:
A. イベントを取り込む:
await authClient.usage.ingestion({
event: "ai_generation", // Must match Meter definition in Dashboard
metadata: {
tokens: 156,
model: "gpt-4",
},
});
注:イベントは認証済みのユーザーに自動的に関連付けられます。
B. メーターを一覧表示する:
const { data: meters } = await authClient.usage.meters.list({
query: { page: 1, limit: 10 },
});
// Returns: consumed units, credited units, current balance
3. ポータルプラグイン
ホストされた顧客ポータルへの顧客のアクセスを管理します。
クライアントでの使用方法:
A. ポータルを開く:
// Redirects user to Polar Customer Portal
await authClient.customer.portal();
B. 顧客の状態を取得する: 有効なサブスクリプション、付与された特典、メーター残高を返します。
const { data: state } = await authClient.customer.state();
C. リソースを一覧表示する:
// List Active Subscriptions
const { data: subs } = await authClient.customer.subscriptions.list({
query: { active: true },
});
// List Orders (Purchases)
const { data: orders } = await authClient.customer.orders.list();
// List Benefits
const { data: benefits } = await authClient.customer.benefits.list();
4. Webhook プラグイン
webhooks プラグインは、Polar 組織からの受信イベントを取得します。
セットアップ手順:
- エンドポイントを設定する: Polar ダッシュボード > Webhooks に移動し、エンドポイントを
/api/auth/polar/webhooksに設定します。 - シークレットを設定する: 環境変数に
POLAR_WEBHOOK_SECRETを追加します。 - プラグインを追加する:
import { polar, webhooks } from "@polar-sh/better-auth";
const auth = betterAuth({
plugins: [
polar({
client: polarClient,
use: [
webhooks({
secret: process.env.POLAR_WEBHOOK_SECRET,
// Handlers
onCustomerStateChanged: (payload) => {
console.log("Customer state changed:", payload);
},
onOrderPaid: (payload) => {
console.log("Order paid:", payload);
},
// ... over 25+ handlers available
onPayload: (payload) => {
console.log("Catch-all event:", payload);
},
}),
],
}),
],
});
対応イベント:
onPayload(すべてのイベント)onCheckoutCreated、onCheckoutUpdatedonOrderCreated、onOrderPaid、onOrderRefundedonRefundCreated、onRefundUpdatedonSubscriptionCreated、onSubscriptionUpdatedonSubscriptionActive、onSubscriptionCanceled、onSubscriptionRevokedonProductCreated、onProductUpdatedonCustomerCreated、onCustomerUpdated、onCustomerDeleted、onCustomerStateChangedonBenefitCreated、onBenefitGrantCreated、onBenefitGrantRevoked
一般的なワークフロー
顧客の削除を同期する
データベースでユーザーが削除されたときに、Polar の顧客も削除するには:
const auth = betterAuth({
user: {
deleteUser: {
enabled: true,
afterDelete: async (user) => {
await polarClient.customers.deleteExternal({
externalId: user.id,
});
},
},
},
});
組織へのアクセスを確認する
組織のサブスクリプション(B2B)を通じてユーザーがアクセス権を持つかどうかを確認します:
const orgId = (await authClient.organization.list())?.data?.[0]?.id;
const { data: orders } = await authClient.customer.orders.list({
query: {
active: true,
referenceId: orgId, // Filter by Org ID
},
});
const hasAccess = orders.length > 0;