はじめに

Stripe & Firebase によるサブスクリプションを試した際のメモ。

TL;DR

この記事が参考になった方
ここここからチャージや購入してくれると嬉しいです(ブログ主へのプレゼントではなく、ご自身へのチャージ)
欲しいもの / Wish list

目次

  1. はじめに
  2. TL;DR
  3. 環境・条件
  4. 詳細
    1. Firebase Extension の導入
    2. Tips
      1. 購読状況の確認
      2. 定期購読のキャンセル
  5. まとめ
  6. その他・メモ
    1. 単発購入について
    2. 決済システムの導入にあたって
  7. 参考文献

環境・条件

1
2
3
4
5
6
7
8
9
10
11
12
13
$ sw_vers
ProductName: macOS
ProductVersion: 11.1
BuildVersion: 20C69

$ node -v
v12.7.0

$ npm -v
6.14.5

$ firebase --version
9.1.0

詳細

Firebase Extension の導入

Stripe が公式提供している Firebase Extension があるのでそれを使う。

上記 Extension 中にも手順が書かれているが、以下の Qiita 記事をベースに作業するのがおすすめ。


Qiita 記事と似たような内容になるが、ざっくりやったこと概要。

  • Stripe アカウント作成
  • Firebase プロジェクト作成
  • Firebase Extensions インストール
  • Firebase Authentication 初期化
  • Firebase Firestore 初期化
  • Firestore ルール変更
    • インストールした Extensions からコピペする
  • Stripe extension の webhook 設定
    • Stripe extension から webhook endpoint URL をコピー
    • Stripe の webhook ページでエンドポイント追加
    • 発行された secret を Stripe extension 側に設定
  • 拡張機能の再構成
    • 数分かかるので待つ。待たずに Stripe の商品作成とかやると反映されないので注意
  • Stripe カスタマーポータル
    • 設定 → カスタマーポータル → リンク → 利用規約/プライバシーポリシー
  • Stripe 税率設定
    • 税率ID をコピーしていおく
  • Stripe 商品設定
  • Firebase アプリ追加
  • GitHub のサンプルコード をセットアップ
    • DL(git clone git@github.com:stripe-samples/firebase-subscription-payments.git)
    • public/javascript/app.js を変更
      • STRIPE_PUBLISHABLE_KEY
      • taxRates
      • firebaseConfig
      • functionLocation
  • サンプル実行
    • ローカル: firebase serve --project <your-project-id>
    • デプロイ: firebase use --add してから firebase deploy

Tips

ここからは Firebase ExtensionsのRun Subscription Payments with Stripeを使ってサブスク課金をコードを書かずに実装する - Qiita に出てこない話を中心に記述。

購読状況の確認

何らかのプロダクトに Stripe & Firebase によるサブスクを導入したとして、ユーザーが現在サブスク購読中かどうかを確認したい場合の話。
(購読停止したユーザーには機能制限するなど)


Firebase ExtensionsのRun Subscription Payments with Stripeを使ってサブスク課金をコードを書かずに実装する - Qiita にも書かれている通り、購読状況は Firestore に格納される。

具体的には customers/xxxx/subscriptions/sub_yyyy に格納される。


基本的には current_period_endstatus だけ見れば良い(はず)。

1
2
status === 'active' &&
now <= current_period_end

上記をクエリできるように複合インデックスを作成しておく。(インデックス作成してないとエラーになる)

なお オレンジ枠内に書いてある通り、インデックスが必要なクエリを実行すると「このリンクでインデックス作ってね」と言われるので、そこから作る感じでも良いと思う。

1
2
3
4
5
6
7
app.firestore()
.collection(/**/)
.where(/**/)
.where(/**/)
.get();
// (node:89915) UnhandledPromiseRejectionWarning: FirebaseError: The query requires an index.
// You can create it here: https://console.firebase.google.com/v1/r/project/xxxx/firestore/indexes?create_composite=xxxx

Node.js のコンソールで簡単に確認した。
参考: Firebase を JavaScript プロジェクトに追加する

まずは Firebase client SDK をインストール。

1
$ npm i firebase

以下、サンプルコード。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
const firebase = require("firebase/app");
require("firebase/auth");
require("firebase/firestore");
const firebaseConfig = {
apiKey: "...",
authDomain: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "..."
};
const firebaseApp = firebase.initializeApp(firebaseConfig);

// email, password で認証(他認証を使っている場合は適切なものを使用)
const email = 'customer1@example.com'
const password = 'hogehoge'
firebaseApp.auth().signInWithEmailAndPassword(email, password);

// 認証済みユーザー
// (REPL 上に一気にコピペすると、↑の認証完了前に currentUser を取得しようとして null になるので注意)
const user = firebaseApp.auth().currentUser;

// status, current_period_end で購読状況を確認
// (見やすいように改行しているが、REPL だと1行にしないとダメ)
firebaseApp.firestore()
.collection(`/customers/${user.uid}/subscriptions`)
.where('status', '==', 'active')
.where('current_period_end', '>', new Date())
.get()
.then(qs => {
const isValid = !qs.empty;
console.log({
isValid,
qsSize: qs.size,
qsEmpty: qs.empty,
});
// => {
// isValid: true,
// qsSize: 1,
// qsEmpty: false
// }
});

個人的には Firebase の API Reference 分かりづらい(探しづらい)と思うので、リンク貼りつつ概要解説。


定期購読のキャンセル

参考: Integrating the customer portal


Stripe のデフォルト設定のまま試すと、利用者(サブスク購読者)側からサブスクのキャンセルができない(はず)。


Stripe のダッシュボードで「設定」→「Billing」→「カスタマーポータル」にアクセスし、


「定期支払いをキャンセル」を有効にすると、カスタマーポータルからキャンセルできるようになる。


有効化後はカスタマーポータル上に「プランをキャンセル」ボタンが出てくる。


キャンセルすると Firestore の cancel_at, canceled_at などに反映される。


キャンセル後、カスタマーポータルには「プランを更新」ボタンが出てくる。


「プランを更新」すると、Firestore の cancel_at, canceled_at などがクリアされる。(画像略)


他にも色々と細かい設定ができるので、詳細は公式ドキュメント参照。(英語だけど)

まとめ

その他・メモ

単発購入について

別記事で試した。

決済システムの導入にあたって

以下も合わせて要確認

参考文献

関連記事

この記事が参考になった方
ここここからチャージや購入してくれると嬉しいです(ブログ主へのプレゼントではなく、ご自身へのチャージ)
欲しいもの / Wish list