int queryPurchases(Inventory inv) throws JSONException, RemoteException { boolean verificationFailed = false; String continueToken = null; do { Bundle ownedItems = connection.getPurchases(continueToken); int response = getResponseCodeFromBundle(ownedItems); if (response != BILLING_RESPONSE_RESULT_OK) { return response; } if (!ownedItems.containsKey(RESPONSE_INAPP_ITEM_LIST) || !ownedItems.containsKey(RESPONSE_INAPP_PURCHASE_DATA_LIST) || !ownedItems.containsKey(RESPONSE_INAPP_SIGNATURE_LIST)) { return HELPER_BAD_RESPONSE; } ArrayList<String> purchaseDataList = ownedItems.getStringArrayList(RESPONSE_INAPP_PURCHASE_DATA_LIST); ArrayList<String> signatureList = ownedItems.getStringArrayList(RESPONSE_INAPP_SIGNATURE_LIST); for (int i = 0; i < purchaseDataList.size(); ++i) { String purchaseData = purchaseDataList.get(i); String signature = signatureList.get(i); if (security.verifyPurchase(purchaseData, signature)) { Purchase purchase = new Purchase(purchaseData, signature); inv.addPurchase(purchase); } else { verificationFailed = true; } } continueToken = ownedItems.getString(INAPP_CONTINUATION_TOKEN); } while (!TextUtils.isEmpty(continueToken)); return verificationFailed ? HELPER_VERIFICATION_FAILED : BILLING_RESPONSE_RESULT_OK; }
/** * Handles an activity result that's part of the purchase flow in in-app billing. If you are * calling {@link #launchPurchaseFlow}, then you must call this method from your Activity's {@link * android.app.Activity@onActivityResult} method. This method MUST be called from the UI thread of * the Activity. * * @param requestCode The requestCode as you received it. * @param resultCode The resultCode as you received it. * @param data The data (Intent) as you received it. * @return Returns true if the result was related to a purchase flow and was handled; false if the * result was not related to a purchase, in which case you should handle it normally. */ public boolean handleActivityResult(int requestCode, int resultCode, Intent data) { Result result; if (requestCode != this.requestCode) return false; checkSetupDone("handleActivityResult"); asyncFlag.end(); if (data == null) { result = new Result(HELPER_BAD_RESPONSE, "Null data in IAB result"); if (purchaseListener != null) { purchaseListener.onPurchaseFinished(result, null); } return true; } int responseCode = getResponseCodeFromIntent(data); String purchaseData = data.getStringExtra(RESPONSE_INAPP_PURCHASE_DATA); String dataSignature = data.getStringExtra(RESPONSE_INAPP_SIGNATURE); if (resultCode == Activity.RESULT_OK && responseCode == BILLING_RESPONSE_RESULT_OK) { if (purchaseData == null || dataSignature == null) { result = new Result(HELPER_UNKNOWN_ERROR, "IAB returned null purchaseData or dataSignature"); if (purchaseListener != null) { purchaseListener.onPurchaseFinished(result, null); } return true; } Purchase purchase; try { purchase = new Purchase(purchaseData, dataSignature); String sku = purchase.getSku(); if (!security.verifyPurchase(purchaseData, dataSignature)) { result = new Result( HELPER_VERIFICATION_FAILED, "Signature verification failed for sku " + sku); if (purchaseListener != null) { purchaseListener.onPurchaseFinished(result, purchase); } return true; } } catch (JSONException e) { e.printStackTrace(); result = new Result(HELPER_BAD_RESPONSE, "Failed to parse purchase data."); if (purchaseListener != null) { purchaseListener.onPurchaseFinished(result, null); } return true; } if (purchaseListener != null) { purchaseListener.onPurchaseFinished( new Result(BILLING_RESPONSE_RESULT_OK, "Success"), purchase); } } else if (resultCode == Activity.RESULT_OK) { if (purchaseListener != null) { result = new Result(responseCode, "Problem purchashing item."); purchaseListener.onPurchaseFinished(result, null); } } else if (resultCode == Activity.RESULT_CANCELED) { result = new Result(HELPER_USER_CANCELLED, "User canceled."); if (purchaseListener != null) { purchaseListener.onPurchaseFinished(result, null); } } else { result = new Result(HELPER_UNKNOWN_PURCHASE_RESPONSE, "Unknown purchase response."); if (purchaseListener != null) purchaseListener.onPurchaseFinished(result, null); } return true; }