예제 #1
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;
  }
예제 #2
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);
    }
  }
 /**
  * Returns a list of all purchases on a specific itemNumber
  *
  * @param itemNumber the itemNumber of the product you want to find all purchases for
  * @return ArrayList<Purchase>
  */
 public ArrayList<Purchase> getPurchasesByItemNumber(long itemNumber) {
   ArrayList<Purchase> returnList = new ArrayList<Purchase>();
   for (Purchase purch : _purchaseCollection.values()) {
     if (purch.getItemNumber() == itemNumber) returnList.add(purch);
   }
   return returnList;
 }
예제 #4
0
 /** Returns a list of all owned product IDs of a given type */
 List<String> getAllOwnedSkus(String itemType) {
   List<String> result = new ArrayList<String>();
   for (Purchase p : mPurchaseMap.values()) {
     if (p.getItemType().equals(itemType)) result.add(p.getSku());
   }
   return result;
 }
예제 #5
0
 @Test
 public void testGetPurchase() throws Exception {
   Inventory inventory = new Inventory();
   Purchase p = mock(Purchase.class);
   when(p.getSku()).thenReturn("sku1");
   inventory.addPurchase(p);
   assertThat(inventory.getPurchase("sku1")).isSameAs(p);
 }
예제 #6
0
 public boolean equals(Purchase pur) {
   if (this.item.equals(pur.getItem())
       && this.category == pur.getCategory()
       && this.date.equals(pur.getDate())) {
     return true;
   } else {
     return false;
   }
 }
예제 #7
0
 public static JSONArray listToArray(java.util.List<Purchase> list) {
   JSONArray array = new JSONArray();
   if (list != null && !list.isEmpty()) {
     for (Purchase model : list) {
       JSONObject jsonObject = model.toJsonObject();
       array.add(jsonObject);
     }
   }
   return array;
 }
 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);
 }
예제 #9
0
  @Test
  public void testGetAllOwnedSkus() throws Exception {
    Inventory inventory = new Inventory();
    Purchase p1 = mock(Purchase.class);
    when(p1.getSku()).thenReturn("sku1");

    Purchase p2 = mock(Purchase.class);
    when(p2.getSku()).thenReturn("sku2");

    inventory.addPurchase(p1);
    inventory.addPurchase(p2);

    assertThat(inventory.getAllOwnedSkus()).containsOnly("sku1", "sku2");
  }
예제 #10
0
  public boolean addRecord(Purchase purchase) {

    // extract data from item;
    ContentValues contentValues = new ContentValues();
    contentValues.put(COL_2, purchase.getName());
    contentValues.put(COL_3, purchase.getPrice());
    contentValues.put(COL_4, purchase.getDate());
    contentValues.put(COL_5, purchase.getNotePath());
    // I am storing the name of of the enum, not the int value
    contentValues.put(COL_6, purchase.getCategory().name());
    SQLiteDatabase db = getWritableDatabase();
    db.insert(PURCHASE_TABLE, null, contentValues);
    db.close();
    return true;
  }
예제 #11
0
  public static void main(String[] args) {
    MediatorImpl mediator = new MediatorImpl();
    System.out.println("-----------採購人員採購電腦-----------");
    Purchase purchase = new Purchase(mediator);
    purchase.buyIBMComputer(100);
    System.out.println("-----------銷售人員銷售電腦-----------");
    Sale sale = new Sale(mediator);
    sale.sellIBMComputer(1);
    System.out.println("-----------庫房管理人員清倉處理-----------");
    Stock stock = new Stock(mediator);
    stock.clearStock();

    // 用一個中介物件封裝一系列的物件交互作用,中介者使各物件不需要直接的互動,從而使其偶和鬆散,而且可以獨立的改變他們之間的交互作用
    // Define an object that encapsulates how a set of objects interact. Mediator promotes loose
    // coupling by keeping objects from referring to each other explicitly. and it lets you vary
    // their interaction independently.
  }
