web-dev-qa-db-ja.com

androidアプリ課金の購入確認に失敗しました

私はAndroidアプリでアプリの請求を実装するのに問題があります。購入署名の確認に失敗しました。私はまだエラーを受け取っていますが、Security.Javaファイルを見て、間違ったものに関する情報を得るために編集したこのメソッドを見つけました:

    public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
    if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) ||
            TextUtils.isEmpty(signature)) {
        if(TextUtils.isEmpty(signedData)) Log.d(TAG, "SIGNED DATA EMPTY");
        if(TextUtils.isEmpty(base64PublicKey)) Log.d(TAG, "KEY IS EMPTY");
        if(TextUtils.isEmpty(signature)) Log.d(TAG, "SIGNATURE IS EMPTY");
        Log.e(TAG, "Purchase verification failed: missing data.");
        return false;
    }

    PublicKey key = Security.generatePublicKey(base64PublicKey);
    return Security.verify(key, signedData, signature);
}

そして、「署名が空です」というメッセージが表示されます。次の手順を実行した後でも、リリースキーを使用してapkに署名します。ドラフトとしてアップロードします。「adb -d install app.apk」を使用してデバイスにインストールします。

私は実際の購入でテストしています。ありがとう。

編集 購入フローは問題ありません。queryInventoryAsyncを呼び出すとエラーが発生します

23
TheRedFox

verifyPurchase()メソッドを以下のものに置き換えます。以下に示す古いコードを使用して、Google開発者は近い将来このエラーを解決しようとしていますが、コードを更新する前に以下のコードを選択する必要があります。

_ public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
              if (signedData == null) {
                Log.e(TAG, "data is null");
                return false;
            }

            boolean verified = false;
            if (!TextUtils.isEmpty(signature)) {
                PublicKey key = Security.generatePublicKey(base64PublicKey);
                verified = Security.verify(key, signedData, signature);
                if (!verified) {
                    Log.w(TAG, "signature does not match data.");
                    return false;
                }
            }
            return true;
        }
_

詳細については、次のリンクを確認してください。

更新後にアプリ内課金が機能しない-Googleストア

プロジェクトのOLD CODEメソッドverifyPurchase()メソッドを置き換えてみてください。ただし、テスト製品を購入しようとしているときにのみ発生するはずです。このコードを使用した後、実際の製品の購入についても教えてください。

編集:

「Android.test.purchased」のようなダミー製品を使用している間は署名を取得しないため、なぜ起こるのか。したがって、古いコードでは、署名が与えられていない場合でもtrueを返し、新しいコードではfalseを返すため、正常に機能しています。

link1およびlink2のヌルまたはブランクの署名データに関する詳細情報

したがって、New Codeメソッドではなく、古いコードメソッドverifyPurchase()を置き換えることをお勧めします。

新しいコードは実際の製品では正常に機能するが、ダミー製品では機能しない可能性があると思います。しかし、実際の製品についてはテストしていません。

または

テスト購入にはGvSの回答を使用し、新しいコードの優れたソリューションとしても使用します。

それがあなたの問題を解決することを願っています。

39
Maulik

テストSKUを使用してテストを行うことができます ここで説明 。これらは:

  • Android.test.purchased
  • Android.test.canceled
  • Android.test.refunded
  • Android.test.item_unavailable

これらの購入は、テストとデバッグのシナリオでも、購入をキャンセルする必要なく成功します(少なくともAndroid.test.purchased)。

VerifyPurchaseでreturn false to:

    Log.e(TAG, "Purchase verification failed: missing data.");
    if (BuildConfig.DEBUG) {
            return true;
    }
    return false;           

ただし、これはテストシナリオでのみ使用することに注意してください。

デバッグビルドがあり、署名データが欠落している場合、これはtrueを返します。 BuildConfig.DEBUGは本番ビルドではfalseになるため、これで問題ありません。しかし、すべてがデバッグされた後にこのコードを削除する方が良いです。

40
GvS

携帯電話で適切なユーザーでログインしていることを確認してください。デベロッパーコンソールで携帯電話のGoogleアカウントをテストユーザーとして追加します。

http://developer.Android.com/google/play/billing/billing_testing.html#billing-testing-static

場合によっては、予約されたアイテムが署名済みの静的応答を返すことがあります。これにより、アプリケーションで署名検証をテストできます。予約されたアイテムは、アプリケーションを実行しているユーザーが開発者またはテストアカウントを持っている場合にのみ署名付きの応答を返します。

1
Till

戻り値をtrueに設定します

public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
    return true;
}

変更を元に戻した後

0