protected void OnPay(object sender, EventArgs e)
        {
            if (!Page.IsValid) return;

             var service = GetCardService();
             CardProfile = SetCreditCardViewModel(service);

             var cardExpiresOnDate =
            new DateTime(MemberProtect.Utility.ValidateInteger(CardProfile.ExpirationYear),
                         MemberProtect.Utility.ValidateInteger(CardProfile.ExpirationMonth), 1)
               .AddMonths(1).AddDays(-1);

             if (cardExpiresOnDate.CompareTo(DateTime.Today) <= 0)
             {
            SetMessage(
               _transientCardEntry
                  ? "Please choose a valid credit card expiration date in the future."
                  : "This card is expired please choose or add another card.",
               MessageTone.Negative);
            return;
             }

             var sErrors = string.Empty;

             if (_transientCardEntry)
             {
            if (CardProfile.CardType == "American Express")
            {
               var oRegex = new Regex("^\\d{15}$");
               if (!oRegex.Match(CardProfile.CreditCardNumber).Success)
               {
                  sErrors += "Credit Card Number must be a valid American Express number (123123412341234).<br/>";
               }

               if (CardProfile.CardVerificationCode.Length != 4)
               {
                  sErrors += "Please enter your 4 digit security code.<br/>";
               }
            }
            else
            {
               var oRegex = new Regex("^\\d{16}$");
               if (!oRegex.Match(CardProfile.CreditCardNumber).Success)
               {
                  sErrors += "Credit Card Number must be a valid credit card number (1234123412341234).<br/>";
               }

               if (CardProfile.CardVerificationCode.Length != 3)
               {
                  sErrors += "Please enter your 3 digit security code.<br/>";
               }
            }

            if (!m_chkAgree.Checked)
            {
               sErrors += "You must accept the Terms & Conditions.";
            }

            if (sErrors != string.Empty)
            {
               SetMessage(sErrors, MessageTone.Negative);
               return;
            }
             }

             var oExpirationDateTime =
            new DateTime(MemberProtect.Utility.ValidateInteger(m_cboCreditCardExpireYear.SelectedValue),
                         MemberProtect.Utility.ValidateInteger(m_cboCreditCardExpireMonth.SelectedValue), 1).AddMonths(1).AddDays(-1);

             var oTransactionInformation = new AuthorizeNETTransactionInformation(CardProfile.CreditCardNumber, GetTotal(), oExpirationDateTime)
             {
            FirstName = CardProfile.FirstName,
            LastName = CardProfile.LastName,
            CreditCardCode = CardProfile.CardVerificationCode,
            Email = CardProfile.ReceiptEmailAddressCsv,
            Description = "Invoice Payment",
            Company = (m_txtCompany.Text.Length > 50) ? m_txtCompany.Text.Substring(0, 49) : m_txtCompany.Text,
            InvoiceNumber = GetListOfInvoiceNumbers()
             };

             if (_transientCardEntry && m_chkSavePaymentInformation.Checked)
             {
            var errors = service.SaveCreditCard(CardProfile);
            if (errors.Any())
            {
               SetMessage(errors.Aggregate((msg, error) => msg + error + "<br />"), MessageTone.Negative);
               return;
            }

            // just flip the bit?  hope the state is all proper
            _transientCardEntry = false;
             }

             var paymentGatewayResponse = new PaymentGatewayResponse(string.Empty);

             if (_transientCardEntry)
             {
            var oAuthorizeNet = new AuthorizeNET(ApplicationContext.SiteProperites.AuthorizeNetIsDebug,
                                                 MemberProtect.Cryptography.Decrypt(ApplicationContext.SiteProperites.AuthorizeNetLoginID),
                                                 MemberProtect.Cryptography.Decrypt(ApplicationContext.SiteProperites.AuthorizeNetTransactionKey));

            if (!oAuthorizeNet.ProcessAuthorizationAndCapture(oTransactionInformation))
            {
               var message = "Your payment could not be processed, please double-check all information and try again.";
               if (ApplicationContext.SiteProperites.AuthorizeNetIsDebug)
               {
                  var response = CreditCards.ParseAuthorizeNetResponse(oAuthorizeNet.Response);
                  message += string.Format(" (Response: {0}, Reason: {1})", response.ResponseCode, response.ResponseReasonCode);
               }

               SetMessage(message, MessageTone.Negative);
               return;
            }

            paymentGatewayResponse = oAuthorizeNet.PaymentGatewayResponse;
             }
             else
             {
            // go through CIM to process transaction
            paymentGatewayResponse = service.CIMAuthorizationAndCapture(oTransactionInformation,
                                                                        CardProfile.CIMProfileId,
                                                                        CardProfile.CIMPaymentProfileId);
            if (paymentGatewayResponse.Errors.Any() || paymentGatewayResponse.GetValue(PaymentGatewayResponse.FieldNames.ResponseCode) != "1")
            {
               var message = paymentGatewayResponse.Errors.Any()
                                ? paymentGatewayResponse.Errors.Aggregate((messages, error) => messages + ", " + error)
                                : paymentGatewayResponse.GetValue(PaymentGatewayResponse.FieldNames.ResponseReasonText);
               ShowMessage(message, MessageTone.Negative);
               return;
            }
             }

             var oIAPayment = SavePayment(paymentGatewayResponse);

             StringBuilder oSpeedySpotsLineItems;
             var oLineItems = SaveLineItems(oIAPayment, out oSpeedySpotsLineItems);

             // QB Import Payment Rule
             // - All of the line items within a payment MUST associate with an actual QB Invoice and the amount on the individual line items must match up with the invoice, otherwise
             var bIsPaymentAutoImported = QuickBooksInvoiceMatching(oIAPayment);

             // Clear the invoice in memory
             Session["InvoicePayments"] = null;

             SendPaymentReceiptEmail(CardProfile, oLineItems, oIAPayment);

             SendBillingEmail(CardProfile, bIsPaymentAutoImported, oSpeedySpotsLineItems, oIAPayment);

             // Clear the invoice in memory
             Session["InvoicePayments"] = null;

             // Display the receipt
             m_divPayment.Visible = false;
             m_divReceipt.Visible = true;
        }
 private IAPayment SavePayment(PaymentGatewayResponse paymentGatewayResponse)
 {
     var oIAPayment = new IAPayment
      {
     Total = GetTotal(),
     Email = CardProfile.ReceiptEmailAddressCsv,
     Company = m_txtCompany.Text,
     Instructions = m_txtInstructions.Text,
     CreditCardFirstName = MemberProtect.Cryptography.Encrypt(CardProfile.FirstName),
     CreditCardLastName = MemberProtect.Cryptography.Encrypt(CardProfile.LastName),
     CreditCardType = MemberProtect.Cryptography.Encrypt(CardProfile.CardType),
     CreditCardNumber = MemberProtect.Cryptography.Encrypt(CardProfile.CreditCardNumber),
     AuthorizeNetTransactionID = paymentGatewayResponse.GetValue(PaymentGatewayResponse.FieldNames.TransactionId),
     AuthorizeNetProcessResponse = paymentGatewayResponse.GetValue(PaymentGatewayResponse.FieldNames.ResponseReasonText),
     CreatedDateTime = DateTime.Now,
     Zip = ""
      };
      DataAccess.IAPayments.InsertOnSubmit(oIAPayment);
      DataAccess.SubmitChanges();
      return oIAPayment;
 }
        private void InformBillingThatCustomerPaid(CreditCardViewModel paymentDetails, PaymentGatewayResponse paymentGatewayResponse,
                                                 Func<string, string> urlBuilder,
                                                 IARequest request, DateTime approved, decimal chargeAmount)
        {
            string subject;
             string customerType;

             var mpOrg = _dataContext.MPOrgUsers.FirstOrDefault(row => row.MPUserID == _customerMemberProtectUserId);
             var mpOrgId = mpOrg == null ? Guid.Empty : mpOrg.MPOrgID;

             if (_memberProtect.Utility.YesNoToBool(_memberProtect.Organization.GetDataItem(mpOrgId, "IsVerified")))
             {
            subject = "Estimate Payment made (verified)";
            customerType = "a verified";
             }
             else
             {
            subject = "Estimate Payment made (unverified)";
            customerType = "an unverified";
             }

             var paidEmail = new StringBuilder();
             paidEmail.AppendFormat("An estimate payment was made by {0} customer:<br/>", customerType);
             paidEmail.Append("<br/>");
             paidEmail.AppendFormat("Company: <a href='{0}?id={1}'>{2}</a><br/>", urlBuilder("company-modify.aspx"),
                                mpOrgId.ToString().Replace("-", string.Empty), _memberProtect.Organization.GetName(mpOrgId));
             paidEmail.AppendFormat("Customer: <a href='{0}?id={1}'>{2} {3}</a><br/>", urlBuilder("user-account.aspx"),
                                _customerMemberProtectUserId.ToString().Replace("-", string.Empty),
                                _memberProtect.User.GetDataItem(_customerMemberProtectUserId, "FirstName"),
                                _memberProtect.User.GetDataItem(_customerMemberProtectUserId, "LastName"));
             paidEmail.AppendFormat("Email Receipt: {0}<br/>", paymentDetails.ReceiptEmailAddressCsv);
             paidEmail.AppendFormat("Request: <a href='{0}?rid={1}'>{2}</a><br/>", urlBuilder("create-job.aspx"), request.IARequestID, request.RequestIdForDisplay);
             paidEmail.AppendFormat("Amount: {0:c}<br/>", chargeAmount);
             paidEmail.AppendFormat("Card: {0} ending in {1}<br/>", paymentDetails.CardType, _memberProtect.Utility.Right(paymentDetails.CreditCardNumber, 4));
             paidEmail.AppendFormat("Name on Card: {0} {1}<br/>", paymentDetails.FirstName, paymentDetails.LastName);
             paidEmail.AppendFormat("When: {0:g}<br/>", approved);
             paidEmail.AppendFormat("Authorize Receipt: {0}<br/>", paymentGatewayResponse.GetValue(PaymentGatewayResponse.FieldNames.TransactionId));

             EmailCommunicationService.EstimatePaymentBillingNoticeSend(paidEmail, subject);
        }
        private void RecordOrder(CreditCardViewModel paymentDetails, PaymentGatewayResponse response, IARequestEstimate estimate)
        {
            var iaOrder = new IAOrder
             {
            MPUserID = _customerMemberProtectUserId,
            CreditCardType = _memberProtect.Cryptography.Encrypt(paymentDetails.CardType),
            CreditCardNumber = _memberProtect.Cryptography.Encrypt(paymentDetails.CreditCardNumber),
            CreditCardExpirationMonth = _memberProtect.Cryptography.Encrypt(paymentDetails.ExpirationMonth),
            CreditCardExpirationYear = _memberProtect.Cryptography.Encrypt(paymentDetails.ExpirationYear),
            CreditCardFirstName = _memberProtect.Cryptography.Encrypt(paymentDetails.FirstName),
            CreditCardLastName = _memberProtect.Cryptography.Encrypt(paymentDetails.LastName),
            CreditCardZip = "",
            AuthorizeNetResponse = string.Empty,
            AuthorizeNetTransactionID = response.GetValue(PaymentGatewayResponse.FieldNames.TransactionId),
            AuthorizeNetProcessDatetime = DateTime.Now,
            AuthorizeNetProcessResponse = response.GetValue(PaymentGatewayResponse.FieldNames.ResponseCode),
            AuthorizeNetProcessUsername = _dataContext.MPUsers.First(u => u.MPUserID == _customerMemberProtectUserId).Username,
            AuthorizeNetProcessCaptureAmount = estimate.Charge,
            AuthorizeNetProcessCaptureAmountChangeReason = string.Empty,
            AuthorizeNetProcessStatus = "Captured",
            CreatedDateTime = DateTime.Now
             };
             _dataContext.IAOrders.InsertOnSubmit(iaOrder);
             _dataContext.SubmitChanges();

             var iaOrderLineItem = new IAOrderLineItem
             {
            IAOrderID = iaOrder.IAOrderID,
            Description = "Request Estimate",
            Quantity = 1,
            Price = estimate.Charge,
            IsSynched = false
             };
             _dataContext.IAOrderLineItems.InsertOnSubmit(iaOrderLineItem);

             estimate.IAOrderID = iaOrder.IAOrderID;
             _dataContext.SubmitChanges();
        }
        public CreditCardServiceResponse PayEstimate(CreditCardViewModel cardProfile, Func<string, string> urlBuilder, IARequest request, IARequestEstimate estimate)
        {
            var response = new CreditCardServiceResponse {SuccessfulCharge = true};

             var transaction = new AuthorizeNETTransactionInformation(cardProfile.CreditCardNumber, estimate.Charge, cardProfile.ExpirationDate)
             {
            FirstName = cardProfile.FirstName,
            LastName = cardProfile.LastName,
            CreditCardCode = cardProfile.CardVerificationCode,
            Email = cardProfile.ReceiptEmailAddressCsv,
            InvoiceNumber = string.Format("Est-{0}", request.RequestIdForDisplay),
            Description = "Request Estimate",
            Company = cardProfile.CompanyName.PadRight(50).Substring(0, 50).Trim(),
            Zip = ""
             };

             var paymentGatewayResponse = new PaymentGatewayResponse(string.Empty);

             if (cardProfile.CreditCardId == 0)
             {
            var authorizeNetDirect = new AuthorizeNET(_enableDebug, _loginId, _transactionKey);

            if (!authorizeNetDirect.ProcessAuthorizationAndCapture(transaction))
            {
               response.SuccessfulCharge = false;
               response.ErrorMessage = authorizeNetDirect.Error;
            }

            response.PaymentGatewayResponse = authorizeNetDirect.PaymentGatewayResponse;
             }
             else
             {
            // go through CIM to process transaction
            paymentGatewayResponse = CIMAuthorizationAndCapture(transaction,
                                                                cardProfile.CIMProfileId,
                                                                cardProfile.CIMPaymentProfileId);
            if (paymentGatewayResponse.Errors.Any() || paymentGatewayResponse.GetValue(PaymentGatewayResponse.FieldNames.ResponseCode) != "1")
            {
               var message = paymentGatewayResponse.Errors.Any()
                                ? paymentGatewayResponse.Errors.Aggregate((messages, error) => messages + ", " + error)
                                : paymentGatewayResponse.GetValue(PaymentGatewayResponse.FieldNames.ResponseReasonText);

               response.SuccessfulCharge = false;
               response.ErrorMessage = message;
            }
             }

             if (!response.SuccessfulCharge) return response;

             RecordOrder(cardProfile, paymentGatewayResponse, estimate);

             var requestStatusLookup = new RequestStatusLookup(_dataContext);
             request.IARequestStatusID = requestStatusLookup.GetRequestStatus(RequestStatus.Processing).IARequestStatusID;
             _dataContext.SubmitChanges();

             var approved = DateTime.Now;
             MarkEstimateAsPaid(request, estimate, approved);

             SendCustomerReceipt(cardProfile, request, estimate);

             InformBillingThatCustomerPaid(cardProfile, paymentGatewayResponse, urlBuilder, request, approved, estimate.Charge);

             return response;
        }