public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }

            var formCollection = bindingContext.HttpContext.Request.Form;

            if (formCollection == null || formCollection.Count < 1)
            {
                return(Task.CompletedTask);
            }

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

            foreach (var key in formCollection.Keys)
            {
                StringValues value = string.Empty;

                formCollection.TryGetValue(key: key, value: out value);

                properties.Add(key: key, value: value);
            }

            var model = new PayFastNotify();

            model.FromFormCollection(properties);

            bindingContext.Result = ModelBindingResult.Success(model);

            return(Task.CompletedTask);
        }
Exemple #2
0
        public void Can_Verify_Signature_With_Passphrase()
        {
            // Arrange
            var passPhrase      = "salt";
            var notifyViewModel = new PayFastNotify();

            notifyViewModel.SetPassPhrase(passPhrase);
            notifyViewModel.amount_fee       = "0.00";
            notifyViewModel.amount_gross     = "20.00";
            notifyViewModel.amount_net       = "20.00";
            notifyViewModel.billing_date     = "2017-02-13";
            notifyViewModel.email_address    = "*****@*****.**";
            notifyViewModel.item_description = "Some details about option 2";
            notifyViewModel.item_name        = "Option 2";
            notifyViewModel.m_payment_id     = "8d00bf49-e979-4004-228c-08d452b86380";
            notifyViewModel.merchant_id      = "10004241";
            notifyViewModel.name_first       = "Test";
            notifyViewModel.name_last        = "User 01";
            notifyViewModel.payment_status   = "COMPLETE";
            notifyViewModel.pf_payment_id    = "327767";
            notifyViewModel.signature        = "c5cce9e08316373ca2ba6b427e39772e";
            notifyViewModel.token            = "01c3f68f-5802-4760-c0a5-85d658ccff99";

            // Act
            var calculatedSignature = notifyViewModel.GetCalculatedSignature();

            // Assert
            Assert.Equal(notifyViewModel.signature, calculatedSignature);
        }
