static void insertPurchases(
     @Nonnull Billing billing, @Nonnull String product, @Nonnull List<Purchase> purchases)
     throws RemoteException {
   final Bundle bundle = newBundle(OK);
   final ArrayList<String> list = new ArrayList<String>();
   for (Purchase purchase : purchases) {
     list.add(purchase.toJson());
   }
   bundle.putStringArrayList(Purchases.BUNDLE_DATA_LIST, list);
   final IInAppBillingService service = ((TestServiceConnector) billing.getConnector()).service;
   when(service.getPurchases(anyInt(), anyString(), eq(product), isNull(String.class)))
       .thenReturn(bundle);
 }
Example #2
0
  @Click(R.id.get_purchases_button)
  public void getPurchases(View v) {
    try {
      Bundle ownedItems;
      ownedItems = billingService.getPurchases(apiLevel, getPackageName(), "inapp", null);

      if (ownedItems.getInt("RESPONSE_CODE") != 0) {
        logView.append("getPurchases Fail\n");
        return;
      }

      ArrayList<String> purchaseDataList =
          ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
      if (purchaseDataList.size() == 0) {
        logView.append("getPurchases empty\n");
      }

      for (String purchaseData : purchaseDataList) {
        logView.append("getPurchases: " + purchaseData + "\n");
      }
    } catch (RemoteException e) {
      String msg = "getPurchases: " + e.getMessage() + "\n";
      logView.append(msg);

      Log.e(TAG, msg);
      e.printStackTrace();
    }
  }
Example #3
0
  int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException {
    // Query purchases
    logDebug("Querying owned items, item type: " + itemType);
    logDebug("Package name: " + mContext.getPackageName());
    boolean verificationFailed = false;
    String continueToken = null;

    do {
      logDebug("Calling getPurchases with continuation token: " + continueToken);
      Bundle ownedItems =
          mService.getPurchases(3, mContext.getPackageName(), itemType, continueToken);

      int response = getResponseCodeFromBundle(ownedItems);
      logDebug("Owned items response: " + String.valueOf(response));
      if (response != BILLING_RESPONSE_RESULT_OK) {
        logDebug("getPurchases() failed: " + getResponseDesc(response));
        return response;
      }
      if (!ownedItems.containsKey(RESPONSE_INAPP_ITEM_LIST)
          || !ownedItems.containsKey(RESPONSE_INAPP_PURCHASE_DATA_LIST)
          || !ownedItems.containsKey(RESPONSE_INAPP_SIGNATURE_LIST)) {
        logError("Bundle returned from getPurchases() doesn't contain required fields.");
        return IABHELPER_BAD_RESPONSE;
      }

      ArrayList<String> ownedSkus = ownedItems.getStringArrayList(RESPONSE_INAPP_ITEM_LIST);
      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);
        String sku = ownedSkus.get(i);
        if (Security.verifyPurchase(mSignatureBase64, purchaseData, signature)) {
          logDebug("Sku is owned: " + sku);
          Purchase purchase = new Purchase(itemType, purchaseData, signature);

          if (TextUtils.isEmpty(purchase.getToken())) {
            logWarn("BUG: empty/null token!");
            logDebug("Purchase data: " + purchaseData);
          }

          // Record ownership and token
          inv.addPurchase(purchase);
        } else {
          logWarn("Purchase signature verification **FAILED**. Not adding item.");
          logDebug("   Purchase data: " + purchaseData);
          logDebug("   Signature: " + signature);
          verificationFailed = true;
        }
      }

      continueToken = ownedItems.getString(INAPP_CONTINUATION_TOKEN);
      logDebug("Continuation token: " + continueToken);
    } while (!TextUtils.isEmpty(continueToken));

    return verificationFailed ? IABHELPER_VERIFICATION_FAILED : BILLING_RESPONSE_RESULT_OK;
  }
