/// <summary>
        /// Refund an order that has been paid or released
        /// </summary>
        /// <param name="orderGuid">Order guid</param>
        /// <param name="orderTotal">Order total</param>
        /// <param name="currencyCode">Currency code</param>
        /// <returns></returns>
        public RefundTransactionResult RefundTransaction(String orderGuid, decimal orderTotal, string currencyCode)
        {
            var result = new RefundTransactionResult();

            var transx = _sagePayServerTransactionService.GetSagePayServerTransactionByVendorTxCode(orderGuid);

            if (transx == null)
            {
                result.Message = String.Format("SagePay Server vendor transaction code {0} does not exist.", orderGuid);
                return(result);
            }


            var webClient  = new WebClient();
            var returnGuid = Guid.NewGuid();

            var data = new QueryStringNameValueCollection
            {
                { "VPSProtocol", SagePayHelper.GetProtocol() },
                { "TxType", "REFUND" },
                { "Vendor", _sagePayServerPaymentSettings.VendorName },
                { "VendorTxCode", returnGuid.ToString() },
                { "VPSTxId", transx.VpsTxId },
                { "SecurityKey", transx.SecurityKey },
                { "TxAuthNo", transx.TxAuthNo },
                {
                    "Amount",
                    orderTotal.ToString("F2", CultureInfo.InvariantCulture)
                },
                { "Currency", currencyCode },
                { "Description", "---" },
                { "RelatedVPSTxId", transx.VpsTxId },
                { "RelatedVendorTxCode", orderGuid },
                { "RelatedSecurityKey", transx.SecurityKey },
                { "RelatedTxAuthNo", transx.TxAuthNo }
            };

            var postUrl = SagePayHelper.GetSageSystemUrl(_sagePayServerPaymentSettings.ConnectTo, "refund");

            string strResponse;

            try
            {
                var responseData = webClient.UploadValues(postUrl, data);

                strResponse = Encoding.ASCII.GetString(responseData);
            }
            catch (WebException ex)
            {
                result.Message = (String.Format(
                                      @"Your server was unable to release this transaction with Sage Pay.
                    Check that you do not have a firewall restricting the POST and 
                    that your server can correctly resolve the address {0}. <br/>
                    The Status Number is: {1}<br/>
                    The Description given is: {2}", postUrl, ex.Status, ex.Message));
                return(result);
            }

            if (string.IsNullOrWhiteSpace(strResponse))
            {
                result.Message = (String.Format(
                                      @"Your server was unable to register this transaction with Sage Pay.
                    Check that you do not have a firewall restricting the POST and 
                    that your server can correctly resolve the address {0}.", postUrl));
                return(result);
            }
            var strStatus       = SagePayHelper.FindField("Status", strResponse);
            var strStatusDetail = SagePayHelper.FindField("StatusDetail", strResponse);

            switch (strStatus)
            {
            case "OK":

                result.Success = true;
                break;

            case "MALFORMED":
                result.Message = (string.Format("Error ({0}: {1}) <br/> {2}", strStatus, strStatusDetail, data.Encode()));
                break;

            case "INVALID":
                result.Message = (string.Format("Error ({0}: {1}) <br/> {2}", strStatus, strStatusDetail, data.Encode()));
                break;

            default:
                result.Message = (string.Format("Error ({0}: {1})", strStatus, strStatusDetail));
                break;
            }

            return(result);
        }
        /// <summary>
        /// Refund an order that has been paid or released
        /// </summary>
        /// <param name="orderGuid">Order guid</param>
        /// <param name="orderTotal">Order total</param>
        /// <param name="currencyCode">Currency code</param>
        /// <returns></returns>
        public RefundTransactionResult RefundTransaction(String orderGuid, decimal orderTotal, string currencyCode)
        {
            var result = new RefundTransactionResult();

            var transx = _sagePayServerTransactionService.GetSagePayServerTransactionByVendorTxCode(orderGuid);

            if (transx == null)
            {
                result.Message = String.Format("SagePay Server vendor transaction code {0} does not exist.", orderGuid);
                return result;
            }

            var webClient = new WebClient();
            var returnGuid = Guid.NewGuid();

            var data = new QueryStringNameValueCollection
                           {
                               {"VPSProtocol", SagePayHelper.GetProtocol()},
                               {"TxType", "REFUND"},
                               {"Vendor", _sagePayServerPaymentSettings.VendorName},
                               {"VendorTxCode", returnGuid.ToString()},
                               {"VPSTxId", transx.VpsTxId},
                               {"SecurityKey", transx.SecurityKey},
                               {"TxAuthNo", transx.TxAuthNo},
                               {
                                   "Amount",
                                   orderTotal.ToString("F2", CultureInfo.InvariantCulture)
                               },
                               {"Currency", currencyCode},
                               {"Description", "---"},
                               {"RelatedVPSTxId", transx.VpsTxId},
                               {"RelatedVendorTxCode", orderGuid},
                               {"RelatedSecurityKey", transx.SecurityKey},
                               {"RelatedTxAuthNo", transx.TxAuthNo}
                           };

            var postUrl = SagePayHelper.GetSageSystemUrl(_sagePayServerPaymentSettings.ConnectTo, "refund");

            string strResponse;

            try
            {

                var responseData = webClient.UploadValues(postUrl, data);

                strResponse = Encoding.ASCII.GetString(responseData);

            }
            catch (WebException ex)
            {
                result.Message = (String.Format(
                    @"Your server was unable to release this transaction with Sage Pay.
                    Check that you do not have a firewall restricting the POST and
                    that your server can correctly resolve the address {0}. <br/>
                    The Status Number is: {1}<br/>
                    The Description given is: {2}", postUrl, ex.Status, ex.Message));
                return result;
            }

            if (string.IsNullOrWhiteSpace(strResponse))
            {
                result.Message = (String.Format(
                    @"Your server was unable to register this transaction with Sage Pay.
                    Check that you do not have a firewall restricting the POST and
                    that your server can correctly resolve the address {0}.", postUrl));
                return result;
            }
            var strStatus = SagePayHelper.FindField("Status", strResponse);
            var strStatusDetail = SagePayHelper.FindField("StatusDetail", strResponse);

            switch (strStatus)
            {
                case "OK":

                    result.Success = true;
                    break;

                case "MALFORMED":
                    result.Message = (string.Format("Error ({0}: {1}) <br/> {2}", strStatus, strStatusDetail, data.Encode()));
                    break;

                case "INVALID":
                    result.Message = (string.Format("Error ({0}: {1}) <br/> {2}", strStatus, strStatusDetail, data.Encode()));
                    break;

                default:
                    result.Message = (string.Format("Error ({0}: {1})", strStatus, strStatusDetail));
                    break;

            }

            return result;
        }