25

IAB v3 が動作し、管理対象アイテムを購入できました。ただし、開発とテストを継続するために、同じ購入をもう一度試すことができるように、購入を払い戻したいと思いました. Google Checkout Merchant アカウントにログインし、購入の払い戻しに成功しました。ただし、アプリはユーザーがアイテムを購入したと見なします。払い戻しを行ってからすでに数週間が経過しているため、遅延の問題ではありません.

基本的に、私のQueryInventoryFinishedListener実装でinventory.hasPurchase(SKU_REMOVE_ADS)は、払い戻し後でも常に true を返します (SKU_REMOVE_ADSは販売している商品の SKU です)。払い戻しが処理された後、false が返されることを期待していました。

IAB リファレンスの「払い戻しの処理」セクションを見ると、アプリは IN_APP_NOTIFY メッセージをリッスンする必要があると書かれています。ただし、IN_APP_NOTIFY のドキュメントは、アプリ内課金の v2 に固有のものです。v3 リファレンスのどこにも言及されておらず、IAB v3 のデモに使用しているサンプルの TrivialDrive アプリでもリファレンスを見つけることができないため、v3 で利用できるものではないようです。

では、IAB の v3 は払い戻しや購入のキャンセルをサポートしていますか? 誰かがそれを試して、それを機能させましたか?

4

3 に答える 3

37

Google Play に関する限り、消耗品と非消耗品の間に違いはありません。この区別は、アプリ内で何を実装するかに完全に基づいています。そのため、テストしている SKU は非消耗品 (恒久的なプレミアム アップグレードなど) であることを意図していても、テスト目的では、それを消耗品として扱って消費し、再度購入できるようにすることができます。

便利な方法は、アプリ内に一時的なテスト メニューをセットアップし (たとえば、テスト中にアプリのメイン オプション メニューにメニュー項目を追加することによって)、その項目のハンドラーが IabHelper インスタンスの consumerAsync() メソッドを呼び出すようにすることです。もう一度テスト購入したいSKU。これによりアイテムが消費され、デバイスからすぐに再購入できるようになります。

もちろん、アプリをテストするためだけに自分のお金を使わないように、Google Checkout からの購入を払い戻したいと思うでしょう。

そのような静的な値を使用してテストしている場合、テスト SKU android.test.purchased をリセットするために、consumeAsync() も問題なく機能するように思われることを付け加えておきます。

払い戻しを反映するための購入状態の更新に関して、個人的に経験したことがあります (また、他の開発者によって投稿された同様のレポートが多数あります)。Checkout を介して手動で払い戻しを開始すると (たとえば、TrivialDrive アプリからのテスト購入) 、結果が出るまでに数日かかります。製品の購入状態の変更 (INAPP_PURCHASE_STATE_REFUNDED へ)。

(惨めさは会社を愛することを知っているので、これらの追加レポートのいくつかは、このディスカッション スレッドで見つけることができます: https://plus.google.com/+AndroidDevelopers/posts/R8DKwZDsz5m )

これの少なくとも一部は、デバイス上の購入データの Google Play のキャッシュによるものです。

私の経験では、デバイスを再起動すると、Google Play が GP サーバーからキャッシュを更新することがあります。そのため、チェックアウトを介した注文のキャンセルまたは返金による変更も、再起動後に検出される可能性があります。

ユーザーがいつ再起動するかわからないため、このような長いターンアラウンド期間は役に立たないように思えるかもしれません。しかし、繰り返しになりますが、最終的にはすべてのデバイスが再起動されることがわかっているため、払い戻しを受け取ったユーザーが払い戻しされた IAB 製品を最終的に使用できなくなることを懸念している場合は、数日の遅延は問題にならない可能性があります。それが最終的に起こる限り。

もちろん、再起動時にキャッシュが更新されるというこの概念は文書化されておらず、逸話的であることを覚えておいてください (これまでのかなりの数の IAB3 および TrivialDrive の動作と同様)。フォークロア、彼らはそれを呼んでいます。

更新をトリガーするもう 1 つのことは、ユーザーが製品を購入しようとしたときです。購入が開始されるとすぐに、システムは製品がまだ所有されていないことを確認する必要があるため、Google Play キャッシュを更新します。私の個人的な経験では、これは常に発生しています。しかし、繰り返しますが、これは払い戻しを確認するためのあまり実用的な方法ではありません。なぜなら、入札されていない購入ダイアログが表示され、ユーザーに「既に所有している」というエラー メッセージが表示されるためです (ユーザー所有している場合)。

これがどこで行われるかユーザーが自分のデバイスの 1 つで IAB アイテムの代金を支払い、購入に使用したのと同じアカウントが所有する別のデバイスでそのアイテムにアクセスしようとする場合に便利です。その場合の購入情報は、まだキャッシュされていないことが非常に多いです。ただし、アイテムが既に購入されている場合、再購入を試みると追加料金なしで現在のデバイスで利用できるようになるはずであるということを、購入ダイアログにちょっとしたメモを入れることができます. 場合によっては、最終的に IabHelper.BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED 応答を取得するために、(ユーザーが開始した) 購入を 2 回試行する必要があります。はい、少しぎこちないですが、人間の言葉では、メッセージの適切な強調表示と、アイテムを所有していることを伝える確認ダイアログの謝罪文言などで機能すると思います:-))。

