protected void Page_Load(object sender, EventArgs e)
        {
            CommonHelper.SetResponseNoCache(Response);

            if (!Page.IsPostBack)
            {

                string crypt = Request.Params["Crypt"];

                SagePayPaymentProcessor proc = new SagePayPaymentProcessor();
                string decrypted = proc.Decrypt(crypt);
                var decryptedDict = proc.Parse(decrypted);

                string status = decryptedDict["Status"];
                if (string.IsNullOrEmpty(status))
                    status = string.Empty;

                if (status == "OK")
                {
                    // this is a very serious error - it means that the SagePay message is corrupt
                    string message = "Error in response from SagePay - expected failure, but saw OK - status is " + status;
                    LogManager.InsertLog(LogTypeEnum.OrderError, message, decrypted);
                    throw new NopException("Response Incorrect");
                }

                string statusDetail = decryptedDict["StatusDetail"];
                if (string.IsNullOrEmpty(statusDetail))
                    statusDetail = string.Empty;

                lblMessageTitle.Text = string.Format("Payment failed - status {0}", status);
                lblMessage.Text = string.Format("Payment failed - error detail is {0}", statusDetail);

                string VendorTxCode = decryptedDict["VendorTxCode"];
                if (string.IsNullOrEmpty(VendorTxCode))
                    VendorTxCode = string.Empty;

                if (string.IsNullOrEmpty(VendorTxCode))
                {
                    // this is a very serious error - it means that the SagePay message is corrupt :(
                    string message = "Error in VendorTxCode response from SagePay - status is " + status;
                    LogManager.InsertLog(LogTypeEnum.OrderError, message, decrypted);
                    throw new NopException("Response Incorrect");
                }

                // we've got here and we have a valid VendorTxCode and a valid order id
                Order order = OrderManager.GetOrderById((int)Convert.ToDouble(VendorTxCode));
                if (order == null)
                    throw new NopException(string.Format("The order ID {0} doesn't exists", VendorTxCode));

                // would be nice to let the user have another go here - e.g. with a different card

                // cancel the order and let the customer know
                if (OrderManager.CanCancelOrder(order))
                {
                    OrderManager.CancelOrder(order.OrderId, true);
                }
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            CommonHelper.SetResponseNoCache(Response);

            if (!Page.IsPostBack)
            {
                string crypt = Request.Params["Crypt"];
                SagePayPaymentProcessor proc = new SagePayPaymentProcessor();
                string decrypted = proc.Decrypt(crypt);
                var decryptedDict = proc.Parse(decrypted);

                string status = decryptedDict["Status"];
                if (string.IsNullOrEmpty(status))
                    status = string.Empty;

                if (status != "OK")
                {
                    // this is a very serious error - it means that the SagePay message is corrupt
                    string message = "Error in response from SagePay - status is " + status;
                    this.LogService.InsertLog(LogTypeEnum.OrderError, message, decrypted);
                    throw new NopException("Response Incorrect");
                }

                string TxAuthNo = decryptedDict["TxAuthNo"];
                if (string.IsNullOrEmpty(TxAuthNo))
                    TxAuthNo = string.Empty;

                string VendorTxCode = decryptedDict["VendorTxCode"];
                if (string.IsNullOrEmpty(VendorTxCode))
                    VendorTxCode = string.Empty;

                if (string.IsNullOrEmpty(TxAuthNo))
                {
                    // this is a very serious error - it means that the SagePay message is corrupt :(
                    string message = "Error in TXAuthNo response from SagePay - status is " + status;
                    this.LogService.InsertLog(LogTypeEnum.OrderError, message, decrypted);
                    throw new NopException("Response Incorrect");
                }

                if (string.IsNullOrEmpty(VendorTxCode))
                {
                    // this is a very serious error - it means that the SagePay message is corrupt :(
                    string message = "Error in VendorTxCode response from SagePay - status is " + status;
                    this.LogService.InsertLog(LogTypeEnum.OrderError, message, decrypted);
                    throw new NopException("Response Incorrect");
                }

                // we've got here and we have a valid VendorTxCode and a valid order id
                Order order = this.OrderService.GetOrderById((int)Convert.ToDouble(VendorTxCode));
                if (order == null)
                    throw new NopException(string.Format("The order ID {0} doesn't exists", VendorTxCode));

                // would like to add more secure code here - this flow doesn't feel entirely safe/secure!
                // would like to store the TxAuthNo returned.

                if (this.OrderService.CanMarkOrderAsPaid(order))
                {
                    this.OrderService.MarkOrderAsPaid(order.OrderId);
                }
                Response.Redirect("~/checkoutcompleted.aspx");
            }
        }