Exemple #3
0
        public void Can_Verify_Signature_Without_Passphrase()
        {
            // Arrange
            var notifyViewModel = new PayFastNotify();

            notifyViewModel.amount_fee       = "-2.28";
            notifyViewModel.amount_gross     = "30.00";
            notifyViewModel.amount_net       = "27.72";
            notifyViewModel.email_address    = "*****@*****.**";
            notifyViewModel.item_description = "Some details about the once off payment";
            notifyViewModel.item_name        = "Once off option";
            notifyViewModel.m_payment_id     = "8d00bf49-e979-4004-228c-08d452b86380";
            notifyViewModel.merchant_id      = "10004241";
            notifyViewModel.name_first       = "Test";
            notifyViewModel.name_last        = "User 01";
            notifyViewModel.payment_status   = "COMPLETE";
            notifyViewModel.pf_payment_id    = "392624";
            notifyViewModel.signature        = "a8a4d344281414843db03880265e3d94";

            // Act
            var calculatedSignature = notifyViewModel.GetCalculatedSignature();

            // Assert
            Assert.Equal(notifyViewModel.signature, calculatedSignature);
        }
        public async Task <SaveResult> SaveEntity(PayFastNotifyViewModel viewModel)
        {
            SaveResult saveResult = new SaveResult();
            Dictionary <bool, string> dictionary = new Dictionary <bool, string>();

            var entity = new PayFastNotify();

            try
            {
                if (viewModel.Id != 0)
                {
                    if (_context.PayFastNotify.IgnoreQueryFilters().Any(a => a.Id == viewModel.Id))
                    {
                        entity = await _context.PayFastNotify.IgnoreQueryFilters().FirstOrDefaultAsync(a => a.Id == viewModel.Id);
                    }
                    entity = viewModel.ToEntity(entity);
                    _context.PayFastNotify.Update(entity);
                }
                else
                {
                    entity = viewModel.ToEntity(entity);
                    _context.PayFastNotify.Add(entity);
                }

                await _context.SaveChangesAsync();

                if (entity.Id > 0)
                {
                    saveResult.IsSuccess = true;
                    saveResult.Id        = entity.Id;
                }
            }
            catch (DbUpdateException upDateEx)
            {
                var    results = upDateEx.GetSqlerrorNo();
                string msg     = results == (int)SqlErrNo.FK ? ConstEntity.MissingValueMsg : ConstEntity.UniqueKeyMsg;
                saveResult = dictionary.GetValidateEntityResults(msg).ToSaveResult();
            }
            catch (Exception ex)
            {
                saveResult.Message = CrudError.SaveErrorMsg;
            }


            return(saveResult);
        }
        public async Task <ActionResult> Notify([ModelBinder(typeof(PayFastNotifyModelBinder))] PayFastNotify payFastNotifyViewModel)
        {
            payFastNotifyViewModel.SetPassPhrase(this.payFastSettings.PassPhrase);

            var calculatedSignature = payFastNotifyViewModel.GetCalculatedSignature();

            var isValid = payFastNotifyViewModel.signature == calculatedSignature;

            System.Diagnostics.Debug.WriteLine($"Signature Validation Result: {isValid}");

            // The PayFast Validator is still under developement
            // Its not recommended to rely on this for production use cases
            var payfastValidator = new PayFastValidator(this.payFastSettings, payFastNotifyViewModel, IPAddress.Parse(this.HttpContext.Request.UserHostAddress));

            var merchantIdValidationResult = payfastValidator.ValidateMerchantId();

            System.Diagnostics.Debug.WriteLine($"Merchant Id Validation Result: {merchantIdValidationResult}");

            var ipAddressValidationResult = payfastValidator.ValidateSourceIp();

            System.Diagnostics.Debug.WriteLine($"Ip Address Validation Result: {merchantIdValidationResult}");

            // Currently seems that the data validation only works for successful payments
            var paymentId = payFastNotifyViewModel.m_payment_id;

            if (payFastNotifyViewModel.payment_status == PayFastStatics.CompletePaymentConfirmation)
            {
                var dataValidationResult = await payfastValidator.ValidateData();

                System.Diagnostics.Debug.WriteLine($"Data Validation Result: {dataValidationResult}");
            }

            if (payFastNotifyViewModel.payment_status == PayFastStatics.CancelledPaymentConfirmation)
            {
                System.Diagnostics.Debug.WriteLine($"Subscription was cancelled");
            }

            return(new HttpStatusCodeResult(HttpStatusCode.OK));
        }
Exemple #6
0
        public void Can_Verify_Charge_Signature_With_Passphrase()
        {
            // Arrange
            var notifyViewModel = new PayFastNotify();

            notifyViewModel.SetPassPhrase("salt");
            notifyViewModel.m_payment_id     = "8d00bf49-e979-4004-228c-08d452b86380";
            notifyViewModel.token            = "9aff14eb-65ea-a8ff-ca41-ef457c9c351a";
            notifyViewModel.pf_payment_id    = "392638";
            notifyViewModel.payment_status   = "COMPLETE";
            notifyViewModel.item_name        = "Recurring Option";
            notifyViewModel.item_description = "Some details about the recurring option";
            notifyViewModel.amount_gross     = "20.00";
            notifyViewModel.amount_fee       = "-3.17";
            notifyViewModel.amount_net       = "16.83";
            notifyViewModel.custom_str1      = string.Empty;
            notifyViewModel.custom_str2      = string.Empty;
            notifyViewModel.custom_str3      = string.Empty;
            notifyViewModel.custom_str4      = string.Empty;
            notifyViewModel.custom_str5      = string.Empty;
            notifyViewModel.custom_int1      = string.Empty;
            notifyViewModel.custom_int2      = string.Empty;
            notifyViewModel.custom_int3      = string.Empty;
            notifyViewModel.custom_int4      = string.Empty;
            notifyViewModel.custom_int5      = string.Empty;
            notifyViewModel.name_first       = "Test";
            notifyViewModel.name_last        = "User 01";
            notifyViewModel.email_address    = "*****@*****.**";
            notifyViewModel.merchant_id      = "10004241";

            notifyViewModel.signature = "c629a4b9c9df461a29db663ec0a77ae7";


            // Act
            var calculatedSignature = notifyViewModel.GetCalculatedSignature();

            // Assert
            Assert.Equal(notifyViewModel.signature, calculatedSignature);
        }
