Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React Native でアプリ内課金の実装をする

React Native でアプリ内課金の実装をする

以下のイベントに登壇した際の資料になります。
https://standfm.connpass.com/event/218812/

YUJI TSUBURAYA

July 28, 2021
Tweet

More Decks by YUJI TSUBURAYA

Other Decks in Technology

Transcript

  1. React Native でアプリ内課金の実装をする

    1
    株式会社 J-CAT CXO 円谷(@___35d)


    View full-size slide

  2. 2 / 17
    仕事

    ・J-CAT という会社を 2019年12月に共同創業

    ・普段は会社の経営をしたり、Nuxt.js を書いたりしてる

    ・実業務では React 書いてなくて、あんまりキャッチアップできてないのが悩み

    ・その前は BizReach という会社に所属

    ・このときは React Native 書いてた(v0.48 - v0.52 らへんの時代)

    ・flowtype だった 懐かしい


    プライベート

    ・Splatoon というゲームをよくやってる(All X)

    ・Notion 発信活動(Twitter / YouTube / note)

    ・Fast Notion というアプリの個人開発 👈 今日の話

    自己紹介 - 円谷 雄二

    はじめに


    View full-size slide

  3. 3 / 17
    今日話す内容 -> Fast Notion 課金部分の実装について

    ・半年前はあまり(日本語では)知見がなさげだった

    ・今回の発表が知見の一部になればなと思ってます -> 今後実装する人の参考になれば

    ・ついでに、個人開発者ならではのところ話せたら面白いかなと思います

    ・(企業だとコンプラに引っかかりそうなところ)実装周り なるべくコード晒す

    ・どこで審査落ちたかとか

    ・(ほか聞きたいこともしあれば、コメントとか Twitter とかで投げておいてもらえると喜びます!)


    󰢃 きょうは話さないこと

    ・Expo Eject の細かい手順・ハマりポイント

    ・課金ロジックの細部

    ・In App Purchase ライブラリ API の網羅的解説

    はじめに


    View full-size slide

  4. 4 / 17
    ・Expo / React Native 製 

    ・現在は一人で開発

    ・2020年4月βリリース、約1.5年くらい運用

    ・iOS / Android 版両方ある

    ・合計 25,000 インストールくらい

    Fast Notion というアプリについて

    個人開発しているアプリについて

    けんすう砲👇

    スワン砲👇

    平岡砲👇


    View full-size slide

  5. 5 / 17
    ・割と普通な構成です。(一人でやる工夫はいろいろしているが)特に声を大にして言及するところはないかも…

    ・クライアント: React Native / Expo / TypeScript / Jest / Sentry

    ・バックエンド: Python / GCP / Node.js ( Firebase Functions / Express / TypeScript)

    Fast Notion の技術スタック

    個人開発しているアプリについて

    Client

    API Server 1

    Notion API

    API Server 2


    View full-size slide

  6. 6 / 17
    1. 広告(Admob とか)

    2. アカウント作って継続するのに課金しつづける系(Netflix とか)

    3. アプリ購入時課金(買い切り ダウンロードするのにお金かかるやつ)

    4. InAppPurchase(Apple / Google の課金システム使うやつ)

    - 都度買うやつ(ガチャ回すための石とかそういうやつ)

    - 月 / 年ごとに支払うやつ サブスク 👈 今日はこれの話


    (InAppPurchase 余談)

    ・Apple の課金システム使わないとレビュー通らなかったりする

    ・あと手数料高いよね(Apple 30%)

    ・なんとかならんかなあ…

    (前提知識)一般的なアプリのマネタイズ手法いろいろ

    個人開発しているアプリについて

    HEY の 件で Apple と DHH がケンカしてたり、

    Epic Games が Apple のこと訴えてたり(裁判中)

    View full-size slide

  7. 7 / 17
    ・前置き長くなっちゃったけど、このへんから実装の話

    ・基本は無料

    ・サブスク期間中は +α で全ての機能が開放される

    ・アプリ内では ProPlan という名称

    ・ProPlan になっていると、

    ・DB 連携・履歴保存・登録ページ数上限解除 ...等

    ・useIsProPlan 的な感じで画面ごとに機能出し分け

    Fast Notion におけるサブスク課金

    個人開発しているアプリについて

    アプリ内に保存している真偽値を返却 

    Pro Plan になっていない状態(左)、サブスク課金画面(右)

    View full-size slide

  8. 8 / 17
    ・ネイティブ実装が入るので、スクラッチで実装するのはキツい -> ライブラリ導入がオススメ

    ・比較表を作ってみた

    ・素の RN だったら react-native-iap 一択。 Expo Bare Workflow だったら expo-in-app-purchase も可

    ・自分は expo-in-app-purchase を採用(expo 使ってたので信頼してた)

    課金を実現するライブラリ比較

    In App Purchase の実装


    View full-size slide

  9. 9 / 17
    ・ネイティブ実装を TS で薄くラップしてる

    ・良いところ -> 安心と信頼の Expo ドキュメント(読みやすい・厚い)

    ・react-native-unimodules に依存(ネイティブ層とのブリッジング部分は Expo 製の共通モジュール)


    expo-in-app-purchase について

    In App Purchase の実装


    View full-size slide

  10. 10 / 17
    1. サブスクの支払いができる(1ヶ月プランと1年プランがある)

    2. サブスク期間内は ProPlan になり全ての機能が開放される

    3. 期間外は通常プランに戻る

    - 期間外の判定はそこまでシビアでなくても良い

    -> 1秒でも過ぎたら使えない、とかにはしていない

    -> 適当なタイミングで、Apple のサーバーからサブスク状態を取得する

    4. Restore できる(Restore については詳しく後ほど説明します)


    󰡇 それぞれの実装について ざっくりコード付きで解説 していきます

    (時間の関係上、Apple に寄せて解説しています)


    実装した要件の言語化(似た要件でアプリ作る人の参考に)

    個人開発しているアプリについて


    View full-size slide

  11. 11 / 17
    ・2021/07/28 現在、Expo 内で唯一の bare workflow でしか使えないモジュールっぽい

    (ちょっと前まではもうちょっとあった気がするが)


    ・bare workflow 化 するために Eject

    $ expo eject 

    ・もろもろ選択肢が出るので答えていくと eject 完了


    ・ライブラリのインストール 

    $ yarn add expo-in-app-purchase

    $ cd ios & pod install

    (実装 1/6)expo-in-app-purchase インストール

    In App Purchase の実装

    https://docs.expo.io/bare/unimodules-full-list/?redirected#only-available-in-the-bare-workflow-currently


    View full-size slide

  12. 12 / 17
    商品データの作成(App Store Connect)

    ・製品のタイプが選べるので、「自動更新サブスクリプション」を選択(価格・期間を決める)

    ・この製品 ID を実装時に使用


    購入時のイベントリスナー登録

    ・購入フローが完了したとき用のイベントリスナーをあらかじめ登録
    setPurchaseListener(() => {});

    ・Fast Notion ではコールバック内で ProPlan のフラグを立ててる


    (実装 2/6)商品データの作成・購入時のイベントリスナー登録

    In App Purchase の実装


    View full-size slide

  13. 13 / 17
    ・どの商品をユーザーに購入してもらうかの UI 作成に必要

    ・getProductsAsync で商品データを取得

    ・商品データの情報をもとに、価格を表示

    ・貨幣コードも同時に返ってくるので、きちんと表示してやる

    ・ここが雑でハードコーディングしてたら審査落ちた

    ・(ちゃんとローカライズしろと怒られた)







    (実装 3/6)商品データの取得・表示

    In App Purchase の実装


    View full-size slide

  14. 14 / 17
    ・await purchaseItemAsync(productId); で購入できる

    ・購入する前に、以下の2つの関数を事前に実行しておく必要があるので注意

    ・await connectAsync(); 初期化処理

    ・await getProductsAsync([productId]); 製品情報の取得処理

    ・購入処理が完了すると、実装2 で紹介した setPurchaseListener(({ responseCode, results }) => {}); が発火する

    ・-> 購入に成功した場合、このタイミングで ProPlan のフラグを立てている





    (実装 4/6)購入処理

    In App Purchase の実装


    View full-size slide

  15. 15 / 17
    アプリ起動時にサブスク状態の確認をしてる(けっこう仕様が複雑…
    😢 )

    1. const { results } = await getPurchaseHistoryAsync(); で購入履歴を取得

    2. 購入履歴をもとに、Apple のレシート検証用サーバーにリクエスト投げる

    - payload には、購入履歴から取得したレシート情報と、「共有シークレット」を詰める

    - キーの名前が password はちょっと罠

    3. レスポンスにサブスクの有効期限が

    詰まっているので、現在時刻と比較

    4. 比較結果によって、ProPlan フラグを変更



    (実装 5/6)サブスク課金状態の確認

    In App Purchase の実装

    AppStoreConnect から共有シークレット取得

    View full-size slide

  16. 16 / 17
    ・Restore (購入復元) / すでに購入した人に対しての機能
    ・別端末で Fast Notion をインストールした場合にも ProPlan に戻せる
    ・「Restore 機能どこにあるの?」と Apple 様に怒られて審査落ち
    ・処理内容自体は 実装5「課金状態の確認」とほぼ同じ
    ・これで一通り実装の解説 Done
    (実装 6/6)Restore (購入復元)機能

    In App Purchase の実装


    View full-size slide

  17. 17 / 17
    ライブラリに関して

    ・導入するのがオススメ(react-native-iap or expo-in-app-purchase)

    ・ライブラリを使うとネイティブ実装不要。TS only で実装できて開発体験良い


    導入・実装について

    ・Expo の場合は eject 必須 Bare Workflow にする

    ・コード記述量自体はそこまで多くない ライブラリ使えば気軽に


    さいごに

    ・(特に宣伝ないので)Twitter とかフォローしてもらえると喜びます

    ・以上で発表終わります ありがとうございました!

    まとめ

    まとめ


    View full-size slide