Firebase ExtensionsにStripeでのサブスク支払い機能が登場!
ずっと便利そうだなぁと思ってたけど、やっとさわれたのでその時の備忘録。
Run Subscription Payments with Stripeの拡張機能は、有料プラン(Blaze plan)じゃないと使えないので注意。
公式のデモも公開されている。
まずはサンプルプロジェクトで試してみるところから。 GitHubにサンプルが用意されているので、これを使う。
(サンプル動かす以上のことを書こうと思ったけど、ボリュームが多いので分割...)
(ほぼめぐもっとさんの記事な感じ。記事を読みながら自分用に整理した備忘録版)
1. プロジェクトの準備
1.1. Firebaseプロジェクトの作成
とりあえず、サンプル用のFirebaseプロジェクトを作成し、有料プラン(Blaze)に変更する。
Extensionsを有効にすると、Authentication、Firestore、Functionsを使うため、 それぞれ初期準備を済ませておく 。
(Firestoreとかを準備をしてなかったので、Extensionsの有効化のときにエラーになった。。)
サンプルだとGoogle認証が使えるので、AuthenticationのGoogle認証を有効にしておく。
2. Extensionsの有効化
2.1. Extensionsのインストール
ここのURLから「コンソールでインストール」を押下し、拡張機能を追加する。
拡張機能を追加するFirebaseプロジェクトの選択画面になるので、作成したプロジェクトを選択する。
すると、初期設定の画面に移動する。
1~3は、拡張機能が作成したりするFunctionsなどの説明。
4が設定項目という感じ。
それぞれの項目はこんな感じ。
Cloud Functions deployment location
拡張機能が追加してくれるFunctionのリージョン。
Firestoreで選択したものとかがよい。
Products and pricing plans collection
Stripeで追加した商品などの情報がFirestoreに追加されるときのコレクションIDを設定。
Customer details and subscriptions collection
Stripeの顧客や決済情報がFirestoreに追加するときのコレクションIDを設定。
Sync new users to Stripe customers and Cloud Firestore
いつ、StripeとFirestoreに顧客を追加するかの設定。
"Sync"だとAuthenticationに新しいユーザが追加されたときに追加され、 "Do not sync"だと決済したときに追加される。
Automatically delete Stripe customer objects
Stripeの顧客を自動で削除するかどうかの設定。
"Auto delete"だと、AuthenticationかFirestoreで該当のユーザ/ドキュメントが削除された時、Stripe上の顧客を削除し、さらに該当顧客のすぺてのサブスクリプションをキャンセルしてくれる。
Stripe API key with restricted access
StripeのAPIキーを設定。Stripeの「開発者>API キー」で確認・作成できる。
Firebase用に制限付きキーを作成するのが推奨。
書き込み権限を3つ(Customers/Checkout Sessions/Customer portal)、
読み込み権限を2つ(Subscriptions/Plans)
で作成する。
Stripe webhook secret
Stripeに登録したWebhookの署名シークレットを設定。
インストール後に設定する項目なので、今はそのままでOK。
(初期設定完了後にStripeに登録するwebhookのURLが表示されるため)
2.2. Extensionsの設定
インストールを開始すると、初期設定するので3~5分くらい待つ感じ。
設定が完了すると、こんな感じの画面に移動できるようになるので、
「この拡張機能の動作」から残りの設定を進めていく。
2.2.1. Firestoreのルールを設定
「Set your Cloud Firestore security rules」に書いてあるルールをコピペする。
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /customers/{uid} { allow read: if request.auth.uid == uid; match /checkout_sessions/{id} { allow read, write: if request.auth.uid == uid; } match /subscriptions/{id} { allow read: if request.auth.uid == uid; } } match /products/{id} { allow read: if true; match /prices/{id} { allow read: if true; } match /tax_rates/{id} { allow read: if true; } } } }
2.2.2. StripeのWebhookの設定
Stripeで決済が完了したときになど、Firestoreへ同期するときに必要なため、設定をしていく。
「Configure Stripe webhooks」に書いてあるとおりに進めていけばOK。
Stripe上でのWebhookエンドポイントの追加は「開発者>Webhook」から。
エンドポイントURLと必要な送信イベントは、「Configure Stripe webhooks」に書いてあるとおり。
エンドポイントの追加が完了すると、「署名シークレット」が発行されるので、コピーしておく。
2.2.3. 署名シークレットの設定
拡張機能をインストールするときに、後回しにした「Stripe webhook secret」を設定する。
「この拡張機能の動作」の下にある「拡張機能の構成」の画面から
「拡張機能を再構成」ボタンを押すと編集できる。
「Stripe webhook secret」に先コピーしておいた「署名シークレット」を貼り付けて、保存すればOK。
構成を変更すると、また数分待つ感じ。
2.3. Stripe側の設定
2.3.1. 商品/税率の追加
サンプルを動かす前に、Stripe上に商品や税率を登録しておく必要がある。
「この拡張機能の動作」の「Create product and pricing information」に記載。
商品の登録 ... Stripe上の「商品」から。
税率の登録 ... Stripe上の「商品>税率」から。
登録するとFirestoreに同期されてる。
(productions
は拡張機能で設定したコレクションID)
Firestoreへの同期は商品の追加時などにWebhookを通じて行われるため、
あらかじめ登録しておいた商品は編集しないと追加されないので注意。
2.3.2. 商品のメタデータを設定
「この拡張機能の動作」の「Assign custom claim roles to products」の内容。
商品のメタデータを設定しておくと、商品を購入したときに、カスタムクレームに設定してくれるよう。
カスタムクレームは、Firebase Authのユーザアカウントに独自の属性を追加/設定できる機能。
Admin SDKからしか設定できないが、拡張機能で追加されるFunctions内でよしなにやってくれる。
これを使うと、
- Firestoreのセキュリティルールでのチェックに使えたり
- Client SDK側でどのプランのユーザかを確認できたりする
2.3.2.1. 商品側の設定
こんな感じ。
設定するメタデータのkeyは「firebaseRole」で固定。
2.3.2.2. カスタムクレームの参照
「この拡張機能の動作」の「Assign custom claim roles to products」の内容のまま。
stripeRole
属性に、さっき設定したメタデータがセットされる。
async function getCustomClaimRole() { await firebase.auth().currentUser.getIdToken(true); const decodedToken = await firebase.auth().currentUser.getIdTokenResult(); return decodedToken.claims.stripeRole; }
2.3.3. カスタマーポータルの設定
Stripeでは、顧客が定期支払いのプランや支払い方法を顧客自身が管理できるページを提供してくれている。
デフォルトだとキャンセルもできないようになっているので、設定していく。
「この拡張機能の動作」の「Configure the Stripe customer portal」の内容の通り。
3. サンプルコードを動かしてみる
公式デモのコードがGitHubに上がっているので、動かしてみる。
3.1. サンプルコードのclone
とりあえず、git clone
。
$ git clone git@github.com:stripe-samples/firebase-subscription-payments.git
$ cd firebase-subscription-payments/
3.2. サンプルコードにAPIキーなどの設定
public/javascript/app.js
に配置されてるファイルにAPIキーなどを設定すればOK。
STRIPE_PUBLISHABLE_KEY
- Stripeの「開発者>APIキー」にある公開可能キー
- 標準キーでOK
taxRates
- Stripeの「商品>税率」で追加した税率ID
firebaseConfig
- Firebaseの設定。Firebaseコンソールの設定からWebのマイアプリを追加して表示された内容をコピペ
- functionLocation
- 拡張機能で追加した関数のリージョン。今回は
asia-northeast1
を設定
- 拡張機能で追加した関数のリージョン。今回は
3.3. Firestoreのインデックスを追加
サンプルコードでは、複合インデックスが必要なクエリがあるため、用意しておく。
インデックスはFirebase CLIでも設定できる。
firestore.indexes.json
を作成して、
// firestore.indexes.json { "indexes": [ { "collectionGroup": "prices", "queryScope": "COLLECTION", "fields": [ { "fieldPath": "active", "order": "ASCENDING" }, { "fieldPath": "unit_amount", "order": "ASCENDING" } ] }, ], "fieldOverrides": [] }
Firebase CLIでデプロイ。
$ firebase deploy --only firestore:indexes
インデックスのビルドが完了したらOK
3.4. サンプルコードの起動
// パッケージのインストール $ npm install // Firebaseの設定: 作成したプロジェクトを選択。aliasはdefault $ firebase use -add // 起動 $ npm run dev // => http://localhost:5000
ログインすると、こんな感じで商品の一覧が表示される。
(価格が1円とか2円になってるけど、コードがドルにしか対応してないっぽい)
テスト用のカードが用意されてるので、それを使って購入してみる。
決済画面はこんな感じ。
購入して戻ってみると、プランとカスタムクレームの内容を確認できる。
カスタマーポータルにアクセスすると、今のプランや支払い方法などが確認できる。
とりあえず、サンプルは動いた(´ω`)
つづく...
とりあえず、動いたけど、まだまだわからないところがたくさん。
調べて記事にしようと思ったけど、結構なボリュームになったので、分割に...
あとは、
- Firebase Extensionsの中身
- サンプルコードの中身
- StripeのAPI周りの細かいところ
とかを調べる予定!
参考にしたサイト様
- Firebase Extensions | Run Subscription Payments with Stripe
- 「これは革命」とまでは言わないけれど、Webサービスへのサブスク導入がめちゃめちゃ楽なのでぜひ知って欲しいStripeのFirebase Extensions
- Firebase ExtensionsのRun Subscription Payments with Stripeを使ってサブスク課金をコードを書かずに実装する - Qiita
- functions-samples/stripe at master · firebase/functions-samples
- Firebase による支払い処理
Stripe試してみたシリーズ
- 第一回: サンプルを試す
- 第二回: 拡張機能のドキュメントを読む
- 第三回: 拡張機能のソースを読む
- 第四回: Nuxtアプリで試してみる
- 第五回: 本番運用する前に