public void Create_SamplePaymentServiceWithLoggingSet_Success()
        {
            IServiceCollection serviceCollection = new ServiceCollection();

            ILoggerFactory loggerFactory =
                new LoggerFactory();

            #region Initialize Custom Logging
            CustomLoggerProvider customLoggerProvider;
            loggerFactory.AddCustomLogger(out customLoggerProvider);
            #endregion // Initialize Logging

            serviceCollection.AddInstance <ILoggerFactory>(loggerFactory);

            IServiceProvider serviceProvider =
                serviceCollection.BuildServiceProvider();
            MockPaymentService paymentService =
                new MockPaymentService(loggerFactory);

            Assert.StrictEqual <string>(
                "MockPaymentService created",
                customLoggerProvider.Loggers[typeof(MockPaymentService).FullName].LogDataQueue.Dequeue());

            serviceCollection.AddSingleton <ILoggerFactory>();
        }
        /// <summary>
        /// Allows for capturing of a payment reservation. Not used by Active Commerce
        /// out of the box, but would be useful if you wish to automate capture in your
        /// Active Commerce implementation.
        /// </summary>
        public virtual void Capture(Sitecore.Ecommerce.DomainModel.Payments.PaymentSystem paymentSystem, Sitecore.Ecommerce.DomainModel.Payments.PaymentArgs paymentArgs, ReservationTicket reservationTicket, decimal amount)
        {
            var paymentService = new MockPaymentService
            {
                EndpointUrl = paymentSystem.PaymentUrl,
                Username    = paymentSystem.Username,
                Password    = paymentSystem.Password
            };

            //Capture usually requires confirmation of amount to capture,
            //which can be found on the reservation ticket
            var request = new Request
            {
                RequestType         = RequestType.CaptureReservation,
                MerchantOrderNumber = reservationTicket.InvoiceNumber,
                TransactionId       = reservationTicket.TransactionNumber,
                Currency            = paymentArgs.ShoppingCart.Currency.Code,
                Amount = reservationTicket.Amount
            };
            var response = paymentService.ExecuteRequest(request);

            //IMPORTANT: Set PaymentStatus based on response from gateway
            this.PaymentStatus = response.ResponseStatus == ResponseStatus.Success ?
                                 PaymentStatus.Succeeded : PaymentStatus.Failure;
        }
        /// <summary>
        /// Allows for canceling of a reservation, in particular if there is a failure during
        /// order processing after an authorization has been completed.
        /// </summary>
        public virtual void CancelReservation(Sitecore.Ecommerce.DomainModel.Payments.PaymentSystem paymentSystem, Sitecore.Ecommerce.DomainModel.Payments.PaymentArgs paymentArgs, ReservationTicket reservationTicket)
        {
            var paymentService = new MockPaymentService
            {
                EndpointUrl = paymentSystem.PaymentUrl,
                Username    = paymentSystem.Username,
                Password    = paymentSystem.Password
            };
            var request = new Request
            {
                RequestType         = RequestType.VoidReservation,
                MerchantOrderNumber = reservationTicket.InvoiceNumber,
                TransactionId       = reservationTicket.TransactionNumber
            };
            var response = paymentService.ExecuteRequest(request);

            //IMPORTANT: Set PaymentStatus based on response from gateway
            this.PaymentStatus = response.ResponseStatus == ResponseStatus.Success ?
                                 PaymentStatus.Succeeded : PaymentStatus.Failure;
        }
        public void SetUp()
        {
            MockRepository = new MockRepository(MockBehavior.Strict);

            MockLogger         = MockRepository.Create <ILogger <PaymentController> >(MockBehavior.Loose);
            MockPaymentService = MockRepository.Create <IPaymentService>();

            #region MockPaymentService

            // Process Payment Mocks
            MockPaymentService.Setup(m => m.ProcessPayment(It.Is <Payment>(i => i.PaymentId == new Guid("af188a89-0d2a-4863-a596-f7844364ac09"))))
            .Returns((Payment paymentRequest) => new Payment
            {
                Amount            = 10,
                CardExpiryDate    = DateTime.Now,
                CardNumber        = "5425233430109903",
                CurrencyCode      = "GDP",
                CVC               = 132,
                FullName          = "John Doe",
                PaymentId         = new Guid("af188a89-0d2a-4863-a596-f7844364ac09"),
                RequestDate       = DateTime.Now,
                Status            = Common.Enums.PaymentStatus.RequestSucceded,
                RecievingBankName = "TestBank",
                IsSuccessful      = true
            });
            MockPaymentService.Setup(m => m.ProcessPayment(It.Is <Payment>(i => i.PaymentId == new Guid("ff58f525-5528-46e2-8b68-aacec43cd4c1"))))
            .Returns((Payment paymentRequest) => new Payment
            {
                Amount            = 10,
                CardExpiryDate    = DateTime.Now,
                CardNumber        = "5425233430109903",
                CurrencyCode      = "GDP",
                CVC               = 132,
                FullName          = "John Doe",
                PaymentId         = new Guid("ff58f525-5528-46e2-8b68-aacec43cd4c1"),
                RequestDate       = DateTime.Now,
                Status            = Common.Enums.PaymentStatus.DuplicateRequest,
                RecievingBankName = "TestBank",
                IsSuccessful      = false,
                Message           = "Internal Error Please try again later"
            });
            MockPaymentService.Setup(m => m.ProcessPayment(It.Is <Payment>(i => i.PaymentId == new Guid("5cf9b529-5c88-4b35-accd-dfcafe96e180"))))
            .Returns((Payment paymentRequest) => new Payment
            {
                Amount            = 10,
                CardExpiryDate    = DateTime.Now,
                CardNumber        = "5425233430109903",
                CurrencyCode      = "GDP",
                CVC               = 132,
                FullName          = "John Doe",
                PaymentId         = new Guid("5cf9b529-5c88-4b35-accd-dfcafe96e180"),
                RequestDate       = DateTime.Now,
                Status            = Common.Enums.PaymentStatus.Error,
                RecievingBankName = "TestBank",
                IsSuccessful      = false,
                Message           = "Internal Error Please try again later"
            });
            MockPaymentService.Setup(m => m.ProcessPayment(It.Is <Payment>(i => i.PaymentId == new Guid("bf2887a9-9eaf-4f75-a38a-e2d27b885c88"))))
            .Returns((Payment paymentRequest) => new Payment
            {
                Amount            = 10,
                CardExpiryDate    = DateTime.Now,
                CardNumber        = "5425233430109903",
                CurrencyCode      = "GDP",
                CVC               = 132,
                FullName          = "John Doe",
                PaymentId         = new Guid("bf2887a9-9eaf-4f75-a38a-e2d27b885c88"),
                RequestDate       = DateTime.Now,
                Status            = Common.Enums.PaymentStatus.CardNotActivated,
                RecievingBankName = "TestBank",
                IsSuccessful      = false,
                Message           = "The customers card is not activated"
            });

            // Get Payment Mocks
            MockPaymentService.Setup(m => m.GetPayment(It.Is <Guid>(i => i == new Guid("af188a89-0d2a-4863-a596-f7844364ac09"))))
            .Returns((Guid paymentId) => new Payment
            {
                Amount            = 10,
                CardExpiryDate    = DateTime.Now,
                CardNumber        = "5425233430109903",
                CurrencyCode      = "GDP",
                CVC               = 132,
                FullName          = "John Doe",
                IsSuccessful      = true,
                PaymentId         = paymentId,
                RequestDate       = DateTime.Now.AddDays(-1),
                Status            = Common.Enums.PaymentStatus.RequestSucceded,
                RecievingBankName = "TestBank"
            });
            MockPaymentService.Setup(m => m.GetPayment(It.Is <Guid>(i => i == new Guid("14077807-b564-4b0b-9e7a-6b8dbd26e615"))))
            .Returns((Guid paymentId) => new Payment
            {
                PaymentId = new Guid("14077807-b564-4b0b-9e7a-6b8dbd26e615"),
                Status    = Common.Enums.PaymentStatus.RequestDoesNotExist,
                Message   = $"The payment: 14077807-b564-4b0b-9e7a-6b8dbd26e615 does not exist"
            });
            MockPaymentService.Setup(m => m.GetPayment(It.Is <Guid>(i => i == new Guid("13b702ef-18be-427e-931d-21b866aed500"))))
            .Returns((Guid paymentId) => new Payment
            {
                Status = Common.Enums.PaymentStatus.Error
            });
            MockPaymentService.Setup(m => m.GetPayment(It.Is <Guid>(i => i == new Guid("682f6880-5415-44a9-a7bf-c8d1f9a6f43e"))))
            .Returns((Guid paymentId) => new Payment
            {
                Status = Common.Enums.PaymentStatus.Unknown
            });

            #endregion


            var builder = new ContainerBuilder();

            builder.Register(context => new MapperConfiguration(cfg =>
            {
                cfg.CreateMap <PaymentRequest, Payment>()
                .ForMember(dest => dest.PaymentId, opt => opt.MapFrom(src => src.Id));
                cfg.CreateMap <Payment, PaymentResponse>()
                .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.PaymentId));
                cfg.CreateMap <PaymentRequest, User>()
                .ForMember(dest => dest.DateOfBirth, opt => opt.MapFrom(src => src.DateOfBirth))
                .ForMember(dest => dest.Fullname, opt => opt.MapFrom(src => src.FullName))
                .ForMember(dest => dest.Id, opt => opt.Ignore());
                cfg.CreateMap <PaymentRequest, Card>()
                .ForMember(dest => dest.CardNumber, opt => opt.MapFrom(src => src.CardNumber))
                .ForMember(dest => dest.ExpiryDate, opt => opt.MapFrom(src => src.CardExpiryDate))
                .ForMember(dest => dest.CVC, opt => opt.MapFrom(src => src.CVC))
                .ForMember(dest => dest.BankName, opt => opt.MapFrom(src => src.SendingBankName))
                .ForMember(dest => dest.Id, opt => opt.Ignore());
                cfg.CreateMap <User, PaymentResponse>();
                cfg.CreateMap <Card, PaymentResponse>();
            })).AsSelf().SingleInstance();

            builder.Register(c =>
            {
                var context = c.Resolve <IComponentContext>();
                var config  = context.Resolve <MapperConfiguration>();
                return(config.CreateMapper(context.Resolve));
            }).As <IMapper>().InstancePerLifetimeScope();


            builder.RegisterInstance(MockLogger.Object).AsImplementedInterfaces();
            builder.RegisterInstance(MockPaymentService.Object).AsImplementedInterfaces();
            builder.RegisterType <PaymentController>().AsImplementedInterfaces();

            Container = builder.Build();

            PaymentController = Container.Resolve <IPaymentController>();
        }
        /// <summary>
        /// You must implement this method for any integrated/onsite payment provider.
        /// </summary>
        public override void Invoke(Sitecore.Ecommerce.DomainModel.Payments.PaymentSystem paymentSystem, Sitecore.Ecommerce.DomainModel.Payments.PaymentArgs paymentArgs)
        {
            //read credit card and cart from PaymentArgs
            var args       = Assert.ResultNotNull(paymentArgs as ActiveCommerce.Payments.PaymentArgs, "PaymentArgs must be of type ActiveCommerce.Payments.PaymentArgs");
            var creditCard = Assert.ResultNotNull(args.PaymentDetails as ActiveCommerce.Payments.CreditCardInfo, "PaymentDetails must be of type ActiveCommerce.Payments.CreditCardInfo");
            var cart       = Assert.ResultNotNull(args.ShoppingCart as ShoppingCart, "Cart must be of type ActiveCommerce.Carts.ShoppingCart");

            //PaymentSystem contains values configured on payment item
            var paymentService = new MockPaymentService
            {
                EndpointUrl = paymentSystem.PaymentUrl,
                Username    = paymentSystem.Username,
                Password    = paymentSystem.Password
            };

            //XML settings can be read from PaymentSystem using PaymentSettingsReader
            var settingsReader   = new Sitecore.Ecommerce.Payments.PaymentSettingsReader(paymentSystem);
            var authorizeSetting = settingsReader.GetSetting("authorizeOnly");
            var authorizeOnly    = authorizeSetting != null &&
                                   Boolean.TrueString.ToLower().Equals(authorizeSetting.ToLower());

            //read values from cart as needed to construct payment gateway request
            var request = new Request
            {
                RequestType         = authorizeOnly ? RequestType.Authorize : RequestType.AuthorizeAndCapture,
                Amount              = cart.Totals.TotalPriceIncVat,
                Currency            = cart.Currency.Code,
                MerchantOrderNumber = cart.OrderNumber,
                BillToAddress       = new Address
                {
                    Address1   = cart.CustomerInfo.BillingAddress.Address,
                    Address2   = cart.CustomerInfo.BillingAddress.Address2,
                    City       = cart.CustomerInfo.BillingAddress.City,
                    State      = cart.CustomerInfo.BillingAddress.State,
                    Country    = cart.CustomerInfo.BillingAddress.Country.Code,
                    PostalCode = cart.CustomerInfo.BillingAddress.Zip,
                    Email      = cart.CustomerInfo.Email,
                    Phone      = cart.CustomerInfo.BillingAddress.GetPhoneNumber()
                },
                CreditCard = new CreditCard
                {
                    CardNumber   = creditCard.CardNumber,
                    CardType     = creditCard.CardType,
                    Expiration   = creditCard.ExpirationDate.ToString("MM/yy"),
                    SecurityCode = creditCard.SecurityCode
                }
            };
            var response = paymentService.ExecuteRequest(request);

            //IMPORTANT: Set the PaymentStatus based on response from the payment gateway
            if (response.ResponseStatus == ResponseStatus.Success)
            {
                this.PaymentStatus = authorizeOnly ? PaymentStatus.Reserved : PaymentStatus.Captured;

                //If authorize/capture doesn't apply, just set as success:
                //this.PaymentStatus = PaymentStatus.Succeeded;
            }
            else
            {
                this.PaymentStatus = PaymentStatus.Failure;
            }

            //IMPORTANT: Save payment details
            TransactionDetails.TransactionNumber = response.TransactionId;
            TransactionDetails.AuthorizationCode = response.AuthorizationCode;
            TransactionDetails.ProviderStatus    = response.ResponseStatus.ToString();
            TransactionDetails.ProviderMessage   = response.Message;
            TransactionDetails.ProviderErrorCode = response.ResponseCode;

            //IMPORTANT: If a reservation / auth only, save the reservation ticket
            if (this.PaymentStatus == PaymentStatus.Reserved)
            {
                TransactionDetails.ReservationTicket = new ReservationTicket
                {
                    InvoiceNumber     = cart.OrderNumber,
                    Amount            = cart.Totals.TotalPriceIncVat,
                    AuthorizationCode = response.AuthorizationCode,
                    TransactionNumber = response.TransactionId
                };
            }
        }