예제 #12
0
  public static void main(String[] args) {

    Scanner scan = new Scanner(System.in);

    String another = "y";

    Purchase purchase = new Purchase();

    System.out.println("Welcome to the coffee shop!");
    System.out.println("Please enter Customer Name: ");
    String name;
    name = scan.nextLine();
    Customer customer = new Customer(name, 0);

    while (!another.equalsIgnoreCase("n")) {
      System.out.println("Pick a flavor: light/medium/bold");
      String flavor = scan.nextLine();
      System.out.println("Pick a size: malenky/ceredny/velicky");
      String size = scan.nextLine();

      double price;
      if (size.equalsIgnoreCase("malenky")) {
        price = 1;
      } else if (size.equalsIgnoreCase("ceredny")) {
        price = 2;
      } else {
        price = 3;
      }

      purchase.addCoffee(new Coffee(flavor, size, price));

      customer.setNumCoffees(customer.getNumCoffees() + 1);

      System.out.println("Your purchase is currently: " + purchase);
      System.out.println("Would you like to buy another cup? (y/n)");
      another = scan.nextLine();
    }

    Order order = new Order(customer, purchase);

    System.out.println("Your order is: " + order);
    System.out.println("Exiting the coffee shop.");

    scan.close();
  }
 /**
  * Add a purchase to the collection
  *
  * @param purchase the purchase to be added
  * @return boolean returns true if added / false if it's not
  */
 public boolean addPurchase(Purchase purchase) {
   int key = purchase.getPurchaseId();
   if (!_purchaseCollection.containsKey(key)) {
     _purchaseCollection.put(key, purchase);
     _lastKey++;
     return true;
   }
   return false;
 }
  @Test
  public void testImplicit() {
    KieServices ks = KieServices.Factory.get();
    KieContainer kContainer = ks.getKieClasspathContainer();
    KieSession ksession = kContainer.newKieSession("ksession-samples");
    ProcessInstance processInstance = ksession.startProcess("approveorder");

    Purchase purchase = new Purchase();
    purchase.setCustomerName("sekhar");
    purchase.setPaymentMethod(PaymentMethod.DEBIT);
    purchase.setSubtotal(0);
    ksession.insert(purchase);
    int rulesFired = ksession.fireAllRules();
    System.out.println("facthandles count -->" + ksession.getFactHandles().size());
    // Check the count
    Assert.assertEquals(1, rulesFired);
    // Check the node exists
    // assertNodeExists(processInstance, "Discount","printout");
    // Check the node names
    // assertNodeTriggered(processInstance.getId(),"Discount","printout");
    // Assert completed
    assertProcessInstanceCompleted(processInstance.getId(), ksession);
  }
        public void onConsumeFinished(Purchase purchase, IabResult result) {
          Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result);

          purchase.setSku(
              SkuManager.getInstance().getSku(purchase.getAppstoreName(), purchase.getSku()));

          if (result.isFailure()) {
            Log.e(TAG, "Error while consuming: " + result);
            UnityPlayer.UnitySendMessage(
                EVENT_MANAGER, CONSUME_PURCHASE_FAILED_CALLBACK, result.getMessage());
            return;
          }
          Log.d(TAG, "Consumption successful. Provisioning.");
          String jsonPurchase;
          try {
            jsonPurchase = purchaseToJson(purchase);
          } catch (JSONException e) {
            UnityPlayer.UnitySendMessage(
                EVENT_MANAGER, CONSUME_PURCHASE_FAILED_CALLBACK, "Couldn't serialize the purchase");
            return;
          }
          UnityPlayer.UnitySendMessage(
              EVENT_MANAGER, CONSUME_PURCHASE_SUCCEEDED_CALLBACK, jsonPurchase);
        }
예제 #16
0
  @Test
  public void testGetAllOwnedSkusForItemType() throws Exception {
    Inventory inventory = new Inventory();
    Purchase p1 = mock(Purchase.class);
    when(p1.getItemType()).thenReturn(ItemType.INAPP);
    when(p1.getSku()).thenReturn("sku_inapp");

    Purchase p2 = mock(Purchase.class);
    when(p2.getItemType()).thenReturn(ItemType.SUBS);
    when(p2.getSku()).thenReturn("sku_sub");

    inventory.addPurchase(p1);
    inventory.addPurchase(p2);

    assertThat(inventory.getAllOwnedSkus(ItemType.SUBS)).containsExactly("sku_sub");
  }