Exemple #7
0
        public async Task <IActionResult> Notify([ModelBinder(BinderType = typeof(PayFastNotifyModelBinder))] PayFastNotify payFastNotifyViewModel)
        {
            if (payFastNotifyViewModel != null)
            {
                Ok();
            }
            int CustomerID = (int)TempData["CustomerID"];

            payFastNotifyViewModel.SetPassPhrase(this.payFastSettings.PassPhrase);
            var calculatedSignature = payFastNotifyViewModel.GetCalculatedSignature();
            var isValid             = payFastNotifyViewModel.signature == calculatedSignature;

            logger.LogInformation($"Signature Validation Result: {isValid}");

            var payfastValidator = new PayFastValidator(this.payFastSettings, payFastNotifyViewModel, this.HttpContext.Connection.RemoteIpAddress);

            var merchantIdValidationResult = payfastValidator.ValidateMerchantId();

            logger.LogInformation($"Merchant Id Validation Result: {merchantIdValidationResult}");

            var ipAddressValidationResult = await payfastValidator.ValidateSourceIp();

            logger.LogInformation($"Ip Address Validation Result: {ipAddressValidationResult}");
            // Currently seems that the data validation only works for success
            if (payFastNotifyViewModel.payment_status == PayFastStatics.CompletePaymentConfirmation)
            {
                var dataValidationResult = await payfastValidator.ValidateData();

                logger.LogInformation($"Data Validation Result: {dataValidationResult}");
            }

            if (payFastNotifyViewModel.payment_status == PayFastStatics.CancelledPaymentConfirmation)
            {
                logger.LogInformation($"Subscription was cancelled");
            }
            repo.CustomerPaymentReceived(payFastNotifyViewModel.m_payment_id);
            return(Ok());
        }
Exemple #8
0
        public async Task <IActionResult> Notify([ModelBinder(BinderType = typeof(PayFastNotifyModelBinder))] PayFastNotify payFastNotifyViewModel)
        {
            payFastNotifyViewModel.SetPassPhrase(this.payFastSettings.PassPhrase);

            var calculatedSignature = payFastNotifyViewModel.GetCalculatedSignature();

            var isValid = payFastNotifyViewModel.signature == calculatedSignature;

            this.logger.LogInformation($"Signature Validation Result: {isValid}");

            // The PayFast Validator is still under developement
            // Its not recommended to rely on this for production use cases
            var payfastValidator = new PayFastValidator(this.payFastSettings, payFastNotifyViewModel, this.HttpContext.Connection.RemoteIpAddress);

            var merchantIdValidationResult = payfastValidator.ValidateMerchantId();

            this.logger.LogInformation($"Merchant Id Validation Result: {merchantIdValidationResult}");

            var ipAddressValidationResult = await payfastValidator.ValidateSourceIp();

            this.logger.LogInformation($"Ip Address Validation Result: {ipAddressValidationResult}");

            // Currently seems that the data validation only works for success
            if (payFastNotifyViewModel.payment_status == PayFastStatics.CompletePaymentConfirmation)
            {
                var dataValidationResult = await payfastValidator.ValidateData();

                this.logger.LogInformation($"Data Validation Result: {dataValidationResult}");
            }

            if (payFastNotifyViewModel.payment_status == PayFastStatics.CancelledPaymentConfirmation)
            {
                this.logger.LogInformation($"Subscription was cancelled");
            }

            return(Ok());
        }
