Billing.Security.VerifyPurchase C# (CSharp) Method

VerifyPurchase() public static method

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 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.
public static VerifyPurchase ( string signedData, string signature ) : List
signedData string the signed JSON string (signed, not encrypted)
signature string the signature for the data, signed with the private key
return List
        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);
            }
            bool verified = false;
            if (!TextUtils.IsEmpty(signature))
            {
                /// <summary>
                /// 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.
                /// </summary>
                string base64EncodedPublicKey = "<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;
                }
            }

            JObject jObject;
            JArray jTransactionsArray = null;
            int numTransactions = 0;
            long nonce = 0L;
            try
            {
                JObject json = JObject.Parse(signedData);

                // The nonce might be null if the user backed out of the buy page.
                nonce = (long)json.SelectToken("nonce");
                jTransactionsArray = (JArray)json.SelectToken("orders");
                if (jTransactionsArray != null)
                {
                    numTransactions = jTransactionsArray.Count;
                }
            }
            catch (JsonSerializationException e)
            {
                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++)
                {
                    JObject jElement = (JObject)jTransactionsArray[i];
                    int response = (int)jElement.SelectToken("purchaseState");
                    Consts.PurchaseState purchaseState = (Consts.PurchaseState)response;
                    string productId = (string)jElement.SelectToken("productId");
                    string packageName = (string)jElement.SelectToken("packageName");
                    long purchaseTime = (long)jElement.SelectToken("purchaseTime");
                    string orderId = (string)jElement.SelectToken("orderId");
                    string notifyId = null;
                    if (jElement.SelectToken("notificationId") != null)
                    {
                        notifyId = (string)jElement.SelectToken("notificationId");
                    }
                    string developerPayload = (string)jElement.SelectToken("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 (JsonSerializationException e)
            {
                Log.Error(TAG, "JSON exception: ", e);
                return null;
            }
            RemoveNonce(nonce);
            return purchases;
        }