テーマ
Stripe 環境変数の配信手順
本ドキュメントは、voting spec (有料投票フロー) が依存する Stripe 関連の環境変数を、ローカル開発環境および本番 (Vercel) に投入するための運用手順を定める。
関連 spec / steering:
/specs/voting/design.mdの「Technology Stack」「Webhook Handler」「Security Considerations」セクション/steering/tech.mdの「デプロイ」セクション
1. 対象環境変数
決済フロー (PaymentIntent 発行 + Stripe Payment Element + Webhook 署名検証) では以下の 3 つの環境変数を使用する。
| 変数名 | 機微度 | 取得元 (Stripe Dashboard) | 配置先 |
|---|---|---|---|
STRIPE_SECRET_KEY | 秘密 (サーバー専用 / 絶対に公開しない) | Developers → API keys → "Secret key" の sk_test_… (テスト) / sk_live_… (本番) | ローカル .env.local / Vercel Environment Variables |
STRIPE_WEBHOOK_SECRET | 秘密 (サーバー専用) | Developers → Webhooks → 該当エンドポイントの "Signing secret" whsec_… (本番) / Stripe CLI stripe listen 起動時に表示される whsec_… (ローカル) | ローカル .env.local / Vercel Environment Variables |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | 公開可 (ブラウザに露出してよい) | Developers → API keys → "Publishable key" の pk_test_… (テスト) / pk_live_… (本番) | ローカル .env.local / Vercel Environment Variables |
NEXT_PUBLIC_プレフィックスは Next.js がクライアントバンドルに展開するための明示的な公開フラグ。Stripe の Publishable key は仕様上クライアントに露出してよい。
機微度の取扱い原則
STRIPE_SECRET_KEY/STRIPE_WEBHOOK_SECRETは Slack / Issue / コミットメッセージ / スクリーンショットに貼らない。.env.localは.gitignore済みであることを毎回確認する (git statusに表示されないこと)。- ローカルの値が漏洩したと疑われたら Stripe Dashboard の Developers → API keys → "Roll key" で即時ローテーションする。
2. ローカル開発環境への投入手順
2.1 Stripe テストキーの取得
- Stripe Dashboard を Test mode に切り替える (右上のトグルが "Test mode" 表示)。
- Developers → API keys を開く。
- "Publishable key" (
pk_test_…) と "Secret key" (sk_test_…) の値をそれぞれコピーする。
2.2 .env.local への記載
リポジトリルートの .env.local (存在しない場合は新規作成) に以下を追記する。
bash
# .env.local
STRIPE_SECRET_KEY="sk_test_xxxxxxxxxxxxxxxxxxxxxxxx"
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_test_xxxxxxxxxxxxxxxxxxxxxxxx"
# STRIPE_WEBHOOK_SECRET は次節で取得する
.env.localはリポジトリの.gitignoreで除外済み。コミット対象に含まれていないことをgit statusで確認すること。
2.3 Webhook secret の取得 (ローカル)
Stripe CLI を用いて、ローカルの Next.js dev server (http://localhost:3000) へ Webhook をフォワードする。CLI の起動メッセージに表示される whsec_… を STRIPE_WEBHOOK_SECRET に設定する。
bash
# Stripe CLI のインストール (未導入の場合)
brew install stripe/stripe-cli/stripe # macOS
# あるいは https://stripe.com/docs/stripe-cli を参照
# ログイン (初回のみ)
stripe login
# ローカル Webhook フォワード
stripe listen --forward-to localhost:3000/api/webhooks/stripe
# 起動時の出力例:
# Ready! Your webhook signing secret is whsec_xxxxxxxxxxxxxxxxxxxxxxxx (^C to quit)表示された whsec_… を .env.local に追加する。
bash
# .env.local (追記)
STRIPE_WEBHOOK_SECRET="whsec_xxxxxxxxxxxxxxxxxxxxxxxx"
stripe listenは起動するたびにwhsec_…が変わる場合があるため、.env.localの値もそのつど更新すること。または--api-keyと組み合わせ、固定の secret を Dashboard 側で発行して使う運用も可。
2.4 ローカルでの疎通確認
Next.js dev server を起動し、別ターミナルで stripe listen を動かした状態で以下を実行する。
bash
# 決済成功イベントを擬似発火
stripe trigger payment_intent.succeeded
# 期待: 200 OK が `app/api/webhooks/stripe/route.ts` から返り、
# `stripe listen` 側に `200 OK` のログが出力されること。3. Vercel 本番環境への投入手順
- Vercel ダッシュボードで対象プロジェクトを開く。
- Project Settings → Environment Variables を開く。
- 以下 3 つを Production / Preview / Development の各環境に対して順次登録する。
STRIPE_SECRET_KEY- Production: 本番用
sk_live_… - Preview / Development: テスト用
sk_test_…
- Production: 本番用
STRIPE_WEBHOOK_SECRET- Production: Stripe Dashboard で作成した本番 Webhook endpoint の
whsec_… - Preview: Preview 用に別エンドポイントを作るか、テスト用 endpoint の
whsec_…
- Production: Stripe Dashboard で作成した本番 Webhook endpoint の
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY- Production:
pk_live_… - Preview / Development:
pk_test_…
- Production:
- 既存のデプロイメントにすぐ反映するには、対象環境で Redeploy を実行する (環境変数はビルド時に注入されるため、追加・更新のたびに再デプロイが必要)。
3.1 本番 Webhook endpoint の作成手順
- Stripe Dashboard (Live mode) → Developers → Webhooks → "Add endpoint"。
- Endpoint URL に
https://<本番ドメイン>/api/webhooks/stripeを指定する。 - 監視するイベントとして以下を選択する:
payment_intent.succeededpayment_intent.payment_failedcharge.refunded
- 作成後の詳細画面の "Signing secret" (
whsec_…) を Vercel のSTRIPE_WEBHOOK_SECRET(Production) に投入する。
Preview デプロイ環境にも Webhook を到達させたい場合は、Preview 用ドメインごとに別 endpoint を作成するか、Preview では Webhook を受け取らない (= Production のみ Webhook を有効化) 運用を選ぶ。
4. 検証手順: Stripe テストキーで PaymentIntent が発行できることの確認
Stripe Secret Key (テスト) を取得した直後に、Node.js から最小の API 呼び出しが成功することを確認する。Production の secret では実行しない。
4.1 ワンライナー (zsh / bash)
リポジトリルートで以下を実行する。
bash
# 事前条件: .env.local に STRIPE_SECRET_KEY="sk_test_..." が設定済み、
# かつ `stripe` パッケージが node_modules にインストール済み
# (voting spec の task 1.1 で導入される `stripe` package)。
node -e '
const Stripe = require("stripe");
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
stripe.paymentIntents.create({ amount: 100, currency: "jpy" })
.then((pi) => {
console.log("id:", pi.id);
console.log("client_secret:", pi.client_secret);
console.log("status:", pi.status);
})
.catch((err) => {
console.error("error:", err.message);
process.exit(1);
});
'
STRIPE_SECRET_KEYが.env.localに置かれているがシェルにロードされていない場合は、set -a; source .env.local; set +a;で一旦シェルに読み込むか、dotenv-cli等でdotenv -e .env.local -- node -e '…'のように実行する。
4.2 期待結果
id:にpi_…形式の ID が出力されることclient_secret:にpi_…_secret_…形式の文字列が出力されることstatus:がrequires_payment_methodであること (PaymentMethod 未指定で作っているため正常)- プロセスが exit code 0 で終了すること
4.3 失敗時の切り分け
| 症状 | 原因の見当 | 対処 |
|---|---|---|
error: Invalid API Key provided | STRIPE_SECRET_KEY が未設定または sk_test_… ではなく pk_… を入れている | Stripe Dashboard で再度コピーし .env.local を修正 |
error: Authentication required | Test mode と Live mode の鍵を取り違えている | Dashboard を Test mode に切り替え、sk_test_… を再取得 |
Cannot find module 'stripe' | stripe パッケージ未インストール (voting task 1.1 未完了) | pnpm install で依存を入れる |
| Network error | プロキシ / ファイアウォール | https://api.stripe.com への HTTPS 接続を確認 |
4.4 検証実施者
本検証は 実 Stripe テストキーへのアクセス権を持つ human operator が実施する。AI エージェントのサンドボックス環境ではテストキーを保持できないため、ここでは手順の文書化のみを行い、実行ログは Issue / PR コメントで共有する運用とする。
5. 環境変数登録チェックリスト
新しい環境 (新規メンバーのローカル環境 / 新しい Vercel プロジェクト) を立ち上げるときの最終確認用。
- [ ] Stripe Dashboard が Test mode (ローカル / Preview) もしくは Live mode (Production) になっていることを確認した
- [ ]
STRIPE_SECRET_KEYを投入した (機微度: 秘密) - [ ]
STRIPE_WEBHOOK_SECRETを投入した (機微度: 秘密、CLI / Dashboard で取得) - [ ]
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYを投入した (機微度: 公開可) - [ ]
.env.localがgit statusに出ないことを確認した (ローカルの場合) - [ ] §4 のワンライナーで
id/client_secretが返ることを確認した - [ ] Vercel の場合、変更後に Redeploy を実行した
- [ ] 本番 Webhook endpoint を Stripe Dashboard に作成した (本番の場合)