Example #4
0
  /**
   * Consumes a given in-app product. Consuming can only be done on an item that's owned, and as a
   * result of consumption, the user will no longer own it. This method may block or take long to
   * return. Do not call from the UI thread. For that, see {@link #consumeAsync}.
   *
   * @param itemInfo The PurchaseInfo that represents the item to consume.
   * @throws IabException if there is a problem during consumption.
   */
  void consume(Purchase itemInfo) throws IabException {
    checkSetupDone("consume");
    try {
      String token = itemInfo.getToken();
      String sku = itemInfo.getSku();
      if (token == null || token.equals("")) {
        logError("Can't consume " + sku + ". No token.");
        throw new IabException(
            IABHELPER_MISSING_TOKEN,
            "PurchaseInfo is missing token for sku: " + sku + " " + itemInfo);
      }

      logDebug("Consuming sku: " + sku + ", token: " + token);
      int response =
          mService.consumePurchase(BILLING_API_VERSION, mContext.getPackageName(), token);
      if (response == BILLING_RESPONSE_RESULT_OK) {
        logDebug("Successfully consumed sku: " + sku);
      } else {
        logDebug("Error consuming consuming sku " + sku + ". " + getResponseDesc(response));
        throw new IabException(response, "Error consuming sku " + sku);
      }
    } catch (RemoteException e) {
      throw new IabException(
          IABHELPER_REMOTE_EXCEPTION,
          "Remote exception while consuming. PurchaseInfo: " + itemInfo,
          e);
    }
  }
Example #5
0
  @Override
  public void queryPurchases(Preferences pref) {
    this.pref = pref;
    try {
      Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
      int response = ownedItems.getInt("RESPONSE_CODE");
      if (response == 0) {
        ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");

        for (int i = 0; i < ownedSkus.size(); i++) {
          String name = null;

          if (ownedSkus.get(i).equals("ryan")) name = "Ryan";
          else if (ownedSkus.get(i).equals("ash")) name = "Ash";
          else if (ownedSkus.get(i).equals("rob")) name = "Rob";
          else if (ownedSkus.get(i).equals("battle_cat")) name = "BattleCat";
          else if (ownedSkus.get(i).equals("xorp")) name = "Xorp";
          else if (ownedSkus.get(i).equals("rootsworth")) name = "Rootsworth";
          else if (ownedSkus.get(i).equals("snap")) name = "Snap";
          else if (ownedSkus.get(i).equals("metatron")) name = "Metatron";
          else if (ownedSkus.get(i).equals("abaddon")) name = "Abaddon";

          pref.putBoolean(name, true);
          pref.flush();
        }
      }
    } catch (RemoteException e) {
      e.printStackTrace();
    }
  }
Example #6
0
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
      billingService = IInAppBillingService.Stub.asInterface(service);
      String packageName = context.getPackageName();
      try {
        // check for in-app billing v3 support
        int response = billingService.isBillingSupported(3, packageName, ITEM_TYPE_INAPP);
        if (response != BILLING_RESPONSE_RESULT_OK) {
          if (listener != null) {
            listener.onSetupFinished(
                new Result(response, "Error checking for billing v3 support."));
          }
          return;
        }
      } catch (RemoteException e) {
        if (listener != null) {
          listener.onSetupFinished(
              new Result(
                  HELPER_REMOTE_EXCEPTION, "RemoteException while setting up in-app billing."));
        }
        e.printStackTrace();
        return;
      }

      if (listener != null) {
        listener.onSetupFinished(new Result(BILLING_RESPONSE_RESULT_OK, "Setup successful."));
      }
    }
