21

我在我的android應用程序的應用程序結算中遇到問題。 我收到購買簽名驗證失敗。 在第一次我強硬這是base64的關鍵,但我檢查了很多次,我仍然得到錯誤,然後我看了一下Security.java文件後,我發現這個方法,我編輯得到一些有關錯誤的信息:android在應用程序結算購買驗證失敗

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); 
} 

而且我越來越「簽名是空的」。 即使我按照以下步驟操作: -Sign我釋放鑰匙 的APK使用-upload它作爲一個草案 -install它的設備上「亞行-d安裝app.apk」

我測試與真正的購買。 謝謝。

編輯購買流程是好的,我得到的錯誤,當我打電話queryInventoryAsync

+1

檢查我下面的回答,希望它會解決你的問題。 – Maulik

回答

35

將您的verifyPurchase()方法替換爲下面的方法。使用下面給出的舊代碼,谷歌開發人員正試圖在不久的將來解決這個錯誤,但在他們更新代碼之前,您應該更喜歡下面的代碼。

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; 
     } 

檢查此鏈接瞭解更多信息:

In App billing not working after update - Google Store

使用嘗試替換舊代碼的方法在你的項目verifyPurchase()方法。但是,只有當您試圖購買測試產品時纔會發生這種情況。使用此代碼後,還請讓我知道真正的產品購買情況。

編輯:

爲什麼會發生,因爲當我們使用的虛擬產品,如「android.test.purchased」我們不會得到任何簽名。因此,在舊代碼中,它運行良好,因爲即使沒有給出簽名,我們仍然返回true,對於新代碼,我們返回false。

來自LINK1簽名數據空或空白,並鏈接2

更多信息,所以我建議你只是替換舊代碼的方法,而不是verifyPurchase()新代碼的方法。

我認爲可能是新代碼將工作正常的真實產品,但不是在虛擬產品。但是我還沒有測試過真正的產品。

利用GVS的回答爲購買測試它也爲新的代碼很好的解決方案。

希望它能解決您的問題。

+0

謝謝!這解決了我的問題 –

+0

@Maulik感謝它爲我的目的測試項目,但我有一個問題,它是應用程序在像購買書籍使用inAppBilling應用程序?請建議我 –

+0

我似乎無法找到該方法'Security.generatePublicKey(base64PublicKey);'Security類是java.s的一部分ecurity?謝謝。 – Chan

40

您可以使用測試SKU的做測試,as explained here。它們是:

  • android.test.purchased
  • android.test.canceled
  • android.test.refunded
  • android.test.item_unavailable

這些採購會成功(至少android.test.purchased)即使在測試和調試方案的,而無需取消購買。

在verifyPurchase我改變return false到:

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

,但你應該知道只有在測試場景的使用這一點。

這將返回true,如果您有調試版本,並且簽名數據丟失。由於BuildConfig.DEBUG在生產版本中將爲false,因此應該可以。但更好的是在調試完所有東西后刪除這些代碼。

+2

我得到了同樣的結果,我能夠購買該項目,但然後queryInventoryAsinc(監聽)給了我錯誤 – TheRedFox

+0

對我來說,這在調試時工作。您還可以在verifyPurchase或IabHelper.handleActivityResult中放置斷點以查看錯誤出現的位置。 – GvS

+0

@GvS,verifyPurchase()的舊代碼可以正常工作,但是當google開發人員更新代碼以在verifyPurchase()方法中創建更安全的事務時,他們會放置一些額外的代碼來驗證簽名,但現在他們正在努力改善這個錯誤。根據我現在聽到的情況。 – Maulik

1

確保您使用正確的用戶登錄了您的手機或在開發者控制檯中添加手機的Google帳戶作爲測試用戶。

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

在某些情況下,保留的項目可能會返回簽署的靜態回覆,它可以讓你在你的應用程序中測試簽名驗證。如果運行應用程序的用戶有開發人員或測試帳戶,則保留項目只會返回已簽名的響應。

0

集返回值true在

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

tesing後撤消更改

相關問題