Exemplo n.º 1
0
 public void onPurchaseStateChange(Consts.PurchaseState purchaseState, string itemId, int quantity, long purchaseTime, string developerPayload)         //bool fromBackgroundTHread = false)
 {
     m_activity.RunOnUiThread(() =>
     {
         Toast.MakeText(m_activity, string.Format("PurchaseState: {0}", purchaseState.ToString()), ToastLength.Long).Show();
     });
 }
Exemplo n.º 2
0
			public VerifiedPurchase(Consts.PurchaseState purchaseState, string notificationId,
					string productId, string orderId, long purchaseTime, string developerPayload) {
				this.purchaseState = purchaseState;
				this.notificationId = notificationId;
				this.productId = productId;
				this.orderId = orderId;
				this.purchaseTime = purchaseTime;
				this.developerPayload = developerPayload;
			}
Exemplo n.º 3
0
 public VerifiedPurchase(Consts.PurchaseState purchaseState, string notificationId,
                         string productId, string orderId, long purchaseTime, string developerPayload)
 {
     this.purchaseState    = purchaseState;
     this.notificationId   = notificationId;
     this.productId        = productId;
     this.orderId          = orderId;
     this.purchaseTime     = purchaseTime;
     this.developerPayload = developerPayload;
 }
 public Transaction(String orderId, String productId, String packageName, PurchaseState purchaseState,
     String notificationId, long purchaseTime, String developerPayload)
 {
     this.orderId = orderId;
     this.productId = productId;
     this.packageName = packageName;
     this.purchaseState = purchaseState;
     this.notificationId = notificationId;
     this.purchaseTime = purchaseTime;
     this.developerPayload = developerPayload;
 }
Exemplo n.º 5
0
        /**
         * Inserts a purchased product into the database. There may be multiple
         * rows in the table for the same product if it was purchased multiple times
         * or if it was refunded.
         * @param orderId the order ID (matches the value in the product list)
         * @param productId the product ID (sku)
         * @param state the state of the purchase
         * @param purchaseTime the purchase time (in milliseconds since the epoch)
         * @param developerPayload the developer provided "payload" associated with
         *     the order.
         */
        private void insertOrder(string orderId, string productId, Consts.PurchaseState state,
                                 long purchaseTime, string developerPayload)
        {
            ContentValues values = new ContentValues();

            values.Put(HISTORY_ORDER_ID_COL, orderId);
            values.Put(HISTORY_PRODUCT_ID_COL, productId);
            values.Put(HISTORY_STATE_COL, (int)state);
            values.Put(HISTORY_PURCHASE_TIME_COL, purchaseTime);
            values.Put(HISTORY_DEVELOPER_PAYLOAD_COL, developerPayload);
            mDb.Replace(PURCHASE_HISTORY_TABLE_NAME, null /* nullColumnHack */, values);
        }
Exemplo n.º 6
0
        /**
         * Adds the given purchase information to the database and returns the total
         * number of times that the given product has been purchased.
         * @param orderId a string identifying the order
         * @param productId the product ID (sku)
         * @param purchaseState the purchase state of the product
         * @param purchaseTime the time the product was purchased, in milliseconds
         * since the epoch (Jan 1, 1970)
         * @param developerPayload the developer provided "payload" associated with
         *     the order
         * @return the number of times the given product has been purchased.
         */
        public int updatePurchase(string orderId, string productId, Consts.PurchaseState purchaseState, long purchaseTime, string developerPayload)
        {
            insertOrder(orderId, productId, purchaseState, purchaseTime, developerPayload);

            ICursor cursor = mDb.Query(PURCHASE_HISTORY_TABLE_NAME, HISTORY_COLUMNS,
                                       HISTORY_PRODUCT_ID_COL + "=?", new String[] { productId }, null, null, null, null);

            if (cursor == null)
            {
                return(0);
            }
            int quantity = 0;

            try
            {
                // Count the number of times the product was purchased
                while (cursor.MoveToNext())
                {
                    int stateIndex             = cursor.GetInt(2);
                    Consts.PurchaseState state = (Consts.PurchaseState)stateIndex;
                    // Note that a refunded purchase is treated as a purchase. Such
                    // a friendly refund policy is nice for the user.
                    if (state == Consts.PurchaseState.PURCHASED || state == Consts.PurchaseState.REFUNDED)
                    {
                        quantity += 1;
                    }
                }

                // Update the "purchased items" table
                updatePurchasedItem(productId, quantity);
            }
            finally
            {
                if (cursor != null)
                {
                    cursor.Close();
                }
            }
            return(quantity);
        }
