LoginSignup
9
10

More than 5 years have passed since last update.

アプリ内課金のstaticItem購入でハマったエラー

Last updated at Posted at 2016-04-13

前提

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メソッドを修正する。

Security.java

    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を指定して、通過させるかどうかを決定出来るようにしました。

9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10