public void UpdateConsumerInformation(PaymentMethod paymentMethod, ConsumerLegalAddressResult consumerLegalAddress)
        {
            Log.InfoFormat("Updating consumer information for payment with ID:{0} belonging to order with ID: {1}", paymentMethod.Payment.Id, paymentMethod.OrderGroupId);
            if (!(paymentMethod.Payment is ExtendedPayExPayment))
            {
                Log.ErrorFormat("Payment with ID:{0} belonging to order with ID: {1} is not an ExtendedPayExPayment, cannot update consumer information", paymentMethod.Payment.Id, paymentMethod.OrderGroupId);
                return;
            }

            ExtendedPayExPayment payment = paymentMethod.Payment as ExtendedPayExPayment;
            try
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    payment.FirstName = consumerLegalAddress.FirstName;
                    payment.LastName = consumerLegalAddress.LastName;
                    payment.StreetAddress = consumerLegalAddress.Address;
                    payment.PostNumber = consumerLegalAddress.PostNumber;
                    payment.City = consumerLegalAddress.City;
                    payment.CountryCode = consumerLegalAddress.Country;
                    payment.AcceptChanges();
                    scope.Complete();
                    Log.InfoFormat("Successfully updated consumer information for payment with ID:{0} belonging to order with ID: {1}", paymentMethod.Payment.Id, paymentMethod.OrderGroupId);
                }
            }
            catch (Exception e)
            {
                Log.Error("Could not update consumer information. See next log item for more information", e);
                Log.ErrorFormat(
                    "Could not update consumer information for payment with ID:{0}. ConsumerLegalAddressResult:{1}.",
                    payment.Id, consumerLegalAddress);
            }
        }
        public bool Capture(PaymentMethod currentPayment)
        {
            Mediachase.Commerce.Orders.Payment payment = (Mediachase.Commerce.Orders.Payment) currentPayment.Payment;
            Log.InfoFormat("Capturing payment with ID:{0} belonging to order with ID: {1}", payment.Id, payment.OrderGroupId);

            int transactionId;
            if (!int.TryParse(payment.AuthorizationCode, out transactionId))
            {
                Log.ErrorFormat("Could not get PayEx transaction ID from payment with ID:{0} belonging to order with ID: {1}", payment.Id, payment.OrderGroupId);
                return false;
            }
            Log.InfoFormat("PayEx transaction ID is {0} on payment with ID:{1} belonging to order with ID: {2}", transactionId, payment.Id, payment.OrderGroupId);

            long amount = payment.Amount.RoundToLong();
            CaptureResult result = _paymentManager.Capture(transactionId, amount, currentPayment.PurchaseOrder.TrackingNumber, currentPayment.Payment.Vat, string.Empty);

            bool success = false;
            if (result.Success && !string.IsNullOrWhiteSpace(result.TransactionNumber))
            {
                Log.InfoFormat("Setting PayEx transaction number to {0} on payment with ID:{1} belonging to order with ID: {2} during capture", result.TransactionNumber, payment.Id, payment.OrderGroupId);
                payment.ValidationCode = result.TransactionNumber;
                payment.AcceptChanges();
                success = true;
                Log.InfoFormat("Successfully captured payment with ID:{0} belonging to order with ID: {1}", currentPayment.Payment.Id, currentPayment.OrderGroupId);
            }

            if (_paymentCapturer != null)
                return _paymentCapturer.Capture(currentPayment) && success;
            return success;
        }
        public void UpdatePaymentInformation(PaymentMethod paymentMethod, string authorizationCode, string paymentMethodCode)
        {
            try
            {
                Log.InfoFormat("Updating payment information for payment with ID:{0} belonging to order with ID: {1}", paymentMethod.Payment.Id, paymentMethod.OrderGroupId);
                if (string.IsNullOrWhiteSpace(paymentMethodCode))
                {
                    paymentMethodCode = paymentMethod.PaymentMethodCode;
                }

                using (TransactionScope scope = new TransactionScope())
                {
                    Log.InfoFormat("Setting authorization code:{0} for payment with ID:{1} belonging to order with ID: {2}", authorizationCode, paymentMethod.Payment.Id, paymentMethod.OrderGroupId);
                    Log.InfoFormat("Setting payment method code:{0} for payment with ID:{1} belonging to order with ID: {2}", paymentMethodCode, paymentMethod.Payment.Id, paymentMethod.OrderGroupId);
                    ((Mediachase.Commerce.Orders.Payment)paymentMethod.Payment).AuthorizationCode = authorizationCode;
                    ((Mediachase.Commerce.Orders.Payment)paymentMethod.Payment).AcceptChanges();
                    paymentMethod.OrderGroup.OrderForms[0]["PaymentMethodCode"] = paymentMethodCode;
                    paymentMethod.OrderGroup.AcceptChanges();
                    scope.Complete();
                }
            }
            catch (Exception e)
            {
                Log.Error("Could not update payment information. See next log item for more information.", e);
                Log.ErrorFormat("Could not update payment information for orderForm with ID:{0}. AuthorizationCode:{1}. PaymentMethodCode:{2}",
                    paymentMethod.OrderGroup.OrderForms[0].Id, authorizationCode, paymentMethodCode);
            }
        }
        private CustomerDetails CreateModel(PaymentMethod currentPayment)
        {
            if (!(currentPayment.Payment is ExtendedPayExPayment))
                return null;

            ExtendedPayExPayment payment = currentPayment.Payment as ExtendedPayExPayment;
            return new CustomerDetails
            {
                SocialSecurityNumber = payment.SocialSecurityNumber,
                CountryCode = payment.CountryCode,
            };
        }
        private PaymentInformation CreateModel(PaymentMethod currentPayment, string orderNumber)
        {
            string additionalValues = FormatAdditionalValues(currentPayment);
            string priceArgsList = _parameterReader.GetPriceArgsList(currentPayment.PaymentMethodDto);
            string purchaseOperation = currentPayment.PurchaseOperation.ToString();

            return new PaymentInformation(
               currentPayment.Cart.Total.RoundToLong(), priceArgsList, currentPayment.Cart.BillingCurrency, currentPayment.Payment.Vat,
               orderNumber, currentPayment.Payment.ProductNumber, currentPayment.Payment.Description, currentPayment.Payment.ClientIpAddress,
               additionalValues, currentPayment.Payment.ReturnUrl, currentPayment.DefaultView,
               currentPayment.Payment.CancelUrl, ContentLanguage.PreferredCulture.TextInfo.CultureName, purchaseOperation);
        }
        public PaymentInitializeResult Initialize(PaymentMethod currentPayment, string orderNumber, string returnUrl, string orderRef)
        {
            PaymentInitializeResult result = new PaymentInitializeResult();
            Log.InfoFormat("Begin redirect to PayEx for payment with ID:{0} belonging to order with ID: {1}.", currentPayment.Payment.Id, currentPayment.OrderGroupId);
            if (!string.IsNullOrWhiteSpace(returnUrl))
            {
                Log.InfoFormat("Redirecting user PayEx for payment with ID:{0} belonging to order with ID: {1}. ReturnUrl: {2}", currentPayment.Payment.Id, currentPayment.OrderGroupId, returnUrl);
                HttpContext.Current.Response.Redirect(returnUrl, true);
                result.Success = true;
                return result;
            }

            Log.ErrorFormat("Could not redirect user to PayEx for payment with ID:{0} belonging to order with ID: {1}. ReturnUrl was empty!", currentPayment.Payment.Id, currentPayment.OrderGroupId);
            return result;
        }
        public PaymentInitializeResult Initialize(PaymentMethod currentPayment, string orderNumber, string returnUrl, string orderRef)
        {
            Log.InfoFormat("Calling PurchaseInvoiceSale for payment with ID:{0} belonging to order with ID: {1}", currentPayment.Payment.Id, currentPayment.OrderGroupId);
            CustomerDetails customerDetails = CreateModel(currentPayment);
            if (customerDetails == null)
                throw new Exception("Payment class must be ExtendedPayExPayment when using this payment method");

            PurchaseInvoiceSaleResult result = _paymentManager.PurchaseInvoiceSale(orderRef, customerDetails);
            if (!result.Status.Success)
                return new PaymentInitializeResult { ErrorMessage = result.Status.Description };

            _paymentActions.UpdatePaymentInformation(currentPayment, result.TransactionNumber, result.PaymentMethod);

            Log.InfoFormat("Successfully called PurchaseInvoiceSale for payment with ID:{0} belonging to order with ID: {1}", currentPayment.Payment.Id, currentPayment.OrderGroupId);
            return new PaymentInitializeResult { Success = true };
        }
        public PaymentInitializeResult Initialize(PaymentMethod currentPayment, string orderNumber, string returnUrl, string orderRef)
        {
            Log.InfoFormat("Retrieving consumer legal address for payment with ID:{0} belonging to order with ID: {1}", currentPayment.Payment.Id, currentPayment.OrderGroupId);
            CustomerDetails customerDetails = CreateModel(currentPayment);
            if (customerDetails == null)
                throw new Exception("Payment class must be ExtendedPayExPayment when using this payment method");

            ConsumerLegalAddressResult result = _verificationManager.GetConsumerLegalAddress(customerDetails.SocialSecurityNumber, customerDetails.CountryCode);
            if (!result.Status.Success)
                return new PaymentInitializeResult { ErrorMessage = result.Status.Description };

            _paymentActions.UpdateConsumerInformation(currentPayment, result);
            Log.InfoFormat("Successfully retrieved consumer legal address for payment with ID:{0} belonging to order with ID: {1}", currentPayment.Payment.Id, currentPayment.OrderGroupId);

            return _paymentInitializer.Initialize(currentPayment, orderNumber, returnUrl, orderRef);
        }
        private string FormatAdditionalValues(PaymentMethod currentPayment)
        {
            string staticAdditionalValues = _parameterReader.GetAdditionalValues(currentPayment.PaymentMethodDto);
            StringBuilder stringBuilder = new StringBuilder(staticAdditionalValues);

            string dynamicAdditionalValues = _additionalValuesFormatter.Format(currentPayment.Payment as PayExPayment);
            if (!string.IsNullOrWhiteSpace(dynamicAdditionalValues))
            {
                if (!string.IsNullOrWhiteSpace(staticAdditionalValues))
                    stringBuilder.Append("&");

                stringBuilder.Append(dynamicAdditionalValues);
            }

            return stringBuilder.ToString();
        }
        public PaymentInitializeResult Initialize(PaymentMethod currentPayment, string orderNumber, string returnUrl, string orderRef)
        {
            Log.InfoFormat("Initializing payment with ID:{0} belonging to order with ID: {1}", currentPayment.Payment.Id, currentPayment.OrderGroupId);
            PaymentInformation paymentInformation = CreateModel(currentPayment, orderNumber);

            InitializeResult result = _paymentManager.Initialize(currentPayment.Cart, paymentInformation, currentPayment.IsDirectModel, currentPayment.IsDirectModel);
            if (!result.Status.Success)
                return new PaymentInitializeResult { Success = false, ErrorMessage = result.Status.Description };

            Log.InfoFormat("Setting PayEx order reference to {0} on payment with ID:{1} belonging to order with ID: {2}", result.OrderRef, currentPayment.Payment.Id, currentPayment.OrderGroupId);
            currentPayment.Payment.PayExOrderRef = result.OrderRef.ToString();

            _cartActions.UpdateCartInstanceId(currentPayment.Cart); // Save all the changes that have been done to the cart

            if (_paymentInitializer != null)
                return _paymentInitializer.Initialize(currentPayment, orderNumber, result.RedirectUrl, result.OrderRef.ToString());

            return new PaymentInitializeResult { Success = true };
        }
        private CustomerDetails CreateModel(PaymentMethod currentPayment)
        {
            if (!(currentPayment.Payment is ExtendedPayExPayment))
                return null;

            ExtendedPayExPayment payment = currentPayment.Payment as ExtendedPayExPayment;

            return new CustomerDetails
            {
                SocialSecurityNumber = payment.SocialSecurityNumber,
                FirstName = payment.FirstName,
                LastName = payment.LastName,
                StreetAddress = payment.StreetAddress,
                City = payment.City,
                CoAddress = payment.CoAddress,
                CountryCode = payment.CountryCode,
                Email = payment.Email,
                IpAddress = currentPayment.Payment.ClientIpAddress,
                MobilePhone = payment.MobilePhone,
                PostNumber = payment.PostNumber,
            };
        }
        public PaymentInitializeResult Initialize(PaymentMethod currentPayment, string orderNumber, string returnUrl, string orderRef)
        {
            Log.InfoFormat("Generating order number for payment with ID:{0} belonging to order with ID: {1}", currentPayment.Payment.Id, currentPayment.OrderGroupId);
            if (string.IsNullOrWhiteSpace(orderNumber))
                orderNumber = _orderNumberGenerator.Generate(currentPayment.Cart);

            Log.InfoFormat("Generated order number:{0} for payment with ID:{1} belonging to order with ID: {2}", orderNumber, currentPayment.Payment.Id, currentPayment.OrderGroupId);
            currentPayment.Payment.OrderNumber = orderNumber;

            if (!string.IsNullOrWhiteSpace(currentPayment.Payment.Description))
            {
                if (currentPayment.Payment.Description.Contains("{0}"))
                {
                    Log.InfoFormat("Including the ordernumber in the payment description for payment with ID:{0} belonging to order with ID: {1}", currentPayment.Payment.Id, currentPayment.OrderGroupId);
                    currentPayment.Payment.Description = string.Format(currentPayment.Payment.Description, orderNumber);
                    Log.InfoFormat("Payment description is set to:{0} for payment with ID:{1} belonging to order with ID: {2}", currentPayment.Payment.Description, currentPayment.Payment.Id, currentPayment.OrderGroupId);
                }
            }

            Log.InfoFormat("Finished generating order number for payment with ID:{0} belonging to order with ID: {1}", currentPayment.Payment.Id, currentPayment.OrderGroupId);
            return _initializer.Initialize(currentPayment, orderNumber, returnUrl, orderRef);
        }