実際問題として、アプリの購入データがアクセスされるたびに、世界中のすべての IAB アプリのすべてのインスタンスがサーバーにアクセスすることを Google が望んでいないことがわかるでしょう。アプリを起動するたびに購入されます。これは、アプリのパフォーマンスの問題でもあります。それがキャッシュのすべてです。そのため、キャッシュを更新するためのトリガーに注意する必要があります。これが公式に文書化されている場所は 1 か所も見つかりませんでした (ただし、コード内であると思われます)。ですから、手を前に出して、暗闇の中で周りを感じ始める準備をしてください。

Google Play バッファリングに関する追加情報については、次のページを参照してください。

アプリ内課金バージョン 3 サーバーの変更がクライアント デバイスで利用可能になる条件は?

あなたの投稿のコード スニペットでは、inventory.hasPurchase(SKU_REMOVE_ADS) を呼び出していることに注意してください。ただし、在庫オブジェクトで返された購入のリストに購入が含まれているかどうかのみがわかります。その SKU の購入状況はわかりません。これが TrivialDrive アプリで使用されているアプローチであることは知っていますが、そのアプリは払い戻しやキャンセルを扱っていません。払い戻しとキャンセルされた注文を検出するには、次のようなものが必要です。

Purchase removeAdsPurchase = inventory.getPurchase(SKU_REMOVE_ADS);
if(removeAdsPurchase != null) {
  int purchaseStateForRemoveAds = removeAdsPurchase.getPurchaseState();
  if(purchaseStateForRemoveAds == 1) {
    //Do cancelled purchase stuff here
  }
  else if(purchaseStateForRemoveAds == 2) {
    //Do refunded purchase stuff here
  }
}

払い戻しとキャンセルされた注文に関する良いニュースは、どちらも完全に開発者の選択に任されているということです。そのため、これらを取得したユーザーがその後も長い間アプリを使用し続けることができ、多くのユーザーがこれを利用していることがわかった場合は、払い戻しを引き続き提供するかどうかを決定できます。すべての場合。私の最善の推測では、それは問題にはならないでしょう。払い戻しを受けた一部のユーザーがその後しばらくアプリを使用できるようになったとしても、それは大したことではないと考えられます。

購入を非常に迅速に再試行する機能が必要であることをテストするためのものであり、consumeAsync() を使用すると、その目的で確実に機能します。

于 2013-04-04T20:42:55.903 に答える
0

この質問を投稿して以来、電話getPurchase(...).getPurchaseState()してその価値を確認する必要があることに気づきました。可能な値は、0 (購入済み)、1 (キャンセル済み)、または 2 (返金済み) です。</p>

ただし、私の場合、アイテムが返金されても、まだ0(購入済み)を返しています。他の人に役立つ場合に備えて、この情報をここに投稿しています。

于 2013-04-05T00:34:24.110 に答える