Example #7
0
  @Click(R.id.get_buy_intent_button)
  public void getBuyIntent(View v) {
    try {
      Bundle buyIntentBundle =
          billingService.getBuyIntent(
              apiLevel,
              getPackageName(),
              skuName,
              "inapp",
              "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
      PendingIntent buyIntent = buyIntentBundle.getParcelable("BUY_INTENT");

      MainActivity.this.startIntentSenderForResult(
          buyIntent.getIntentSender(),
          requestCode,
          new Intent(),
          Integer.valueOf(0),
          Integer.valueOf(0),
          Integer.valueOf(0));
    } catch (Exception e) {
      String msg = "getBuyIntent: " + e.getMessage() + "\n";
      logView.append(msg);

      Log.e(TAG, msg);
      e.printStackTrace();
    }
  }
Example #8
0
  /**
   * Initiate the UI flow for an in-app purchase. Call this method to initiate an in-app purchase,
   * which will involve bringing up the Google Play screen. The calling activity will be paused
   * while the user interacts with Google Play, and the result will be delivered via the activity's
   * {@link android.app.Activity#onActivityResult} method, at which point you must call this
   * object's {@link #handleActivityResult} method to continue the purchase flow. This method MUST
   * be called from the UI thread of the Activity.
   *
   * @param act The calling activity.
   * @param sku The sku of the item to purchase.
   * @param itemType indicates if it's a product or a subscription (ITEM_TYPE_INAPP or
   *     ITEM_TYPE_SUBS)
   * @param requestCode A request code (to differentiate from other responses -- as in {@link
   *     android.app.Activity#startActivityForResult}).
   * @param listener The listener to notify when the purchase process finishes
   * @param extraData Extra data (developer payload), which will be returned with the purchase data
   *     when the purchase completes. This extra data will be permanently bound to that purchase and
   *     will always be returned when the purchase is queried.
   */
  public void launchPurchaseFlow(
      Activity act,
      String sku,
      String itemType,
      int requestCode,
      OnIabPurchaseFinishedListener listener,
      String extraData) {
    checkSetupDone("launchPurchaseFlow");
    flagStartAsync("launchPurchaseFlow");
    IabResult result;

    if (itemType.equals(ITEM_TYPE_SUBS) && !mSubscriptionsSupported) {
      IabResult r =
          new IabResult(IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE, "Subscriptions are not available.");
      if (listener != null) listener.onIabPurchaseFinished(r, null);
      return;
    }

    try {
      logDebug("Constructing buy intent for " + sku + ", item type: " + itemType);
      Bundle buyIntentBundle =
          mService.getBuyIntent(3, mContext.getPackageName(), sku, itemType, extraData);
      int response = getResponseCodeFromBundle(buyIntentBundle);
      if (response != BILLING_RESPONSE_RESULT_OK) {
        logError("Unable to buy item, Error response: " + getResponseDesc(response));

        result = new IabResult(response, "Unable to buy item");
        if (listener != null) listener.onIabPurchaseFinished(result, null);
        return;
      }

      PendingIntent pendingIntent = buyIntentBundle.getParcelable(RESPONSE_BUY_INTENT);
      logDebug("Launching buy intent for " + sku + ". Request code: " + requestCode);
      mRequestCode = requestCode;
      mPurchaseListener = listener;
      mPurchasingItemType = itemType;
      act.startIntentSenderForResult(
          pendingIntent.getIntentSender(),
          requestCode,
          new Intent(),
          Integer.valueOf(0),
          Integer.valueOf(0),
          Integer.valueOf(0));
    } catch (SendIntentException e) {
      logError("SendIntentException while launching purchase flow for sku " + sku);
      e.printStackTrace();

      result = new IabResult(IABHELPER_SEND_INTENT_FAILED, "Failed to send intent.");
      if (listener != null) listener.onIabPurchaseFinished(result, null);
    } catch (RemoteException e) {
      logError("RemoteException while launching purchase flow for sku " + sku);
      e.printStackTrace();

      result =
          new IabResult(
              IABHELPER_REMOTE_EXCEPTION, "Remote exception while starting purchase flow");
      if (listener != null) listener.onIabPurchaseFinished(result, null);
    }
  }
  public void purchase(final String sku, final String transactionId) {
    Log.d("XXX", "Starting purchase for: " + sku);
    PaymentsCache pc = new PaymentsCache(context);
    Boolean isBlocked = pc.getConsumableFlag("block", sku);
    //		if(isBlocked){
    //			Log.d("XXX", "Is awaiting payment confirmation");
    //			error("Awaiting payment confirmation");
    //			return;
    //		}
    final String hash = transactionId;

    Bundle buyIntentBundle;
    try {
      buyIntentBundle =
          mService.getBuyIntent(
              3, context.getApplicationContext().getPackageName(), sku, "inapp", hash);
    } catch (RemoteException e) {
      //			Log.d("XXX", "Error: " + e.getMessage());
      error(e.getMessage());
      return;
    }
    Object rc = buyIntentBundle.get("RESPONSE_CODE");
    int responseCode = 0;
    if (rc == null) {
      responseCode = PaymentsManager.BILLING_RESPONSE_RESULT_OK;
    } else if (rc instanceof Integer) {
      responseCode = ((Integer) rc).intValue();
    } else if (rc instanceof Long) {
      responseCode = (int) ((Long) rc).longValue();
    }
    //		Log.d("XXX", "Buy intent response code: " + responseCode);
    if (responseCode == 1 || responseCode == 3 || responseCode == 4) {
      canceled();
      return;
    }

    PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
    pc.setConsumableValue("validation_hash", sku, hash);
    try {
      if (context == null) {
        //				Log.d("XXX", "No context!");
      }
      if (pendingIntent == null) {
        //				Log.d("XXX", "No pending intent");
      }
      //			Log.d("XXX", "Starting activity for purchase!");
      context.startIntentSenderForResult(
          pendingIntent.getIntentSender(),
          PaymentsManager.REQUEST_CODE_FOR_PURCHASE,
          new Intent(),
          Integer.valueOf(0),
          Integer.valueOf(0),
          Integer.valueOf(0));
    } catch (SendIntentException e) {
      error(e.getMessage());
    }
  }
 @Override
 public void consume(@NonNull Purchase purchase) throws BillingException {
   try {
     int rc = delegate.consumePurchase(3, packageName, purchase.purchaseToken());
     BillingException.checkCode(rc);
   } catch (RemoteException e) {
     throw new UnsupportedOperationException(e);
   }
 }
 @Override
 public boolean arePurchasesSupported(@NonNull @ProductType String type) throws BillingException {
   try {
     int rc = delegate.isBillingSupported(API_VERSION, packageName, type);
     BillingException.checkCode(rc);
     return true;
   } catch (RemoteException e) {
     throw new BillingException(e);
   }
 }
Example #12
0
  /**
   * Initiate the UI flow for an in-app purchase. Call this method to initiate an in-app purchase,
   * which will involve bringing up the Google Play screen. The calling activity will be paused
   * while the user interacts with Google Play, and the result will be delivered via the activity's
   * {@link android.app.Activity#onActivityResult} method, at which point you must call this
   * object's {@link #handleActivityResult} method to continue the purchase flow. This method MUST
   * be called from the UI thread of the Activity.
   *
   * @param act The calling activity.
   * @param sku The sku of the item to purchase.
   * @param requestCode A request code (to differentiate from other responses -- as in {@link
   *     android.app.Activity#startActivityForResult}).
   * @param listener The listener to notify when the purchase process finishes
   * @param extraData Extra data (developer payload), which will be returned with the purchase data
   *     when the purchase completes. This extra data will be permanently bound to that purchase and
   *     will always be returned when the purchase is queried.
   */
  public void launchPurchaseFlow(
      Activity act,
      String sku,
      int requestCode,
      OnIabPurchaseFinishedListener listener,
      String extraData) {
    checkSetupDone("launchPurchaseFlow");
    flagStartAsync("launchPurchaseFlow");
    IabResult result;

    try {
      logDebug("Constructing buy intent for " + sku);
      Bundle buyIntentBundle =
          mService.getBuyIntent(
              BILLING_API_VERSION, mContext.getPackageName(), sku, ITEM_TYPE_INAPP, extraData);
      int response = getResponseCodeFromBundle(buyIntentBundle);
      if (response != BILLING_RESPONSE_RESULT_OK) {
        logError("Unable to buy item, Error response: " + getResponseDesc(response));

        result = new IabResult(response, "Unable to buy item", requestCode);
        if (listener != null) listener.onIabPurchaseFinished(result, null);
      } else {
        PendingIntent pendingIntent = buyIntentBundle.getParcelable(RESPONSE_BUY_INTENT);
        logDebug("Launching buy intent for " + sku + ". Request code: " + requestCode);
        SYSLOG("MoSync Launching buy intent for " + sku + ". Request code: " + requestCode);
        mRequestCode = requestCode;
        mPurchaseListener = listener;
        act.startIntentSenderForResult(
            pendingIntent.getIntentSender(),
            requestCode,
            new Intent(Consts.METHOD_REQUEST_PURCHASE),
            0,
            0,
            0);
      }
    } catch (SendIntentException e) {
      logError("SendIntentException while launching purchase flow for sku " + sku);
      SYSLOG("MoSync SendIntentException while launching purchase flow for sku " + sku);
      e.printStackTrace();

      result = new IabResult(IABHELPER_SEND_INTENT_FAILED, "Failed to send intent.", requestCode);
      if (listener != null) listener.onIabPurchaseFinished(result, null);
    } catch (RemoteException e) {
      logError("RemoteException while launching purchase flow for sku " + sku);
      SYSLOG("MoSync RemoteException while launching purchase flow for sku " + sku);
      e.printStackTrace();

      result =
          new IabResult(
              IABHELPER_REMOTE_EXCEPTION,
              "Remote exception while starting purchase flow",
              requestCode);
      if (listener != null) listener.onIabPurchaseFinished(result, null);
    }
  }
Example #13
0
  @Click(R.id.consume_purchase)
  public void consumePurchase(View v) {
    try {
      Bundle ownedItems = billingService.getPurchases(apiLevel, getPackageName(), "inapp", null);

      ArrayList<String> purchaseDataList =
          ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
      for (String purchaseData : purchaseDataList) {
        JSONObject obj = new JSONObject(purchaseData);
        String purchaseToken = obj.optString("token", obj.optString("purchaseToken"));

        billingService.consumePurchase(apiLevel, getPackageName(), purchaseToken);
        logView.append("消費しました\n");
      }
    } catch (Exception e) {
      String msg = "getPurchases: " + e.getMessage() + "\n";
      logView.append(msg);

      Log.e(TAG, msg);
      e.printStackTrace();
    }
  }
Example #14
0
  @Click(R.id.billing_supported_button)
  public void billingSupported(View v) {
    try {
      int result = billingService.isBillingSupported(apiLevel, getPackageName(), "inapp");
      String msg = "isBillingSupported:" + responseCode(result) + "\n";
      logView.append(msg);

      Log.d(TAG, msg);
    } catch (RemoteException e) {
      String msg = "isBillingSupported:" + e.getMessage() + "\n";
      logView.append(msg);

      Log.e(TAG, msg);
      e.printStackTrace();
    }
  }
Example #15
0
 @Override
 public void makePurchase(String itemID, Preferences pref) {
   this.pref = pref;
   try {
     Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(), itemID, "inapp", null);
     PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
     startIntentSenderForResult(
         pendingIntent.getIntentSender(),
         1001,
         new Intent(),
         Integer.valueOf(0),
         Integer.valueOf(0),
         Integer.valueOf(0));
   } catch (RemoteException e) {
     e.printStackTrace();
   } catch (SendIntentException e) {
     e.printStackTrace();
   }
 }
 @NonNull
 @Override
 public PendingIntent getProductBuyIntent(
     @NonNull @ProductType String type, @NonNull String sku, @Nullable String developerPayload)
     throws BillingException {
   try {
     Bundle response =
         delegate.getBuyIntent(API_VERSION, packageName, sku, type, developerPayload);
     checkBundle(response);
     //noinspection UnnecessaryLocalVariable
     PendingIntent pendingIntent = response.getParcelable("BUY_INTENT");
     if (pendingIntent == null) {
       throw new BillingException.UnexpectedDataException("BUY_INTENT == null");
     }
     return pendingIntent;
   } catch (RemoteException e) {
     throw new BillingException(e);
   }
 }