Exemple #9
0
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            try
            {
                if (bindingContext == null)
                {
                    throw new ArgumentNullException(nameof(bindingContext));
                }

                var formCollection = controllerContext.HttpContext.Request.Form;

                if (formCollection == null || formCollection.Count < 1)
                {
                    return(null);
                }

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

                foreach (string key in formCollection.Keys)
                {
                    var value = formCollection.Get(key);

                    properties.Add(key: key, value: value);
                }

                var model = new PayFastNotify();
                model.FromFormCollection(properties);

                return(model);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);

                return(null);
            }
        }
Exemple #10
0
        //public void Post([FromBody]string value)
        public async Task <IActionResult> Post([ModelBinder(BinderType = typeof(PayFastNotifyModelBinder))] PayFastNotify payFastNotifyViewModel)
        {
            payFastNotifyViewModel.SetPassPhrase(this._payFastSettings.PassPhrase);
            var calculatedSignature = payFastNotifyViewModel.GetCalculatedSignature();
            var isValid             = payFastNotifyViewModel.signature == calculatedSignature;

            // The PayFast Validator is still under developement
            // Its not recommended to rely on this for production use cases
            var payfastValidator = new PayFastValidator(this._payFastSettings, payFastNotifyViewModel, this.HttpContext.Connection.RemoteIpAddress);

            var merchantIdValidationResult = payfastValidator.ValidateMerchantId();

            var ipAddressValidationResult = await payfastValidator.ValidateSourceIp();

            // Currently seems that the data validation only works for success
            if (payFastNotifyViewModel.payment_status == PayFastStatics.CompletePaymentConfirmation)
            {
                var dataValidationResult = await payfastValidator.ValidateData();

                //Complete Order
                //Todo take this to the application layer service
                //var order = await _ctx.Orders.FirstOrDefaultAsync(x => x.PaymentReference == payFastNotifyViewModel.m_payment_id);
                var order = await _ctx.Orders
                            .Include(x => x.User)
                            .FirstOrDefaultAsync(x => x.OrderNumber == payFastNotifyViewModel.m_payment_id);

                //Place the order
                order.Status = Domain.Enums.OrderStatus.Placed;

                //do cin7 push here
                //var so = await Cin7SalesOrderRequest(order);
                await _ctx.SaveChangesAsync();

                string cmsLink = Url.Action("SingleOrder", "Admin", new { id = order.OrderNumber }, Request.Scheme);


                var address = await _ctx.Addresses.FirstOrDefaultAsync(a => a.Id == order.AddressId);

                Console.WriteLine("PAYFAST LOG TEST");

                if (order.Account != null)
                {
                    Dictionary <string, string> vars = new Dictionary <string, string>
                    {
                        { "ordernumber", order.OrderNumber },
                        { "orderprice", string.Format("R {0}", order.SubTotal) },
                        { "orderdate", DateTime.UtcNow.ToString("dd MMM yyyy") },
                        //    { "location-costcenter", string.Format("", order.Account.CompanyName, order.Account.)},
                        { "orderaddress", string.Format("{0}<br/>{1}<br/>{2}<br/>{3}<br/>{4}<br/>{5}", order.Account.CompanyName, order.Location.Name, address?.Address1, address?.Address2, address?.City, address?.PostCode) },
                        { "cmslink", string.Format("<a href='{0}'>{0}</a>", cmsLink) }
                    };

                    Message m = new Message
                    {
                        FromEmail = "*****@*****.**",
                        FromName  = "Officebox",
                        Subject   = string.Format("OfficeBox Order Placed - {0}", order.OrderNumber),
                        To        = new To[]
                        {
                            new To {
                                Email = "*****@*****.**", Name = "OfficeBox"
                            }
                            //new To { Email = "*****@*****.**", Name = "Carel" }
                        }
                    };

                    _emailSender.SendEmailByTemplate(vars, "internal-order-confirmation-account", m);
                }
                else
                {
                    Dictionary <string, string> vars = new Dictionary <string, string>
                    {
                        { "ordernumber", order.OrderNumber },
                        { "orderprice", string.Format("R {0}", order.SubTotal) },
                        { "orderdate", DateTime.Now.ToString("dd MMM yyyy") },
                        { "orderaddress", string.Format("{0}<br/>{1}<br/>{2}<br/>{3}", address?.Address1, address?.Address2, address?.City, address?.PostCode) },
                        { "cmslink", string.Format("<a href='{0}'>{0}</a>", cmsLink) }
                    };

                    Message m = new Message
                    {
                        FromEmail = "*****@*****.**",
                        FromName  = "Officebox",
                        Subject   = string.Format("OfficeBox Order Placed - {0}", order.OrderNumber),
                        To        = new To[]
                        {
                            new To {
                                Email = "*****@*****.**", Name = "OfficeBox"
                            }
                            //new To { Email = "*****@*****.**", Name = "Carel" }
                        }
                    };

                    _emailSender.SendEmailByTemplate(vars, "internal-order-confirmation", m);
                }



                //_emailSender.SendEmailByTemplate("*****@*****.**", vars, "internal-order-confirmation", m);

                Dictionary <string, string> vars2 = new Dictionary <string, string>
                {
                    { "greeting", string.Format("Hi {0}", order.User.FirstName) },
                    { "greetingdescription", string.Format("Your order {0} has been confirmed and is being processed accordingly.", order.OrderNumber) },
                    { "ordernumber", order.OrderNumber },
                    { "orderprice", string.Format("R {0}", order.SubTotal.ToString("N2")) },
                    { "orderdate", DateTime.UtcNow.ToString("dd MMM yyyy") },
                    { "ordertime", DateTime.UtcNow.ToString("hh:mm tt") },
                    { "orderaddress", string.Format("{0}<br/>{1}<br/>{2}<br/>{3}", address?.Address1, address?.Address2, address?.City, address?.PostCode) },
                };

                Message m2 = new Message
                {
                    FromEmail = "*****@*****.**",
                    FromName  = "Officebox",
                    Subject   = string.Format("Awesome - We’ve received the order - {0}", order.OrderNumber),
                    To        = new To[]
                    {
                        new To {
                            Email = order.User.Email, Name = order.User.FirstName
                        }
                    }
                };

                _emailSender.SendEmailByTemplate(vars2, "finalcomfirmation", m2);
            }
            else if (payFastNotifyViewModel.payment_status == PayFastStatics.CancelledPaymentConfirmation)
            {
                //Cancel Order - delete it
                //Todo take this to the application layer service
                var order = _ctx.Orders.FirstOrDefault(x => x.PaymentReference == payFastNotifyViewModel.m_payment_id);
                _ctx.Orders.Remove(order);
                await _ctx.SaveChangesAsync();
            }

            return(Ok());
        }
