/// <summary>
 /// Saves the payment.
 /// </summary>
 /// <param name="payment">The payment.</param>
 public void SavePayment(lss_payment payment)
 {
     using (var context = this.CrmConnector.CreateDataContext())
     {
         context.Attach(payment);
         context.UpdateObject(payment);
         context.SaveChanges();
     }
 }
        /// <summary>
        /// Reads the form fields.
        /// </summary>
        /// <param name="payment">The payment.</param>
        private void ReadFormFields(lss_payment payment)
        {
            payment.lss_notificationstatus       = Request.Form["Status"];
            payment.lss_vpssignature             = Request.Form["VPSSignature"];
            payment.lss_notificationstatusdetail = Request.Form["StatusDetail"];

            int txAuthNo = 0;

            Int32.TryParse(Request.Form["TxAuthNo"], out txAuthNo);
            payment.lss_txauthno = txAuthNo;

            payment.lss_avscv2         = Request.Form["AVSCV2"];
            payment.lss_addressresult  = Request.Form["AddressResult"];
            payment.lss_postcoderesult = Request.Form["PostCodeResult"];
            payment.lss_cv2result      = Request.Form["CV2Result"];
            payment.lss_giftaid        = Request.Form["GiftAid"];
            payment.lss_securestatus3d = Request.Form["3DSecureStatus"];
            payment.lss_cavv           = Request.Form["CAVV"];
            payment.lss_addressstatus  = Request.Form["AddressStatus"];
            payment.lss_payerstatus    = Request.Form["PayerStatus"];
            payment.lss_cardtype       = Request.Form["CardType"];
            payment.lss_last4digits    = Request.Form["Last4Digits"];
        }
        /// <summary>
        /// Creates the post request.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="connector">The connector.</param>
        /// <param name="paymentId">The payment id.</param>
        /// <returns></returns>
        private static string CreatePostRequest(ConfigurationProvider configuration, CrmConnector connector, lss_payment payment)
        {
            OrderProvider   orderProvider   = new OrderProvider(connector);
            ContactProvider contactProvider = new ContactProvider(connector);
            PaymentProvider paymentProvider = new PaymentProvider(connector);

            var order   = orderProvider.GetOrder(payment.lss_orderid.Id);
            var contact = contactProvider.GetContact(order.CustomerId.Id);

            StringBuilder postRequest = new StringBuilder();

            payment.lss_vendortxcode = CreateVendorTransactionCode(order.Name);

            // Save the record so the payment has a name
            payment.lss_name = "Payment: " + payment.lss_vendortxcode + " - £" + payment.lss_amount.Value.ToString("#.##");
            paymentProvider.SavePayment(payment);

            // Check the Contact has the relevant details for a sucessful transaction
            if (String.IsNullOrEmpty(contact.FirstName) ||
                String.IsNullOrEmpty(contact.LastName) ||
                String.IsNullOrEmpty(contact.Address1_Line1) ||
                String.IsNullOrEmpty(contact.Address1_City) ||
                String.IsNullOrEmpty(contact.Address1_PostalCode))
            {
                return("INVALIDCONTACT");
            }

            postRequest.Append("VPSProtocol=2.23&TxType=PAYMENT&Vendor=");
            postRequest.Append(configuration.VendorName);
            postRequest.Append("&VendorTxCode=" + payment.lss_vendortxcode);
            postRequest.Append("&Amount=" + payment.lss_amount.Value.ToString("#.##"));
            postRequest.Append("&Currency=GBP");
            postRequest.Append("&Description=" + order.Name);
            postRequest.Append("&NotificationURL=" + configuration.NotificationUrl);
            postRequest.Append(BuildContactDetails(contact));
            postRequest.Append("&CustomerEMail=" + (String.IsNullOrEmpty(contact.EMailAddress1) ? String.Empty : contact.EMailAddress1.Trim()));
            postRequest.Append(BuildBasket(connector, orderProvider, order));
            postRequest.Append("&AllowGiftAid=0&ApplyAVSCV2=0&Apply3DSecure=0&Profile=NORMAL&AccountType=M");

            return(postRequest.ToString());
        }
        /// <summary>
        /// Checks the response from SagePay
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="connector">The connector.</param>
        /// <param name="payment">The payment.</param>
        /// <param name="responseFromSagePay">The response from sage pay.</param>
        /// <returns>
        /// Returns the next url to go to if the status is ok
        /// </returns>
        private string CheckSagePayResponse(ConfigurationProvider configuration, CrmConnector connector, lss_payment payment, string responseFromSagePay)
        {
            string nextUrl = String.Empty;

            string[] responses = responseFromSagePay.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string response in responses)
            {
                int splitIndex = response.IndexOf("=");
                if (splitIndex != -1)
                {
                    string name  = response.Substring(0, splitIndex);
                    string value = response.Substring(splitIndex + 1);

                    switch (name)
                    {
                    case "VPSProtocol":
                        payment.lss_vpsprotocol = value;
                        break;

                    case "Status":
                        payment.lss_responsestatus = value;
                        break;

                    case "StatusDetail":
                        payment.lss_responsestatusdetail = value;
                        break;

                    case "VPSTxId":
                        payment.lss_vpstxid = value;
                        break;

                    case "SecurityKey":
                        payment.lss_securitykey = value;
                        break;

                    case "NextURL":
                        payment.lss_nexturl = value;
                        break;
                    }
                }
            }

            if (payment.lss_responsestatus != null)
            {
                switch (payment.lss_responsestatus)
                {
                case "OK":
                    // If the status is OK then we can return the Next Url
                    nextUrl = payment.lss_nexturl == null ? String.Empty : payment.lss_nexturl;
                    break;

                case "MALFORMED":
                    payment.lss_paystatus.Value = (int)PaymentProvider.PaymentStatus.Failed;
                    nextUrl = configuration.OrderFailedUrl + "?errorcode=" + ((int)ErrorCodes.MalformedPost).ToString();
                    break;

                case "INVALID":
                    payment.lss_paystatus.Value = (int)PaymentProvider.PaymentStatus.Failed;
                    nextUrl = configuration.OrderFailedUrl + "?errorcode=" + ((int)ErrorCodes.InvalidPost).ToString();
                    break;

                default:
                    payment.lss_paystatus.Value = (int)PaymentProvider.PaymentStatus.Failed;
                    nextUrl = configuration.OrderFailedUrl + "?errorcode=" + ((int)ErrorCodes.GeneralPostError).ToString();
                    break;
                }
            }

            PaymentProvider paymentProvider = new PaymentProvider(connector);

            paymentProvider.SavePayment(payment);

            return(nextUrl);
        }