Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
アプリ内課金のはまりどころ
Search
Shinya Suefusa
December 12, 2018
Programming
570
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
アプリ内課金のはまりどころ
Shinya Suefusa
December 12, 2018
More Decks by Shinya Suefusa
See All by Shinya Suefusa
MonacaクラウドIDEで作る!AndroidThingsアプリの開発
shinyasuefusa
0
2.1k
Other Decks in Programming
See All in Programming
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
470
どこまでゆるくて許されるのか
tk3fftk
0
300
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
230
A2UI という光を覗いてみる
satohjohn
1
170
Contextとはなにか
chiroruxx
1
390
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
180
Strategic Design in the Frontend: Moduliths & Micro Frontends @DDDEurope
manfredsteyer
PRO
0
140
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2.7k
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
820
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
12
4.6k
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.2k
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
Featured
See All Featured
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
67
56k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.7k
AI: The stuff that nobody shows you
jnunemaker
PRO
8
760
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.3k
Navigating Weather and Climate Data
rabernat
0
270
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
630
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.2k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
460
So, you think you're a good person
axbom
PRO
2
2.1k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
400
Discover your Explorer Soul
emna__ayadi
2
1.2k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
580
Transcript
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 1/57 アプリ内課金の アプリ内課金の
はまりどころ はまりどころ Monaca UG OKAYAMA 2018/12/12 @ShinyaSuefusa
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 2/57 今回は 最新技術スゲェ!
最新技術スゲェ! ではなく ナレッジの共有 ナレッジの共有 を目的として発表いたします
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 3/57 で
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 4/57 アプリ内課金 アプリ内課金
ついに有償アプリ作っちゃいました (ただし、Cordova 案件)
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 5/57 使うプラグインはこれ cordova-plugin-purchase
cordova-plugin-purchase
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 6/57 もちろんMonaca でも使えます。
公式のチュートリアルに書いてあります。 ただしサードパーティーなので有償プランで! https://docs.monaca.io/ja/tutorials/in-app_purchase
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 7/57 ここで ここで
さらっとアプリ内課金のポイントだけ ご説明しておきます (この場に無課金ユーザーはいないはず!)
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 8/57 アプリ内課金の種類 アプリ内課金の種類
for Android 管理対象のアプリ内アイテム 定期購読
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 9/57 アプリ内課金の種類 アプリ内課金の種類
for iOS 消費型 非消費型 自動更新購読 継続なしの購読
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 10/57 プラグインの使い方 プラグインの使い方
※ ハイブリッドアプリとして作るので、 原則、Android もiOS も同じ。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 11/57 1. 商品をプラグインに登録する
2. ストアから商品情報を取得する 3. 商品を購入する 4. 商品を消費する store.register(product); store.refresh(); store.order(product); product.finish();
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 12/57 商品情報のライフサイクル 商品情報のライフサイクル
( 後で出てくるのちょっとだけ覚えて)
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 13/57 めっちゃ簡単やん!
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 14/57 がっ! 意外と大変。。。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 15/57 ここから アプリ内課金でハマった事例を
ご紹介します!
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 16/57 事例1 事例1
プラグインの ID を間違えやすい プラグインの ID を間違えやすい
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 17/57 プロジェクトにを追加するとき、 ※Monaca
だとプラグインのインポートですが。 とすると、 なんか古いプラグインが追加されて動かない。 (正確には現在はなおったっぽい?) cordova plugin add cordova-plugin-purchase
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 18/57 正しくは、 cordova
plugin add cc.fovea.cordova.purchase
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 19/57 12/4 にnpm
を調べてみると、18 days ago !?!?
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 20/57 最近ようやく改善されたようです。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 21/57 事例2 事例2
基本、リリース署名必須 基本、リリース署名必須 for Android
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 22/57 Android で動かすなら、リリース版の署名が必要。
課金を試すのにストアへ内部テスト版としてAPK を 登録しなければならない。 この時、APK がdebuggable=true になっているとAPK がストアに弾かれるので、デバッグはできなくな る。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 23/57 署名無しやStore にAPK
を登録せずに動かすと、 みたいなエラーが出る。 6777017: E/IabHelper: In-app billing error: Purchase signature verification FAILED for sku android.test.purchased
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 24/57 デバッグできねぇじゃん!! (
ノД`) シクシク…
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 25/57 でも大丈夫。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 26/57 Android でどうしてもデバッグしたい場合。
1. リリースビルドAPK をストアに登録 2. 同じ署名でデバッグ版を作る 3. 実機インストール! すればデバッグが有効になった状態でアプリ内課 金を試せる。 adb install -d xxx.apk
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 27/57 事例3 事例3
ライセンステスト登録が必要 ライセンステスト登録が必要 for Android
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 28/57 Android で課金テストを行う時、テスターの登録の
後、ライセンステストの登録も必要。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 29/57 - Qiita
より ファ!? Android でアプリ内課金テストを行う
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 30/57 そして、 しれっと
GooglePlay のライセンステストの登録が 外れることがある。 (タイミングは不明)
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 31/57 通常のテストの時に受け取るメール。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 32/57 テスト中、突如やらかす。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 33/57 あ、ちなみに、実際のクレカ登録していなくて も、テストできます。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 34/57 事例4 事例4
iOS の審査時のレシート検証に iOS の審査時のレシート検証に 注意 注意 for iOS
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 35/57 iOS のレシート検証は、テスト用の「Sandbox
」と 「本番」がある。 アプリリリースするには、本番用の設定のビルド をするわけですが、審査時の(審査員の)レシー トは「Sandbox 」のものになるため、「本番」の検 証サーバにアクセスするとエラーになる。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 36/57 サーバーサイドでレシート検証をしている場合 は、審査で申請しているログインID
だったら Sandbox で検証する、などの対応が必要。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 37/57 事例5 事例5
定期購読型に要注意 定期購読型に要注意 for Android/iOS
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 38/57 定期購読型の場合、「期限切れになった」という イベントは自動では発火しない。
つまり、アプリ起動しっぱなしにしておけばいつ までも権利が使えることになる。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 39/57 プラグインのrefresh 関数をコールすると、状態が
OWNED から再度、APPROVED に遷移する。 (APPROVED イベントが発火する) で、再度レシート検証をして期限切れになってい ないかチェックする必要がある。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 40/57 事例6 事例6
定期購読型に要注意 その2 定期購読型に要注意 その2 for Android
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 41/57 プラグインのAndroid 側にバグがあって、前の事例
に書いたレシート検証で期限切れとした場合で も、商品の所有状態(OWNED )がfalse に戻ってく れない(!!)
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 42/57 検証NG でEXPIRED
にするとき、一緒に product.owned = false にする必要がある。 これ重要! なお、iOS 版はちゃんとfalse になる。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 43/57 事例7 事例7
iOS のリストアが厄介 iOS のリストアが厄介 for iOS
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 44/57 iOS 版は購入状態の「リストア」機能が無いとリジ
ェクトされる。 iPhone を買い替えたーとか、iPad でも使うー、と か。 同じAppleID 使えば同じ購入状態にせよ。 という厳しいルールがある。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 45/57 ところが、iOS 版のプラグインは、refresh
関数を2 回呼ぶと、リストアが自動的に行われる仕様にな っている。 SPA なUI を採用していると、2 回以上呼んじゃうっ てところにはまって、勝手にリストアされて新し いレシートが発行されて。。 と面倒なので、担当した案件では勝手にリストア されないように細工した。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 46/57 storekit.restore の中にリストア処理を呼ぶ実装があ
るので、空の関数に差し替える。 if (window.storekit) { // StoreKit(iOS) 場合 refresh時 restore 防 // restore関数 無効化 const storekit = Object.getPrototypeOf(window.storekit) storekit.originalRestore = storekit.restore storekit.restore = () => {} }
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 47/57 事例8 事例8
StoreKit にアクセスすると毎回 StoreKit にアクセスすると毎回 ID/PASS を聞かれる ID/PASS を聞かれる for iOS
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 48/57 iOS のSandbox
でテストする時、StoreKit 経由でStore にアクセスしたタイミングでAppleID を毎回入力す る必要がある。 (iPhone のStore の設定にテストアカウントは登録 することはできない) 一応、入力ダイアログをキャンセルすることもで きる。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 49/57 しかし、ダイアログでキャンセルすると、cordova プラグインのexec
のコールバックが呼ばれず、必ず デッドロックする。 面倒でも毎回ID/PASS を入力してください。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 50/57 事例9 事例9
ローカルストレージがパンクす ローカルストレージがパンクす る る for iOS
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 51/57 iOS 版はトランザクションをfinish
するとレシート情 報やトランザクションID が取れなくなるため、ロ ーカルストレージに情報を保持している。 しかし、レシート情報が結構なサイズなので、定 期購読するとローカルストレージがいずれパンク する。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 52/57 レシート情報をあとで使いたいシーンがないので あれば、下記3つはアプリ起動時とかに消すよう
にする。 if (window.localStorage) { // iOS 情報 使用 破棄 window.localStorage.removeItem('sk_receiptForProduct') window.localStorage.removeItem('sk_receiptForTransaction') window.localStorage.removeItem('sk_appStoreReceipt') }
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 53/57 事例10 事例10
プラグインは SPA に配慮されて プラグインは SPA に配慮されて いない? いない? for iOS/Android
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 54/57 プロダクトのregister は初回のrefresh
にしか反応し ない。 つまり、SPA アプリで一度register→refresh でロード してしまうと、WebAPI とかで再度最新のプロダク トID を追加取得しても追加ロードができない。 グローバル変数でカウントしているため、どうに もならない。。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 55/57 という感じで という感じで
事例を10個ご紹介しましたが、 実際はもっとた くさんノウハウが溜まりました。
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 56/57 Full バージョンは
Monaca Advent Calendar 2018 に投稿します! https://adventar.org/calendars/3073
2018/12/13 RevealJS : /Users/s-suefusa/Desktop/md/MonacaUG OKAYAMA #3/slide.1.md http://localhost:50115/?print-pdf-now#/ 57/57 ありがとうございました ありがとうございました