Example #17
0
  /** Get sku details for an item that is not in the inventory. */
  public SkuDetails getSkuDetails(String sku) throws IabException {
    logDebug("Querying SKU details for one item.");
    SYSLOG("MoSync Querying SKU details for one item: " + sku);
    Bundle querySkus = new Bundle();
    ArrayList<String> skuList = new ArrayList<String>();
    skuList.add(sku);
    querySkus.putStringArrayList(GET_SKU_DETAILS_ITEM_LIST, skuList);
    try {
      Bundle skuDetails =
          mService.getSkuDetails(
              BILLING_API_VERSION, mContext.getPackageName(), ITEM_TYPE_INAPP, querySkus);

      if (!skuDetails.containsKey(RESPONSE_GET_SKU_DETAILS_LIST)) {
        int response = getResponseCodeFromBundle(skuDetails);
        SYSLOG("@@MoSync maPurchaseCreate querySkuDetails response error  " + response);
        if (response != BILLING_RESPONSE_RESULT_OK) {
          logDebug("getSkuDetails() failed: " + getResponseDesc(response));
        } else {
          logError("getSkuDetails() returned a bundle with neither an error nor a detail list.");
        }
        return null;
      }

      ArrayList<String> responseList = skuDetails.getStringArrayList(RESPONSE_GET_SKU_DETAILS_LIST);

      for (String thisResponse : responseList) {
        SkuDetails details = new SkuDetails(thisResponse);
        logDebug("Got sku details: " + details);
        return details;
      }
      return null;

    } catch (RemoteException e) {
      SYSLOG("@@MoSync remote exception while getting sku details");
      throw new IabException(
          IABHELPER_REMOTE_EXCEPTION, "Remote exception while getting sku details.", e);
    } catch (JSONException e) {
      SYSLOG("@@MoSync JSON exception while getting sku details");
      throw new IabException(
          IABHELPER_BAD_RESPONSE, "Error parsing JSON response while getting sku details.", e);
    }
  }
