/// <summary>
        /// Method is called when the order is being completed by the merchant when the <see cref="Payment"/> is authorized.
        /// </summary>
        /// <param name="payment">The authorized payment.</param>
        /// <param name="status">The status.</param>
        protected override bool AcquirePaymentInternal(Payment payment, out string status)
        {
            var    paymentMethod = payment.PaymentMethod;
            string pspId         = paymentMethod.DynamicProperty <string>().PspId;
            string password      = paymentMethod.DynamicProperty <string>().Password;
            string userId        = paymentMethod.DynamicProperty <string>().UserId;
            string shaSignIn     = paymentMethod.DynamicProperty <string>().ShaSignIn;
            bool   testMode      = paymentMethod.DynamicProperty <bool>().TestMode;


            int ogonePaymentStatus = RequestPaymentStatusAtOgone(payment, pspId, userId, password, testMode);

            if (ogonePaymentStatus != 5)
            {
                status = string.Format("Expected status was 'Payment Authorized' (5) but was {0}. {1}. Check STATUS message at {2}.",
                                       ogonePaymentStatus,
                                       "Processing a payment request takes time. Please wait for Ogone to finalize the authorization.",
                                       "https://secure.ogone.com/ncol/param_cookbook.asp"
                                       );
                return(false);
            }

            var dict = new Dictionary <string, string>();

            dict.Add("amount", payment.Amount.ToCents().ToString());
            dict.Add("currency", payment.PurchaseOrder.BillingCurrency.ISOCode);
            dict.Add("operation", "SAS");
            dict.Add("orderid", payment.ReferenceId);
            dict.Add("payid", payment.TransactionId);
            dict.Add("pspid", pspId);
            dict.Add("pswd", password);
            dict.Add("userid", userId);

            var shaComputer             = new OgoneSha1Computer();
            var acquirePaymentShaSignIn = new AcquirePaymentShaSignIn();

            dict.Add("SHASign", shaComputer.ComputeHash(acquirePaymentShaSignIn.BuildHashString(dict, shaSignIn)).ToUpper());

            var url = GetMaintenanceDirectUrl(testMode);

            var oGoneDataCapture = RequestOgone(url, dict);

            var ncresponse        = oGoneDataCapture.Descendants("ncresponse").Single();
            var maintenanceStatus = Convert.ToInt32(ncresponse.Attributes("STATUS").Single().Value);

            payment.PaymentStatus = PaymentStatus.Get((int)ConvertAcquireResultToPaymentStatus(maintenanceStatus));

            status = "";

            if (payment.PaymentStatus.PaymentStatusId == (int)PaymentStatusCode.AcquireFailed)
            {
                status = GetNCResponseErrorMessage(ncresponse);
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Method is called when the order is being canceled by the merchant before the <see cref="Payment"/> is acquired.
        /// </summary>
        /// <param name="payment">The payment.</param>
        /// <param name="status">The status.</param>
        protected override bool CancelPaymentInternal(Payment payment, out string status)
        {
            var    paymentMethod = payment.PaymentMethod;
            string pspId         = paymentMethod.DynamicProperty <string>().PspId;
            string password      = paymentMethod.DynamicProperty <string>().Password;
            string userId        = paymentMethod.DynamicProperty <string>().UserId;
            string shaSignIn     = paymentMethod.DynamicProperty <string>().ShaSignIn;
            bool   testMode      = paymentMethod.DynamicProperty <bool>().TestMode;

            int ogonePaymentStatus = RequestPaymentStatusAtOgone(payment, pspId, userId, password, testMode);

            if (ogonePaymentStatus == 9 || ogonePaymentStatus == 91)
            {
                return(RefundPaymentInternal(payment, out status));
            }
            if (ogonePaymentStatus != 5)
            {
                status = string.Format("expected status was 5 or 91 for cancel payment, but was {0}. Check STATUS message at {1}"
                                       , ogonePaymentStatus
                                       , "https://secure.ogone.com/ncol/param_cookbook.asp?CSRFSP=%2Fncol%2Ftest%2Fdownload_docs%2Easp&CSRFKEY=7E003EFC9703DF1A30BF28559ED87B534C0F0309&CSRFTS=20110822081113"
                                       );
                return(false);
            }

            var dict = new Dictionary <string, string>();

            dict.Add("amount", payment.Amount.ToCents().ToString());
            dict.Add("currency", payment.PurchaseOrder.BillingCurrency.ISOCode);
            dict.Add("operation", "DES");
            dict.Add("orderid", payment.PurchaseOrder.OrderId.ToString());
            dict.Add("payid", payment.TransactionId);
            dict.Add("pspid", pspId);
            dict.Add("pswd", password);
            dict.Add("userid", userId);

            var shaComputer            = new OgoneSha1Computer();
            var cancelPaymentShaSignIn = new CancelPaymentShaSignIn();

            dict.Add("SHASign", shaComputer.ComputeHash(cancelPaymentShaSignIn.BuildHashString(dict, shaSignIn)).ToUpper());

            var url = GetMaintenanceDirectUrl(testMode);

            var oGoneDataCapture = RequestOgone(url, dict);

            var ncresponse        = oGoneDataCapture.Descendants("ncresponse").Single();
            var maintenanceStatus = Convert.ToInt32(ncresponse.Attributes("STATUS").Single().Value);

            payment.PaymentStatus = PaymentStatus.Get((int)ConvertCancelResultToPaymentStatus(maintenanceStatus));
            status = "";
            if (payment.PaymentStatus.PaymentStatusId == (int)PaymentStatusCode.Declined)
            {
                status = GetNCResponseErrorMessage(ncresponse);
                return(false);
            }

            return(true);
        }
        private string CalculateSha1Signature(string shaSignIn, IDictionary <string, string> keys)
        {
            var oGoneSha1Computer = new OgoneSha1Computer();

            string parametersStringForHash = GetParametersStringForHash(shaSignIn, keys);
            string hashValue = oGoneSha1Computer.ComputeHash(parametersStringForHash);

            return(hashValue.ToUpper());
        }
        /// <summary>
        /// Method is called when the order is being canceled by the merchant, after the <see cref="Payment"/> have been acquired by the merchant.
        /// </summary>
        /// <param name="payment">The payment.</param>
        /// <param name="status">The status.</param>
        protected override bool RefundPaymentInternal(Payment payment, out string status)
        {
            var    paymentMethod = payment.PaymentMethod;
            string pspId         = paymentMethod.DynamicProperty <string>().PspId;
            string password      = paymentMethod.DynamicProperty <string>().Password;
            string userId        = paymentMethod.DynamicProperty <string>().UserId;
            string shaSignIn     = paymentMethod.DynamicProperty <string>().ShaSignIn;
            bool   testMode      = paymentMethod.DynamicProperty <bool>().TestMode;

            int paymentStatus = RequestPaymentStatusAtOgone(payment, pspId, userId, password, testMode);

            if (paymentStatus != 9 && paymentStatus != 91)
            {
                status = string.Format("Expected status was 'Payment requested' (9) or 'Payment Processig' (91) for refund, but was {0}. Check 'STATUS' message at {1}",
                                       paymentStatus,
                                       "https://secure.ogone.com/ncol/param_cookbook.asp"
                                       );
                return(false);
            }
            var dict = new Dictionary <string, string>();

            dict.Add("amount", payment.Amount.ToCents().ToString());
            dict.Add("currency", payment.PurchaseOrder.BillingCurrency.ISOCode);
            dict.Add("operation", "RFS");
            dict.Add("orderid", payment.ReferenceId);
            dict.Add("payid", payment.TransactionId);
            dict.Add("pspid", pspId);
            dict.Add("pswd", password);
            dict.Add("userid", userId);

            var shaComputer = new OgoneSha1Computer();
            var hashString  = new CancelPaymentShaSignIn();

            dict.Add("SHASign", shaComputer.ComputeHash(hashString.BuildHashString(dict, shaSignIn)).ToUpper());

            var url = GetMaintenanceDirectUrl(testMode);

            var oGoneDataCapture = RequestOgone(url, dict);
            var ncresponse       = oGoneDataCapture.Descendants("ncresponse").Single();

            var maintenanceStatus = Convert.ToInt32(ncresponse.Attributes("STATUS").Single().Value);

            payment.PaymentStatus = PaymentStatus.Get((int)ConvertRefundResultToPaymentStatus(maintenanceStatus));

            status = "";
            if (payment.PaymentStatus.PaymentStatusId == (int)PaymentStatusCode.Declined)
            {
                status = GetNCResponseErrorMessage(ncresponse);
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Processes the callback from Ogone after the customer has entered credit card information and clicked submit.
        /// </summary>
        /// <param name="payment">The payment.</param>
        public override void ProcessCallback(Payment payment)
        {
            Guard.Against.PaymentNotPendingAuthorization(payment);
            Guard.Against.MissingHttpContext(_webRuntimeInspector);
            Guard.Against.MissingRequestParameter("STATUS");
            Guard.Against.MissingRequestParameter("PAYID");
            Guard.Against.MissingRequestParameter("SHASIGN");

            var         paymentMethod = payment.PaymentMethod;
            HttpContext context       = HttpContext.Current;
            var         computer      = new OgoneSha1Computer();
            var         hashString    = new ProcessCallBackShaSignOut();

            string shaSignOut = paymentMethod.DynamicProperty <string>().ShaSignOut;

            string statusCode    = context.Request["STATUS"];
            string transactionId = context.Request["PAYID"];
            string oGoneShaSign  = context.Request["SHASIGN"].ToUpper();

            string stringToHash = hashString.BuildHashString(context, shaSignOut);
            string shaSign      = computer.ComputeHash(stringToHash).ToUpper();

            if (oGoneShaSign != shaSign)
            {
                throw new SecurityException("Shasigns did not match. Please make sure that 'SHA-OUT Pass phrase' is configured in Ogone and that the same key is configured in Ogone.config.");
            }

            payment["response"] = context.Request.Url.ToString();

            PaymentStatusCode paymentStatus = ConvertAuthorizeResultToPaymentStatus(Convert.ToInt32(statusCode));

            payment.TransactionId = transactionId;
            payment.PaymentStatus = PaymentStatus.Get((int)paymentStatus);

            if (PaymentIsDeclined(payment))
            {
                payment.Save();
            }
            else
            {
                ProcessPaymentRequest(new PaymentRequest(payment.PurchaseOrder, payment));
            }
        }