Exemple #11
0
        public async Task <IActionResult> Notify([ModelBinder(BinderType = typeof(PayFastNotifyModelBinder))] PayFastNotify payFastNotifyViewModel)
        {
            logger.LogInformation("Payfast Notify URL accessed");

            payFastNotifyViewModel.SetPassPhrase(this._payFastSettings.PassPhrase);

            var calculatedSignature = payFastNotifyViewModel.GetCalculatedSignature();

            var isValid = payFastNotifyViewModel.signature == calculatedSignature;

            // The PayFast Validator is still under developement
            // Its not recommended to rely on this for production use cases
            var payfastValidator = new PayFastValidator(this._payFastSettings, payFastNotifyViewModel, this.HttpContext.Connection.RemoteIpAddress);

            var merchantIdValidationResult = payfastValidator.ValidateMerchantId();

            var ipAddressValidationResult = await payfastValidator.ValidateSourceIp();

            // Currently seems that the data validation only works for success
            if (payFastNotifyViewModel.payment_status == PayFastStatics.CompletePaymentConfirmation)
            {
                var dataValidationResult = await payfastValidator.ValidateData();

                //Compelte Order
                //Todo take this to the application layer service
                var order = _ctx.Orders.FirstOrDefault(x => x.PaymentReference == payFastNotifyViewModel.m_payment_id);

                //Place the order
                order.Status = Domain.Enums.OrderStatus.Placed;

                //do cin7 push here
                //var so = await Cin7SalesOrderRequest(order);
                await _ctx.SaveChangesAsync();

                string cmsLink = Url.Action("SingleOrder", "Admin", new { id = order.OrderNumber }, Request.Scheme);

                Location location = await _ctx.Locations
                                    .Include(l => l.Address)
                                    .Include(l => l.Authorizer)
                                    .FirstOrDefaultAsync(l => l.Id == order.LocationId);

                Dictionary <string, string> vars = new Dictionary <string, string>
                {
                    { "ordernumber", order.OrderNumber },
                    { "orderprice", string.Format("R {0}", order.SubTotal) },
                    { "orderdate", DateTime.UtcNow.ToString("dd MMM yyyy") },
                    { "orderaddress", string.Format("<strong>{0}</strong><br/>{1}<br/>{2}<br/>{3}<br/>{4}", location.Name, location.Address.Address1, location.Address.Address2, location.Address.City, location.Address.PostCode) },
                    { "cmslink", string.Format("<a href='{0}'>{0}</a>", cmsLink) },
                };

                Message m = new Message
                {
                    FromEmail = "*****@*****.**",
                    FromName  = "Officebox",
                    Subject   = string.Format("OfficeBox Order Placed - {0}", order.OrderNumber),
                    To        = new To[]
                    {
                        new To {
                            Email = "*****@*****.**", Name = "OfficeBox"
                        }
                        //new To { Email = "*****@*****.**", Name = "Carel" }
                    }
                };

                _emailSender.SendEmailByTemplate(vars, "internal-order-confirmation", m);
                //_emailSender.SendEmailByTemplate("*****@*****.**", vars, "internal-order-confirmation", m);
            }
            else if (payFastNotifyViewModel.payment_status == PayFastStatics.CancelledPaymentConfirmation)
            {
                //Cancle Order - delete it
                //Todo take this to the application layer service
                var order = _ctx.Orders.FirstOrDefault(x => x.PaymentReference == payFastNotifyViewModel.m_payment_id);

                _ctx.Orders.Remove(order);

                string cmsLink = Url.Action("SingleOrder", "Admin", new { id = order.OrderNumber }, Request.Scheme);

                Location location = await _ctx.Locations
                                    .Include(l => l.Address)
                                    .Include(l => l.Authorizer)
                                    .FirstOrDefaultAsync(l => l.Id == order.LocationId);

                Dictionary <string, string> vars = new Dictionary <string, string>
                {
                    { "ordernumber", order.OrderNumber },
                    { "orderprice", string.Format("R {0}", order.SubTotal) },
                    { "orderdate", DateTime.UtcNow.ToString("dd MMM yyyy") },
                    { "orderaddress", string.Format("<strong>{0}</strong><br/>{1}<br/>{2}<br/>{3}<br/>{4}", location.Name, location.Address.Address1, location.Address.Address2, location.Address.City, location.Address.PostCode) },
                    { "cmslink", string.Format("<a href='{0}'>OfficeBox Order Cancelled</a>", cmsLink) },
                };

                Message m = new Message
                {
                    FromEmail = "*****@*****.**",
                    FromName  = "Officebox",
                    Subject   = string.Format("OfficeBox Order Cancelled - {0}", order.OrderNumber),
                    To        = new To[]
                    {
                        new To {
                            Email = "*****@*****.**", Name = "OfficeBox"
                        }
                        //new To { Email = "*****@*****.**", Name = "Carel" }
                    }
                };

                _emailSender.SendEmailByTemplate(vars, "internal-order-confirmation", m);
                //_emailSender.SendEmailByTemplate("*****@*****.**", vars, "internal-order-confirmation", m);

                await _ctx.SaveChangesAsync();
            }

            return(Ok());
        }