前提
In-app Billing v3使用。
サンプルほぼそのまんま。
経緯
アプリ内課金でstatic Item(android.test.purchased)の購入をしようとしたら、
(1)verify signatureエラーが起き、
E/IABUtil/Security(5973): Purchase verification failed: missing data.
E/IabHelper(5973): In-app billing error: Purchase signature verification FAILED for sku android.test.purchased
(2)queryInventoryが失敗するようになった
Error refreshing inventory (querying owned items). (response: -1003:Purchase signature verification failed)
(3)とりあえずまた買おうとすると、
Unable to buy item, Error response: 7:Item Already Owned
こう出るので、じゃあ消費しようとするが、(2)の通りqueryInventoryが失敗するので、ownedListが取得出来ず、consumeができない
テストアカウントが社内で使い回しているアカウントなので、全員に影響が出るんじゃないかと、冷や汗ダラダラでした。
現象解除方法
ひとまず復元も何も出来なくなるので、いったんこの現象をクリアする必要がある。
(1)14日待つ
14日経てば消費されるという記述があったが、verifyが失敗しててもいいんだろうか?
(2)Playストアのデータを削除する
これしか無いようだ。
ということは、同じアカウントを使っている端末があったとしても、影響しないようだ。
(まあサーバーと通信してなさそうだから当たりまえか)
購入テストをする前に、Playストアアプリを一度起動しておくのを忘れないように。
購入を通過させる方法
さて、今後このテスト購入は通過させる必要がある。
購入後のフロー確認のためだけに、何度も購入&消費を繰り返すのは大変だからだ。
特に、購入情報はサーバーにも置いているので、消費した場合、サーバー側も消してもらわないと行けなくて、担当者が別人で休んでたりするとお手上げだ。
ということで検索して、見つけました。
こちらに助けられました(ノД`)
http://yome9.blogspot.jp/2014/10/in-app-billing-v3.html
サンプルまんまなら、util.Securityというクラスがあるはずなので、以下のようにVerifyメソッドを修正する。
private static boolean ignoreVerifyError = true;
public static boolean verifyPurchase(String base64PublicKey,
String signedData, String signature) {
if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey)
|| TextUtils.isEmpty(signature)) {
Log.e("Purchase verification failed: missing data.");
if (BuildConfig.DEBUG && ignoreVerifyError) {
Log.w("!!!! DEBUG ONLY !!! ignoring VerifyError!!!");
return true;
}
return false;
}
PublicKey key = Security.generatePublicKey(base64PublicKey);
return Security.verify(key, signedData, signature);
}
もっと几帳面にやるなら、signedDataからPurchaseクラスに入れて、productId(sku)もチェックするといいかも。
今回は、外からignoreVerifyErrorを指定して、通過させるかどうかを決定出来るようにしました。