Skip to content

{ Tag Archives } In-App Purchase

iOS 7/In-App Purchase/ローカルレシート検証

これの続きです。
iOS 7 + Auto-renewable + TransactionReceipt
これで有効期限が取れたのは取れたのですが(値も正しかった)、これで良いのかわかりません。素直にOpenSSL使って、ローカルレシート確認にする方がいいのかしら…
2013/11/4 追記:
このやり方はAppleのドキュメントに書いてないからダメっぽい。
OpenSSL使ってローカルレシート認証にするのが正解だと思われる。
引き続き検証中。
元の話は、iOSのアプリ内課金(In-App Purchase)でレシートの確認を行う場合、SKPaymentTransaction#transactionReceiptが、iOS 7からDeprecatedになっており、さてどうしたらよいのやら…ということでした。そしてこれに対する回答は、Appleのドキュメントに”超”概要が書いてありました。
レシート検証 プログラミングガイド

P.5
レシートをローカルで検証する
ローカルでの検証には、PKCS #7署名を読み込んで検証するコードと署名されたペイロードを解析し て検証するコードが必要です。

P.7
iOSで(システムが古いために)appStoreReceiptURLメソッドが使用できない場合は、App Storeを使用してSKPaymentTransactionオブジェクトのtransactionReceiptプロパティを 検証するためにフォールバックすることができます。

ふむふむ…「appStoreReceiptURLメソッドが使用できるのならレシートをローカルで検証しなさい」というように読み取れます。何故なら「フォールバックする」=「SKPaymentTransactionオブジェクトのtransactionReceiptプロパティを使う」=「Deprecated」だからです。
ではレシートをローカルで検証するにはどうするか…ドキュメントを読むと次のようにありました。
・ローカルのレシートは、Appleの証明書に署名されたPKCS #7コンテナである
・PKCS #7を読みほどいていくにはOpenSSLを使えば出来るけど、ヒントはドキュメントに書いておく
・まぁそんな感じで実装は開発者にまかせた、頑張れ
お、おう…頑張って実装を…無理や!と思ったら、ここら辺をやってくれている方がいらっしゃいました。ファンタスティック!次の3つを使っていけば、レシートをローカルで検証することが出来ます。
・x2on / OpenSSL-for-iPhone
https://github.com/x2on/OpenSSL-for-iPhone
・rmaddy / VerifyStoreReceiptiOS
https://github.com/rmaddy/VerifyStoreReceiptiOS
・Apple Root Certification Authoirty
http://www.apple.com/certificateauthority/
以下手順。
==========
1. OpenSSL-for-iPhoneの中に build-libssl.sh があるので、ターミナルから叩いて暫く待てば出来上がりです。これを使ったビルドにarが必要なのですが、自分環境にarがなかったので

sudo ln -s /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar /Applications/Xcode.app/Contents/Developer/usr/bin/ar

こんな感じでシンボリックを張ったら通りました。
2. 1で作ったOpenSSLのlibrary2つ、VerifyStoreReceiptiOSの.hと.m、AppleのROOTサーバ証明書(Apple Inc. Root Certificateの方)を、レシートを検証するアプリのプロジェクトに突っ込みます。AppleのROOTサーバ証明書だけプロジェクトのルートに配置してください。他は任意の場所でOKです。それからプロジェクトの設定について、OpenSSLのヘッダが読み取れるようにSearchPathを足すのと、OpenSSLのライブラリをStatic Linkするように変更してください。
3. VerifyStoreReceipt.m の以下行をアンコメント、さらに自分のアプリに合わせて変更してください。

// const NSString * global_bundleVersion = @"1.0.2";
// const NSString * global_bundleIdentifier = @"com.example.SampleApp";

4.  レシートの検証ロジックを、VerifyStoreReceipt.mを使ったものに変更してください。

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
BOOL [...]

Also tagged

iOS 7 + Auto-renewable + TransactionReceipt

iOS 7のIn-App Purchase(アプリ内課金)で、Auto-renewable Product(自動更新購読型)の話です。
Auto-renewableなプロダクトが購入されたとき、それの有効期間を確認するために
paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
からレシート情報を取得しApp Storeへ送ると、次のようなJSONが返ってきます。

{
"latest_receipt" = <latest_receipt_infoのBASE64値>;
"latest_receipt_info" = {
bid = "APPID";
bvrs = "1.0";
"expires_date" = 1383368349000;
[...]

Also tagged