目的
2021年1月13日時点での情報です。
AppleはサイトやツールのUIを頻繁に変更するので手順が異なる場合がありますので、ご注意ください。
SwiftyStoreKitは利用しません。
環境
- Xcode Version 12.3
- Swift 5
- iOSアプリはiTunesConnectに登録済とする
参照サイト
- Apple Developer Offering, Completing, and Restoring In-App Purchases
- Apple Developer requestBody
- Apple Developer original_transaction_id
- 初めてのiOSアプリ内課金実装
課金アイテムについて
今回は一番最安値の120円の **消耗型(一度利用すると無くなるアイテム)*+ をアプリに実行していきたいと思います。
iTunes Connectでの対応
iTunes Connect(App Store Connect)
にアクセス後、マイApp
を選択後、対象のアプリを選択。
アプリの詳細画面の左ペインより管理
を選択。
画面内の+
ボタンをクリックします。
一番最初の App 内課金は、App の新しいバージョンと一緒に提出する必要があります。
課金アイテムの種類を選択(今回は消耗型
)後、作成
をクリック
新しい App 内課金
画面が表示されて、結構設定が必要なようです。
参照名はApp Store Connectおよび「売上とトレンド」のレポートで使用されます。App Storeには表示されません。名前は最大で64文字です。
レポートに使用される固有な英数字のID。ある製品に対して使用した製品IDは、その製品が削除されても再度使用することはできません。
承認後に App Store に App 内課金コンテンツを表示するには、チェックボックスを選択します。
価格の項目で価格を選択します。
残りの以下の設定も行います。
AppStore情報の項目
ローカライズも設定できます。
App Store に表示される App 内課金の名前です。
App 内課金の設定によっては、この説明はカスタマーにも表示される場合があります。
AppStoreプロモーションの項目
こちらはオプションということで設定しませんでした。
App StoreでこのApp内課金のプロモーションをする
審査に関する情報項目
スクショとメモを設定します。
後で変えられるので準備していない場合は適当に。
スクリーンショットは課金アイテムが表示されている画面とか。
メモは課金画面への遷移を記載しました。
スクリーンショットは審査の目的においてのみ使用します。App Store に表示されることはありません。
iOS では、少なくとも 640 x 920 ピクセルが必要です。
審査に役立つ App 内課金に関する追加情報。
設定後、画面右上の保存
ボタンをクリックで以下のように、送信準備完了になりました。
Xcodeでの対応
次にXcodeでの作業です。
アプリのTARGETS
を選択し、Signing & Capabilities
を選択後、Capability
ボタンをクリック
ポップアップよりIn-App Purchase
を選択
プログラムについては、
Apple Developer Offering, Completing, and Restoring In-App Purchases
にサンプルがあるのでそれを利用しました。
サンプルのはMac用とかのも含まれているので注意。
StoreObserver.swift
とStoreManager.swift
あと共通関数のとかメッセージの所を持ってくれば良いかなと。
SwiftyStoreKitという便利なライブラリもあるようだが、時間があるならライブラリに頼らず、課金の仕組みを知っておいたほうが良いと思いました。
課金処理が成功すると、レシートというものをアプリ内で受け取ります。
それを運営サーバに送って、今度はサーバからAppleサーバにレシートを送って整合性を確認します。
こうすることで課金購入の整合性ととって、偽装などに対応できるということ。
後述のレシートについても参照
SKProductのpriceLocaleは、テストユーザなどで支払画面に行くまでは、ずっと「USD」で返ってくる。
テストユーザがJPで支払画面にいくと「JPY」になる。
テストユーザの作成
App Store Connect
にアクセス後、ユーザとアクセスをクリック
ユーザとアクセス画面のSandbox
項目よりテスターを選択。
画面上の+
ボタンをクリックして、テストユーザを作成する。
レシートについて
課金処理をすると、Appleサーバとレシートの検証を行う。
Appleサーバにレシートを送る際のURLは、環境によって異なるので注意。
本番:https://buy.itunes.apple.com/verifyReceipt
開発:https://sandbox.itunes.apple.com/verifyReceipt
消費アイテムの場合は、receipt-dataを送るだけで良い。
passwordは不要。←は定期購読とかで必要のよう。
AppleサーバへのAPIだが、環境ごとに分けるのではなく、まず本番と通信するようにする。
テストユーザでの課金の場合、Appleサーバからの返り値でstatus
が21007となるので、
そこでさらに開発環境へAPIを投げる方式が良いらしい。(Appleドキュメントに記載されていた)
レシートが問題ない場合、status
が0で返ってくる。
それ以外の項目としては以下となる。
重要そうなところのみ抜粋
"receipt":{
...
"bundle_id":"xxxx",
...
"receipt_creation_date":"2021-01-17 03:58:27 Etc/GMT",
"receipt_creation_date_ms":"1610855907000",
...
"in_app":[{
"quantity":"1",
"product_id":"yyyy",
"transaction_id":"9000000766037499",
"original_transaction_id":"9000000766037499",
"purchase_date":"2021-01-17 03:58:26 Etc/GMT",
"purchase_date_ms":"1610855906000",
...
}]},
"environment":"Sandbox",
"status":0
}
参照項目にあるApple Developer original_transaction_idページによると、
product_id
、riginal_transaction_id
、expires_date_ms
、purchase_date_ms
は保存したほうが良いらしい。
個人的には今回の場合、
まずbundle_id
とstatus
をチェックして整合性を確認。
DBには
product_id
、quantity
、original_transaction_id
、purchase_date
、purchase_date_ms
、environment
、status
を保存しようと思いました。
ドキュメントにある、expires_date_ms
の項目はありませんでした。
定期購読アイテムなどはあるのかもしれないが、
このアプリではそういうアイテムは今後も売らないので無視。
transaction_id
とoriginal_transaction_id
は基本的には同じ値なのですが、
定期購読アイテムやリストアしたアイテムの場合は値が異なるとのこと
リストアされるのは、非消費アイテムということで(購入者だけの特別メニューとか。)、そのアイテムも今の所実装する目処ないので、不要かなと。
審査
iTunes Connect上で登録した課金アイテムが準備完了となっていること。
そして、XcodeよりアプリをArchiveする。
バイナリを送ったら、次にiTunes Connectにて、申請用のアプリバージョンを作成する。
作ったアプリを選択すると、ページ右ペインの中頃にApp内課金
の項目が増えている。
Select In-App Purchases
を選択。
今回作成した課金アイテムを選択する。
App内課金
の項目にアイテムが追加される。
Purchase用にバイナリを送るなんてことは無かった。
そして、アプリのバイナリも追加したり、その他もいつもの審査通りに設定後、
画面右上の審査へ提出
ボタンをタップする。
そしてら、レビュー待ちとなる。
課金アイテムも審査待ち
状態となっていることを確認。
審査開始はその2日後に行われ、審査時間はいつもどおり数時間でした
なにか指摘があると思ったのですが、特に何もなく審査通りましたね。
サーバのログも無く、Apple側ではテストはしていないように見受けられました。
以上です。