예제 #17
0
  public ArrayList<Purchase> getRecords() {
    ArrayList<Purchase> purchases = new ArrayList<Purchase>();
    SQLiteDatabase db = getWritableDatabase();
    String query = "SELECT * FROM " + PURCHASE_TABLE;
    Cursor resultSet = db.rawQuery(query, null);

    while (resultSet.moveToNext()) {
      Purchase current = new Purchase();
      current.setID(resultSet.getInt(0));
      current.setName(resultSet.getString(1));
      current.setPrice(resultSet.getFloat(2));
      current.setDate(resultSet.getLong(3));
      current.setNotePath(resultSet.getString(4));
      current.setCategory(resultSet.getString(5));
      purchases.add(current);
    }
    resultSet.close();
    db.close();
    return purchases;
  }
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
          StoreItem purchasedItem = null;
          int index = 0;

          mHelper.flagEndAsync();

          if (purchase == null) {
            Toast.makeText(
                    c,
                    "We can't find the requested item. Please try again soon!",
                    Toast.LENGTH_SHORT)
                .show();
            return;
          }

          for (StoreItem item : getAllStoreItems(c)) {
            if (item.googleSKU.compareTo(purchase.getSku()) == 0) {
              purchasedItem = item;
              break;
            }

            index++;
          }

          if (result.isFailure() || purchasedItem == null) {
            Log.d("FF PURCHASE", "Error purchasing: " + result);
            purchaseListener.purchaseFailed(purchasedItem, purchase);
            return;
          } else {
            purchasedItem.isPurchased = true;
            getAllStoreItems(c).get(index).isPurchased = true;
            purchaseListener.purchaseSuccess(purchasedItem, purchase);
          }

          writePurchasedItems(c);
        }
 @Test
 public void testSetEmail() throws Exception {
   purchase.setEmail("bbb");
   assertEquals("bbb", purchase.getEmail());
 }
 @Test
 public void testGetEmail() throws Exception {
   assertEquals("number", purchase.getEmail());
   purchase = new Purchase();
   assertNull(purchase.getEmail());
 }
 @Test
 public void testSetCreditCard() throws Exception {
   purchase.setCreditCard("aaa");
   assertEquals("aaa", purchase.getCreditCard());
 }
 @Test
 public void testGetCreditCard() throws Exception {
   assertEquals("credit", purchase.getCreditCard());
   purchase = new Purchase();
   assertNull(purchase.getCreditCard());
 }
 @Override
 public Object currentItem() {
   return obj.currentItem(state);
 }
예제 #24
0
 // 清倉處理
 private void clearStock() {
   sale.offSale();
   purchase.refuseBuyIBM(); // 要求不採購
 }