Example #18
0
  int querySkuDetails(String itemType, Inventory inv, List<String> moreSkus)
      throws RemoteException, JSONException {
    logDebug("Querying SKU details.");
    ArrayList<String> skuList = new ArrayList<String>();
    skuList.addAll(inv.getAllOwnedSkus(itemType));
    if (moreSkus != null) {
      for (String sku : moreSkus) {
        if (!skuList.contains(sku)) {
          skuList.add(sku);
        }
      }
    }

    if (skuList.size() == 0) {
      logDebug("queryPrices: nothing to do because there are no SKUs.");
      return BILLING_RESPONSE_RESULT_OK;
    }

    Bundle querySkus = new Bundle();
    querySkus.putStringArrayList(GET_SKU_DETAILS_ITEM_LIST, skuList);
    Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName(), itemType, querySkus);

    if (!skuDetails.containsKey(RESPONSE_GET_SKU_DETAILS_LIST)) {
      int response = getResponseCodeFromBundle(skuDetails);
      if (response != BILLING_RESPONSE_RESULT_OK) {
        logDebug("getSkuDetails() failed: " + getResponseDesc(response));
        return response;
      } else {
        logError("getSkuDetails() returned a bundle with neither an error nor a detail list.");
        return IABHELPER_BAD_RESPONSE;
      }
    }

    ArrayList<String> responseList = skuDetails.getStringArrayList(RESPONSE_GET_SKU_DETAILS_LIST);

    for (String thisResponse : responseList) {
      SkuDetails d = new SkuDetails(itemType, thisResponse);
      logDebug("Got sku details: " + d);
      inv.addSkuDetails(d);
    }
    return BILLING_RESPONSE_RESULT_OK;
  }
  @NonNull
  @Override
  public ReceiptResponse getProductPurchases(
      @NonNull @ProductType String type, String continueToken) throws BillingException {
    try {
      Bundle data = delegate.getPurchases(API_VERSION, packageName, type, continueToken);
      checkBundle(data);
      ArrayList<String> skus = data.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
      ArrayList<String> purchases = data.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
      ArrayList<String> signatures = data.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
      String nextToken = data.getString("INAPP_CONTINUATION_TOKEN");

      if (skus == null
          || purchases == null
          || signatures == null
          || skus.size() != purchases.size()
          || purchases.size() != signatures.size()) {
        throw new BillingException("unexpected data in response");
      }

      List<Receipt> receipts = new ArrayList<>(skus.size());

      for (int i = 0; i < skus.size(); i++) {
        String json = purchases.get(i);
        String signature = signatures.get(i);
        Purchase purchase = gson.fromJson(json, Purchase.class);
        Receipt receipt =
            new Receipt.Builder()
                .purchase(purchase)
                .signature(signature)
                .originalJson(json)
                .build();
        receipts.add(receipt);
      }

      return ReceiptResponse.Factory.make(receipts, nextToken);
    } catch (RemoteException e) {
      throw new BillingException(e);
    }
  }
