🎉

誰も教えてくれなかったFlutterでのサブスク課金について 「正しい有効期限がちゃんと欲しい!」

2021/11/01に公開

色々Flutterドキュメント漁りまくって、「いやそういうことやったんかーい」みたいなのをまとめる
本当になんかここを知りたい!というのを書いてくれているのが少なくて(というかなかったから自分で実験した)困った

どんな状況でも正しいサブスクの有効期限を表示させる

理系な私としては曖昧な感じが基本的に嫌い、、なんか猶予期限を多めにして、誤魔化す的なのは最終手段として、とりあえずちゃんと有効期限を確保したい。

前提

まずレシートの検証について
私は、

  1. 生のレシートをデータベース(Firestore)にぶち込む
  2. cloud functionsで検証する
  3. 有効期限をアップデートする

という方法でやっている

ここで問題になってくるのが「どうやって正しい有効期限を見つけけてくるか?」ということである
上のだと、ユーザーが定期的にアプリを起動してくれさえいれば問題は起きない。アプリを開くたび、レシートは最新になり1~3が動くからだ

しかし!!
アプリが2ヶ月間開かなかったら?
アプリで課金したけど、アプリを開かずとも他で機能が使えたりするサービスはたくさんあるだろう(NetFlix契約してるけどTVでしか見ないし)

よくある解決策とそこの疑問

とりあえずこの記事最高
https://zenn.dev/hirokt/articles/b3dbc2824800456743d5
ここで有効期限の最新化は

  • ストアのサーバー通知機能を利用する
  • 定期的にユーザーのサブスク期限を確認する

の2パターンが書かれており、まあこれ以外に方法はない(詳しくは記事を読んでね)
まず、"ストアのサーバー通知機能を利用する"方法についてAndroidは安定しているけれど、iOSの方は微妙というのが別のドキュメントで書かれていた。結局、定期的に期限を確認しないとね、っていう。

そこまではいいんや!!
"どうやってサブスク期限を確認する?"がFlutterがちんぷんかんぷんだった。みんなこれだけで理解できるんかな?全然書いてくれてる記事がない。
そもそもどうやってユーザーの手にある最新のレシートを取得するん?なんかAppleとかサーバーに問い合わせるのか?とか調べまくったけど結論は意外...

最新の有効期限の確認方法

古いレシートを使えばいいんや!!!
ああ、、そうなのか。いや、てか、まあ最初にそう思って試したけどできなくて(理由は別にあった)、、なんで?って思って沼にハマったわけなんやけど。
とりあえず古いレシートを使うこと。
これのみ。

Android これは簡単

Androidは簡単で、ドキュメント通り生のレシートを取得したら検証なりなんなりして、普通に最新の有効期限を出してくれる。
ただし、一度終了したサブスクのレシートだと、次に開始したサブスクの有効期限を見せてくれないっぽいんよね。たぶん。
Play Storeから新たにサブスク契約したままアプリを開かない人がいたら検知のしようがない、、?もうちょっと検証が必要かも

iOS これが困らせた

iOSが曲者で、普通にドキュメント通り書くと、ダメっぽい

// これがダメな方
purchaseDetails.verificationData.localVerificationData
// 追記:バージョンアップで書き方変わったっぽいからそっち参照
final PurchaseVerificationData verificationData =
      await InAppPurchaseConnection.instance
          .refreshPurchaseVerificationData();
// これがいけてる方
verificationData.localVerificationData

このレシートが最強で、こいつがどんな古くても、最新の有効期限を取得してくれる(Androidだと一度終了したサブスクのレシートダメだったけど、このiOSのはそんなの関係なしで"サブスクの今の最新の有効期限"をちゃんと出してくれる)
ちなみに、iOSだとサブスクが終了して、purchaseResponse.pastPurchasesを回すと大量のレシートの残りカスみたいなのが出てきちゃうけど、これは使わなくていい。サブスクのみ使ってるなら、上記のレシート1枚でOK

というわけであとは簡単

要は古いレシート使えってこと!これさえ書いてくれてたらどんなに助かったことか。
あとは定期的にレシートを検証するように書けばOK
Firebase functionsとGCPのスケジューラーだけでいける

Discussion