예제 #25
0
  public Purchase unmarshall(StaxUnmarshallerContext context) throws Exception {
    Purchase purchase = new Purchase();
    int originalDepth = context.getCurrentDepth();
    int targetDepth = originalDepth + 1;

    if (context.isStartOfDocument()) targetDepth += 1;

    while (true) {
      XMLEvent xmlEvent = context.nextEvent();
      if (xmlEvent.isEndDocument()) return purchase;

      if (xmlEvent.isAttribute() || xmlEvent.isStartElement()) {

        if (context.testExpression("hostReservationId", targetDepth)) {
          purchase.setHostReservationId(StringStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("hostIdSet", targetDepth)) {
          purchase.withHostIdSet(new ArrayList<String>());
          continue;
        }

        if (context.testExpression("hostIdSet/item", targetDepth)) {
          purchase.withHostIdSet(StringStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("instanceFamily", targetDepth)) {
          purchase.setInstanceFamily(StringStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("paymentOption", targetDepth)) {
          purchase.setPaymentOption(StringStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("upfrontPrice", targetDepth)) {
          purchase.setUpfrontPrice(StringStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("hourlyPrice", targetDepth)) {
          purchase.setHourlyPrice(StringStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("currencyCode", targetDepth)) {
          purchase.setCurrencyCode(StringStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }

        if (context.testExpression("duration", targetDepth)) {
          purchase.setDuration(IntegerStaxUnmarshaller.getInstance().unmarshall(context));
          continue;
        }
      } else if (xmlEvent.isEndElement()) {
        if (context.getCurrentDepth() < originalDepth) {
          return purchase;
        }
      }
    }
  }
예제 #26
0
  /**
   * 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) {
    IabResult result;
    if (requestCode != mRequestCode) return false;

    checkSetupDone("handleActivityResult");

    // end of async purchase operation
    flagEndAsync();

    if (data == null) {
      logError("Null data in IAB activity result.");
      result = new IabResult(IABHELPER_BAD_RESPONSE, "Null data in IAB result", requestCode);
      if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(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) {
      logDebug("Successful resultcode from purchase activity.");
      logDebug("Purchase data: " + purchaseData);
      logDebug("Data signature: " + dataSignature);
      logDebug("Extras: " + data.getExtras());

      if (purchaseData == null || dataSignature == null) {
        logError("BUG: either purchaseData or dataSignature is null.");
        logDebug("Extras: " + data.getExtras().toString());
        result =
            new IabResult(
                IABHELPER_UNKNOWN_ERROR,
                "IAB returned null purchaseData or dataSignature",
                requestCode);
        if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
        return true;
      }

      Purchase purchase = null;
      try {
        purchase = new Purchase(purchaseData, dataSignature);
        String sku = purchase.getSku();

        // Verify signature
        if (!Security.verifyPurchase(mSignatureBase64, purchaseData, dataSignature)) {
          logError("Purchase signature verification FAILED for sku " + sku);
          result =
              new IabResult(
                  IABHELPER_VERIFICATION_FAILED,
                  "Signature verification failed for sku " + sku,
                  requestCode);
          if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, purchase);
          return true;
        }
        logDebug("Purchase signature successfully verified.");
      } catch (JSONException e) {
        logError("Failed to parse purchase data.");
        e.printStackTrace();
        result =
            new IabResult(IABHELPER_BAD_RESPONSE, "Failed to parse purchase data.", requestCode);
        if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
        return true;
      }

      if (mPurchaseListener != null) {
        mPurchaseListener.onIabPurchaseFinished(
            new IabResult(BILLING_RESPONSE_RESULT_OK, "Success", requestCode), purchase);
      }
    } else if (resultCode == Activity.RESULT_OK) {
      // result code was OK, but in-app billing response was not OK.
      logDebug(
          "Result code was OK but in-app billing response was not OK: "
              + getResponseDesc(responseCode));
      if (mPurchaseListener != null) {
        result = new IabResult(responseCode, "Problem purchashing item.", requestCode);
        mPurchaseListener.onIabPurchaseFinished(result, null);
      }
    } else if (resultCode == Activity.RESULT_CANCELED) {
      logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode));
      result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled.", requestCode);
      if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
    } else {
      logError(
          "Purchase failed. Result code: "
              + Integer.toString(resultCode)
              + ". Response: "
              + getResponseDesc(responseCode));
      result =
          new IabResult(
              IABHELPER_UNKNOWN_PURCHASE_RESPONSE, "Unknown purchase response.", requestCode);
      if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
    }
    return true;
  }
 @Override
 public void first() {
   state = obj.count() - 1;
 }
예제 #28
0
 void addPurchase(Purchase p) {
   mPurchaseMap.put(p.getSku(), p);
 }
 /**
  * Serialize purchase data to json
  *
  * @param purchase purchase data
  * @return json string
  * @throws JSONException
  */
 private String purchaseToJson(Purchase purchase) throws JSONException {
   return new JSONStringer()
       .object()
       .key("itemType")
       .value(purchase.getItemType())
       .key("orderId")
       .value(purchase.getOrderId())
       .key("packageName")
       .value(purchase.getPackageName())
       .key("sku")
       .value(purchase.getSku())
       .key("purchaseTime")
       .value(purchase.getPurchaseTime())
       .key("purchaseState")
       .value(purchase.getPurchaseState())
       .key("developerPayload")
       .value(purchase.getDeveloperPayload())
       .key("token")
       .value(purchase.getToken())
       .key("originalJson")
       .value(purchase.getOriginalJson())
       .key("signature")
       .value(purchase.getSignature())
       .key("appstoreName")
       .value(purchase.getAppstoreName())
       .endObject()
       .toString();
 }
예제 #30
0
  /**
   * 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;
  }