Example #20
0
  @Click(R.id.get_sku_details_button)
  public void getSkuDetails(View v) {
    try {
      ArrayList<String> itemList = new ArrayList<String>();
      itemList.add(skuName);

      Bundle skusBundle = new Bundle();
      skusBundle.putStringArrayList("ITEM_ID_LIST", itemList);

      Bundle details =
          billingService.getSkuDetails(apiLevel, getPackageName(), "inapp", skusBundle);

      int responseCode = details.getInt("RESPONSE_CODE");
      ArrayList<String> responseList = details.getStringArrayList("DETAILS_LIST");

      if (responseList.size() == 0) {
        String msg = "getSkuDetails: empty" + "\n";
        ;
        logView.append(msg);

        Log.d(TAG, msg);
      }
      for (String info : responseList) {
        String msg = "getSkuDetails: " + info + "\n";
        ;
        logView.append(msg);

        Log.d(TAG, msg);
      }

    } catch (RemoteException e) {
      String msg = "getSkuDetails: " + e.getMessage() + "\n";
      logView.append(msg);

      Log.e(TAG, msg);
      e.printStackTrace();
    }
  }
  @NonNull
  @Override
  public List<Product> getProductDetails(@NonNull @ProductType String type, List<String> skuList)
      throws BillingException {
    try {
      Bundle skuBundle = new Bundle();
      skuBundle.putStringArrayList("ITEM_ID_LIST", new ArrayList<>(skuList));
      Bundle response = delegate.getSkuDetails(API_VERSION, packageName, type, skuBundle);
      checkBundle(response);

      List<String> jsons = response.getStringArrayList("DETAILS_LIST");
      if (jsons == null) {
        return Collections.emptyList();
      }
      List<Product> products = new ArrayList<>(jsons.size());
      for (String json : jsons) {
        Product product = gson.fromJson(json, Product.class);
        products.add(product);
      }
      return products;
    } catch (RemoteException e) {
      throw new BillingException(e);
    }
  }
Example #22
0
 public Bundle getBuyIntent(String sku, String extraData) throws RemoteException {
   return billingService.getBuyIntent(
       3, context.getPackageName(), sku, ITEM_TYPE_INAPP, extraData);
 }
Example #23
0
 public Bundle getPurchases(String continueToken) throws RemoteException {
   return billingService.getPurchases(
       3, context.getPackageName(), ITEM_TYPE_INAPP, continueToken);
 }
Example #24
0
 public Bundle getSkuDetails(Bundle querySkus) throws RemoteException {
   return billingService.getSkuDetails(3, context.getPackageName(), ITEM_TYPE_INAPP, querySkus);
 }