料金プラン管理
料金プランは決済システムの中核です。ユーザーが購入できる製品、価格、決済方法、特典を定義します。NEXTY.DEVは、料金プランを管理するための完全な管理インターフェースとAPIを提供します。
料金プランのデータ構造
基本フィールド
{
id: string; // UUID、自動生成
environment: 'test' | 'live'; // 環境:テストまたは本番
cardTitle: string; // カードタイトル
cardDescription?: string; // カード説明
provider: 'stripe' | 'creem' | 'none'; // 決済プロバイダー
isActive: boolean; // 有効化されているか
isHighlighted: boolean; // ハイライトされているか
displayOrder: number; // 表示順序
}決済設定フィールド
Stripe設定
{
stripePriceId?: string; // Stripe Price ID
stripeProductId?: string; // Stripe Product ID
stripeCouponId?: string; // Stripe Coupon ID
enableManualInputCoupon: boolean; // 手動クーポン入力エントリーを有効化
}Creem設定
{
creemProductId?: string; // Creem Product ID
creemDiscountCode?: string; // Creem割引コード
}決済タイプと間隔
{
paymentType: 'one_time' | 'onetime' | 'recurring' | null; // StripeとCreemは異なる定義を持ち、ボイラープレートはプロバイダーの元の定義を保持
recurringInterval: 'month' | 'year' | 'every-month' | 'every-year' | null; // StripeとCreemは異なる定義を持ち、ボイラープレートはプロバイダーの元の定義を保持
}価格情報
{
price?: string; // 実際の価格(数値文字列)
currency?: string; // 通貨コード(例:USD、CNY)
displayPrice?: string; // 表示価格(例:"$10")
originalPrice?: string; // 元の価格(割引表示に使用)
priceSuffix?: string; // 価格サフィックス(例:"month"、"year")
}多言語サポート (langJsonb)
langJsonbは多言語コンテンツを保存するために使用されるJSONBフィールドです:
{
"en": {
"cardTitle": "Pro Plan",
"cardDescription": "Best for professionals",
"displayPrice": "$29",
"priceSuffix": "month",
"buttonText": "Get Started",
"features": [
{ "description": "Feature 1", "included": true },
{ "description": "Feature 2", "included": true }
]
},
"zh": {
"cardTitle": "专业版",
"cardDescription": "适合专业人士",
"displayPrice": "¥199",
"priceSuffix": "月",
"buttonText": "立即开始",
"features": [
{ "description": "功能 1", "included": true },
{ "description": "功能 2", "included": true }
]
}
}特典設定 (benefitsJsonb)
benefitsJsonbは、プランがユーザーに付与する特典、特にクレジットを定義するために使用されます:
{
"oneTimeCredits": 100, // 一回限りのクレジット(一回限りの決済)
"monthlyCredits": 50, // 月額クレジット(サブスクリプション)
"totalMonths": 12 // 総月数(年額サブスクリプション)
}機能リスト (features)
機能リストは、プランに含まれる機能を表示するために使用される配列です:
[
{
"description": "Unlimited projects",
"included": true,
"bold": false
},
{
"description": "Priority support",
"included": true,
"bold": true
},
{
"description": "Advanced analytics",
"included": false,
"bold": false
}
]料金プランの作成
ダッシュボード経由で作成
/dashboard/pricesにアクセス(管理者権限が必要)- 「プランを作成」ボタンをクリック
- プラン情報を入力:
- 基本情報: タイトル、説明、環境
- 決済プロバイダー: Stripe、Creem、またはNoneを選択
- 決済設定: 選択したプロバイダーに応じて対応する設定を入力
- 価格情報: 価格、通貨、表示価格など
- 多言語コンテンツ:
langJsonbフィールドに多言語コンテンツを入力 - 特典設定:
benefitsJsonbでクレジットなどの特典を設定 - 機能リスト: プランに含まれる機能を追加
API経由で作成
createPricingPlanAction関数を使用します:
import { createPricingPlanAction } from '@/actions/prices/admin';
const result = await createPricingPlanAction({
planData: {
environment: 'live',
cardTitle: 'Pro Plan',
provider: 'stripe',
stripePriceId: 'price_xxx',
paymentType: 'recurring',
recurringInterval: 'month',
price: '29.00',
currency: 'USD',
displayPrice: '$29',
priceSuffix: 'month',
isActive: true,
isHighlighted: false,
displayOrder: 1,
langJsonb: {
en: {
cardTitle: 'Pro Plan',
cardDescription: 'Best for professionals',
displayPrice: '$29',
priceSuffix: 'month',
buttonText: 'Get Started',
features: [
{ description: 'Feature 1', included: true }
]
}
},
benefitsJsonb: {
monthlyCredits: 100
},
features: [
{ description: 'Unlimited projects', included: true }
]
},
locale: 'en'
});料金プランの更新
ダッシュボード経由で更新
/dashboard/pricesにアクセス- 更新したいプランをクリック
- プラン情報を変更
- 変更を保存
API経由で更新
updatePricingPlanAction関数を使用します:
import { updatePricingPlanAction } from '@/actions/prices/admin';
const result = await updatePricingPlanAction({
id: 'plan-id',
planData: {
displayPrice: '$39', // 変更が必要なフィールドのみ更新
isHighlighted: true
},
locale: 'en'
});料金プランの削除
ダッシュボード経由で削除
/dashboard/pricesにアクセス- 削除したいプランをクリック
- 削除ボタンをクリック
- 削除を確認
API経由で削除
deletePricingPlanAction関数を使用します:
import { deletePricingPlanAction } from '@/actions/prices/admin';
const result = await deletePricingPlanAction({
id: 'plan-id',
locale: 'en'
});料金プランのクエリ
管理者用:すべてのプランをクエリ
import { getAdminPricingPlans } from '@/actions/prices/admin';
const result = await getAdminPricingPlans();
if (result.success) {
const plans = result.data; // すべてのプラン(非アクティブなものも含む)
}公開用:アクティブなプランをクエリ
import { getPublicPricingPlans } from '@/actions/prices/public';
const result = await getPublicPricingPlans();
if (result.success) {
const plans = result.data; // アクティブなプランのみを返す
}システムは現在の環境(NODE_ENV)に基づいて自動的にフィルタリングします:
- 本番環境:
environment = 'live'のプランを返す - その他の環境:
environment = 'test'のプランを返す
IDで単一プランをクエリ
import { getPricingPlanById } from '@/actions/prices/admin';
const result = await getPricingPlanById('plan-id');
if (result.success) {
const plan = result.data;
}料金プランの表示
Pricingコンポーネントの使用(タイプ別に分類)
Pricing.tsxコンポーネントは、決済タイプに基づいてプランを分類して表示します:
import Pricing from '@/components/home/Pricing';
export default function PricingPage() {
return <Pricing />;
}コンポーネントは自動的に:
- プランを月額サブスクリプション、年額サブスクリプション、一回限りの決済に分類
- Tabsコンポーネントを使用して異なるプランタイプを切り替え
- 現在のロケールに基づいて対応する多言語コンテンツを表示
PricingAllコンポーネントの使用(すべてのプランを表示)
PricingAll.tsxコンポーネントは、すべてのアクティブなプランを一度に表示します:
import PricingAll from '@/components/home/PricingAll';
export default function PricingPage() {
return <PricingAll />;
}カスタムスタイリング
PricingCardDisplayコンポーネントのスタイリングを変更して、ニーズに合わせることもできます。
多言語コンテンツ管理
言語コード
システムは標準的な言語コード(例:en、zh、ja)を使用して異なる言語を識別します。
多言語フィールド
以下のフィールドが多言語をサポートしています:
cardTitlecardDescriptiondisplayPriceoriginalPricepriceSuffixbuttonTexthighlightTextfeatures
多言語フォールバックメカニズム
現在のロケールのコンテンツが存在しない場合、システムは自動的にデフォルト言語(通常はen)にフォールバックします:
const localizedPlan =
plan.langJsonb?.[currentLocale] ||
plan.langJsonb?.[DEFAULT_LOCALE] ||
{};特典設定のベストプラクティス
一回限りの決済特典
{
"oneTimeCredits": 100
}一回限りのプランを購入後、ユーザーはすぐに100クレジットを受け取ります。
月額サブスクリプション特典
{
"monthlyCredits": 50
}月額プランをサブスクライブ後:
- すぐに50クレジットを受け取る
- 毎月の更新時に50クレジットにリセット
年額サブスクリプション特典
{
"monthlyCredits": 50,
"totalMonths": 12
}年額プランをサブスクライブ後:
- すぐに50クレジットを受け取る
- その後の毎月50クレジットを受け取る
- 12か月にわたって配分
決済プロバイダーの設定
Stripe設定手順
- StripeダッシュボードでProductを作成
- Priceを作成(一回限りまたはサブスクリプションを選択)
- Price IDをコピー
- 料金プランの
stripePriceIdに入力
Creem設定手順
- CreemダッシュボードでProductを作成
- Product IDをコピー
- 料金プランの
creemProductIdに入力
クーポン設定
Stripeクーポン
- StripeダッシュボードでCouponを作成
- 料金プランで作成したCouponを選択、手動で入力する必要はありません
- Stripe料金の場合、デフォルトのCouponが設定されている場合、手動でのクーポン変更は許可されません。
enableManualInputCouponフィールドを通じて手動クーポン入力エントリーを有効化できます
Creem割引コード
- CreemダッシュボードでDiscount Codeを作成
creemDiscountCodeフィールドに入力
よくある質問
Q: 無料プランはどのように作成しますか?
A: provider = 'none'を設定します。これにより、プランは表示されますが、決済プロセスはトリガーされません。buttonLinkフィールドを使用して、ユーザーを機能使用ページに誘導するカスタムリンクを設定できます。
Q: プランを非表示にするにはどうすればよいですか?
A: isActive = falseを設定します。プランは公開APIで返されず、料金ページにも表示されません。
Q: プランの表示順序を調整するにはどうすればよいですか?
A: displayOrderフィールドを変更します。数値が小さいほど、表示順序で上位に表示されます。