Exemplo n.º 7
0
        /**
         * Notifies the application of purchase state changes. The application
         * can offer an item for sale to the user via
         * {@link BillingService#requestPurchase(String)}. The BillingService
         * calls this method after it gets the response. Another way this method
         * can be called is if the user bought something on another device running
         * this same app. Then Android Market notifies the other devices that
         * the user has purchased an item, in which case the BillingService will
         * also call this method. Finally, this method can be called if the item
         * was refunded.
         * @param purchaseState the state of the purchase request (PURCHASED,
         *     CANCELED, or REFUNDED)
         * @param productId a string identifying a product for sale
         * @param orderId a string identifying the order
         * @param purchaseTime the time the product was purchased, in milliseconds
         *     since the epoch (Jan 1, 1970)
         * @param developerPayload the developer provided "payload" associated with
         *     the order
         */
        public static void purchaseResponse(
            Context context, Consts.PurchaseState purchaseState, String productId,
            String orderId, long purchaseTime, String developerPayload)
        {
            // Update the database with the purchase state. We shouldn't do that
            // from the main thread so we do the work in a background thread.
            // We don't update the UI here. We will update the UI after we update
            // the database because we need to read and update the current quantity
            // first.

            new System.Threading.Tasks.TaskFactory().StartNew(() =>
            {
                var db       = new Db(context);
                var quantity = db.updatePurchase(
                    orderId, productId, purchaseState, purchaseTime, developerPayload);
                db.close();

                if (sPurchaseObserver != null)
                {
                    sPurchaseObserver.onPurchaseStateChange(purchaseState, productId, quantity, purchaseTime, developerPayload);
                }
            });
        }
Exemplo n.º 8
0
 public void onPurchaseStateChanged(string itemId, Consts.PurchaseState state)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 9
0
        /**
         * Verifies that the data was signed with the given signature, and returns
         * the list of verified purchases. The data is in JSON format and contains
         * a nonce (number used once) that we generated and that was signed
         * (as part of the whole data string) with a private key. The data also
         * contains the {@link PurchaseState} and product ID of the purchase.
         * In the general case, there can be an array of purchase transactions
         * because there may be delays in processing the purchase on the backend
         * and then several purchases can be batched together.
         * @param signedData the signed JSON string (signed, not encrypted)
         * @param signature the signature for the data, signed with the private key
         */
        public static List <VerifiedPurchase> verifyPurchase(string signedData, string signature)
        {
            if (signedData == null)
            {
                Log.Error(TAG, "data is null");
                return(null);
            }

            if (Consts.DEBUG)
            {
                Log.Info(TAG, "signedData: " + signedData);
            }

            var verified = !ExpectSignature;

            if (!TextUtils.IsEmpty(signature))
            {
                /**
                 * Compute your public key (that you got from the Android Market publisher site).
                 *
                 * Instead of just storing the entire literal string here embedded in the
                 * program,  construct the key at runtime from pieces or
                 * use bit manipulation (for example, XOR with some other string) to hide
                 * the actual key.  The key itself is not secret information, but we don't
                 * want to make it easy for an adversary to replace the public key with one
                 * of their own and then fake messages from the server.
                 *
                 * Generally, encryption keys / passwords should only be kept in memory
                 * long enough to perform the operation they need to perform.
                 */
                string     base64EncodedPublicKey = "place your key here";
                IPublicKey key = Security.generatePublicKey(base64EncodedPublicKey);
                verified = Security.verify(key, signedData, signature);
                if (!verified)
                {
                    Log.Warn(TAG, "signature does not match data.");
                    //return null;
                }
            }

            JsonObject jObject;
            JsonArray  jTransactionsArray = null;
            int        numTransactions    = 0;
            long       nonce = 0L;

            try
            {
                jObject = JsonObject.Parse(signedData) as JsonObject;

                // The nonce might be null if the user backed out of the buy page.
                nonce = jObject["nonce"];

                jTransactionsArray = jObject["orders"] as JsonArray;
                if (jTransactionsArray != null)
                {
                    numTransactions = jTransactionsArray.Count;
                }
            }
            catch             //(MalformedJsonException)
            {
                return(null);
            }

            if (!Security.isNonceKnown(nonce))
            {
                Log.Warn(TAG, "Nonce not found: " + nonce);
                return(null);
            }

            List <VerifiedPurchase> purchases = new List <VerifiedPurchase>();

            try
            {
                for (int i = 0; i < numTransactions; i++)
                {
                    var jElement = jTransactionsArray[i];
                    int response = jElement["purchaseState"];
                    Consts.PurchaseState purchaseState = (Consts.PurchaseState)response;
                    string productId    = jElement["productId"];
                    string packageName  = jElement["packageName"];
                    long   purchaseTime = jElement["purchaseTime"];
                    string orderId      = jElement["orderId"];

                    string notifyId         = null;
                    string developerPayload = null;

                    if (jElement.ContainsKey("notificationId"))
                    {
                        notifyId = jElement["notificationId"];
                    }

                    if (jElement.ContainsKey("developerPayload"))
                    {
                        developerPayload = jElement["developerPayload"];
                    }

                    // If the purchase state is PURCHASED, then we require a
                    // verified nonce.
                    if (purchaseState == Consts.PurchaseState.PURCHASED && !verified)
                    {
                        continue;
                    }

                    purchases.Add(new VerifiedPurchase(purchaseState, notifyId, productId,
                                                       orderId, purchaseTime, developerPayload));
                }
            }
            catch (Exception e)             //(MalformedJsonException e)
            {
                Log.Error(TAG, "JSON exception: ", e);
                return(null);
            }
            removeNonce(nonce);
            return(purchases);
        }
Exemplo n.º 10
0
 public ICursor queryTransactions(String productId, PurchaseState state)
 {
     return mDb.Query(TABLE_TRANSACTIONS, TABLE_TRANSACTIONS_COLUMNS, COLUMN_PRODUCT_ID + " = ? AND " + COLUMN_STATE + " = ?",
             new String[] { productId, Convert.ToString(state.ToString()) }, null, null, null);
 }