public void launchPurchaseFlow( Activity activity, String sku, int requestCode, OnPurchaseFinishedListener listener, String extraData) { checkSetupDone("launchPurchaseFlow"); asyncFlag.start("launchPurchaseFlow"); Result result; try { Bundle buyIntentBundle = connection.getBuyIntent(sku, extraData); int response = getResponseCodeFromBundle(buyIntentBundle); if (response != BILLING_RESPONSE_RESULT_OK) { result = new Result(response, "Unable to buy item"); if (listener != null) listener.onPurchaseFinished(result, null); } else { PendingIntent intent = buyIntentBundle.getParcelable(RESPONSE_BUY_INTENT); this.requestCode = requestCode; purchaseListener = listener; activity.startIntentSenderForResult( intent.getIntentSender(), requestCode, new Intent(), 0, 0, 0); } } catch (IntentSender.SendIntentException e) { result = new Result(HELPER_SEND_INTENT_FAILED, "Failed to send intent."); if (listener != null) listener.onPurchaseFinished(result, null); } catch (RemoteException e) { result = new Result(HELPER_REMOTE_EXCEPTION, "Remote exception while starting purchase flow"); if (listener != null) listener.onPurchaseFinished(result, null); } }
/** * 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; }