Dazzling.Studio.CheckoutService 1.0.6

Provides basic checkout for Paypal and IDeal for ING Bank.

Install-Package Dazzling.Studio.CheckoutService -Version 1.0.6
dotnet add package Dazzling.Studio.CheckoutService --version 1.0.6
<PackageReference Include="Dazzling.Studio.CheckoutService" Version="1.0.6" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Dazzling.Studio.CheckoutService --version 1.0.6
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

IDEAL ING Bank

Get all the issuers

try
            {
                var ideal = cpm.PaymentMethods.Single(x => x.Name.Equals("ideal", StringComparison.InvariantCultureIgnoreCase));
                ServicePointManager.Expect100Continue = true;
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;                

                Connector connector = new Connector();
                connector.MerchantId = ideal["MerchantID"];
                connector.SubId = ideal["SubID"];
                connector.ExpirationPeriod = ideal["ExpirationPeriod"];
                connector.MerchantReturnUrl = new Uri(string.Format(ideal["MerchantReturnURL"], CurrentUser.LanguageCode));

                ING.iDealAdvanced.Data.Issuers issuers = connector.GetIssuerList();

                foreach (var country in issuers.Countries)
                {
                    foreach (var issuer in country.Issuers)
                    {
                        cpm.iDealIssuerList.Add(new SelectListItem() { Text = issuer.Name, Value = issuer.Id.ToString() });
                    }
                }
            }
            catch (ING.iDealAdvanced.Data.IDealException iex)
            {
                // request consumerMessage	
                MailController.Instance(Request, model.Content, CurrentUser.LanguageCode).MailError(new HandleErrorInfo(iex, "CheckoutPaymentPage", "LoadIssueList")).SendAsync();
            }
            catch (Exception ex)
            {
                MailController.Instance(Request, model.Content, CurrentUser.LanguageCode).MailError(new HandleErrorInfo(ex, "CheckoutPaymentPage", "LoadIssueList")).SendAsync();
                //throw;
            }

Mapping the CheckoutOrder object

static readonly IMapper OrderMapper;
        static CheckoutPageController()
        {
            var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<Order, CheckoutOrder>()
                  .ForMember(dest => dest.Company, opt => opt.MapFrom(src => SnuffoSettings.STORE_NAME))
                  .ForMember(dest => dest.OrderReference, opt => opt.MapFrom(src => src.OrderNumber))
                  .ForMember(dest => dest.IssuerId, opt => opt.MapFrom(src => src.MetaData))
                  .ForMember(dest => dest.PaymentMethod, opt => opt.MapFrom(src => string.Equals(src.PaymentMethod.Name, CS.PaymentMethod.iDEAL.ToString(), StringComparison.InvariantCultureIgnoreCase) ? CS.PaymentMethod.iDEAL : CS.PaymentMethod.PayPal))
                  .ForMember(dest => dest.OrderDate, opt => opt.MapFrom(src => src.OrderDate))
                  .ForMember(dest => dest.CallBackUrlOnPaymentSucceed, opt => opt.Ignore())
                  .ForMember(dest => dest.CallBackUrlOnPaymentFailed, opt => opt.Ignore())
                  .ForMember(dest => dest.Currency, opt => opt.MapFrom(src => SnuffoSettings.GetCurrency()))
                  .ForMember(dest => dest.ShippingFee, opt => opt.MapFrom(src => src.CalculateShippingFee()))
                  .ForMember(dest => dest.ServiceFee, opt => opt.MapFrom(src => src.CalculatePaymentFee()))
                  .ForMember(dest => dest.Subtotal, opt => opt.MapFrom(src => src.CalculateSubTotalWithoutVAT()))
                  .ForMember(dest => dest.Total, opt => opt.MapFrom(src => src.CalculateTotal()))
                  .ForMember(dest => dest.Discount, opt => opt.Ignore())
                  .ForMember(dest => dest.VAT, opt => opt.MapFrom(src => src.CalculateVAT()));

                cfg.CreateMap<ProductOrderDetail, CheckoutOrderDetail>()
                  .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Product.Sku))
                  .ForMember(dest => dest.Quantity, opt => opt.MapFrom(src => src.Quantity))
                  .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Product.DisplayName(null)))
                  .ForMember(dest => dest.UnitPrice, opt => opt.MapFrom(src => src.CalculatePriceWithDiscount()));                

            OrderMapper = config.CreateMapper();
            //Mapper.AssertConfigurationIsValid();
        }

Checking out

try
            {
                var order = currentCart.GetOrder();

                var checkoutOrder = OrderMapper.Map<CheckoutOrder>(order);
                string baseUrl = WebUtils.GetApplicationUrlPath(HttpContext.ApplicationInstance.Context);
                checkoutOrder.CallBackUrlOnPaymentSucceed = $"{baseUrl}{CurrentUser.LanguageCode}/checkout-completed";
                checkoutOrder.CallBackUrlOnPaymentFailed = $"{baseUrl}{CurrentUser.LanguageCode}/checkout-cancelled";

                checkoutOrder.OrderDetails.AddRange(OrderMapper.Map<List<CheckoutOrderDetail>>(order.ProductOrderDetails));
                checkoutOrder.OrderDetails.AddRange(OrderMapper.Map<List<CheckoutOrderDetail>>(order.TicketOrderDetails));

                var payment = PaymentBase.CreatePayment(checkoutOrder);
                if (payment.PaymentMethod == CS.PaymentMethod.PayPal)
                {
                    PayPalPayment paypal = payment as PayPalPayment;
                    paypal.IsSandbox = string.Equals(order.PaymentMethod["Mode"], "sandbox");
                    paypal.ClientId = order.PaymentMethod["ClientId"];
                    paypal.ClientSecret = order.PaymentMethod["ClientSecret"];
                }

                if (Request.QueryString.Count == 0)
                {
                    var response = payment.DoPayment();
                    order.PaymentTransactionId = response.PaymentTransactionId;

                    // Save the order
                    currentCart.SaveOrder(order);

                    return Redirect(response.PaymentServiceUrl);
                }

                order.PayerId = Request.QueryString["PayerID"];
                if (payment.RequestPaymentStatus(order.PaymentTransactionId, order.PayerId, out string message) != PaymentStatus.Success)
                {
                    order.PaymentError = message;
                    // Save order
                    order.OrderStatusId = OrderStatus.Cancelled.Id;
                    currentCart.SaveOrder(order);

                    return Redirect($"/{CurrentUser.LanguageCode}/checkout-cancelled/");
                }
                // Tickets are sent immediately
                order.OrderStatusId = (order.ProductOrderDetails.IsNullOrEmpty()) ? OrderStatus.Sent.Id : OrderStatus.Started.Id;

                order.Paid = true;
                order.PaidAmount = order.CalculateTotal();

                currentCart.CompleteOrder(order);

                if (order.ProductOrderDetails.Any())
                {
                    // Send order confirmation mail.
                    MailController.Instance(Request, model.Content, CurrentUser.LanguageCode).ConfirmOrderMail(order).Send();
                }
                if (order.TicketOrderDetails.Any()) // tickets bought
                {
                    MailController.Instance(Request, model.Content, CurrentUser.LanguageCode).SendTicketsPDF(order).Send();
                }
            }
            catch (OrderAlreadyProcessedException)
            {
                // Clear cart.
                currentCart.ClearCart();
            }

IDEAL ING Bank

Get all the issuers

try
            {
                var ideal = cpm.PaymentMethods.Single(x => x.Name.Equals("ideal", StringComparison.InvariantCultureIgnoreCase));
                ServicePointManager.Expect100Continue = true;
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;                

                Connector connector = new Connector();
                connector.MerchantId = ideal["MerchantID"];
                connector.SubId = ideal["SubID"];
                connector.ExpirationPeriod = ideal["ExpirationPeriod"];
                connector.MerchantReturnUrl = new Uri(string.Format(ideal["MerchantReturnURL"], CurrentUser.LanguageCode));

                ING.iDealAdvanced.Data.Issuers issuers = connector.GetIssuerList();

                foreach (var country in issuers.Countries)
                {
                    foreach (var issuer in country.Issuers)
                    {
                        cpm.iDealIssuerList.Add(new SelectListItem() { Text = issuer.Name, Value = issuer.Id.ToString() });
                    }
                }
            }
            catch (ING.iDealAdvanced.Data.IDealException iex)
            {
                // request consumerMessage	
                MailController.Instance(Request, model.Content, CurrentUser.LanguageCode).MailError(new HandleErrorInfo(iex, "CheckoutPaymentPage", "LoadIssueList")).SendAsync();
            }
            catch (Exception ex)
            {
                MailController.Instance(Request, model.Content, CurrentUser.LanguageCode).MailError(new HandleErrorInfo(ex, "CheckoutPaymentPage", "LoadIssueList")).SendAsync();
                //throw;
            }

Mapping the CheckoutOrder object

static readonly IMapper OrderMapper;
        static CheckoutPageController()
        {
            var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<Order, CheckoutOrder>()
                  .ForMember(dest => dest.Company, opt => opt.MapFrom(src => SnuffoSettings.STORE_NAME))
                  .ForMember(dest => dest.OrderReference, opt => opt.MapFrom(src => src.OrderNumber))
                  .ForMember(dest => dest.IssuerId, opt => opt.MapFrom(src => src.MetaData))
                  .ForMember(dest => dest.PaymentMethod, opt => opt.MapFrom(src => string.Equals(src.PaymentMethod.Name, CS.PaymentMethod.iDEAL.ToString(), StringComparison.InvariantCultureIgnoreCase) ? CS.PaymentMethod.iDEAL : CS.PaymentMethod.PayPal))
                  .ForMember(dest => dest.OrderDate, opt => opt.MapFrom(src => src.OrderDate))
                  .ForMember(dest => dest.CallBackUrlOnPaymentSucceed, opt => opt.Ignore())
                  .ForMember(dest => dest.CallBackUrlOnPaymentFailed, opt => opt.Ignore())
                  .ForMember(dest => dest.Currency, opt => opt.MapFrom(src => SnuffoSettings.GetCurrency()))
                  .ForMember(dest => dest.ShippingFee, opt => opt.MapFrom(src => src.CalculateShippingFee()))
                  .ForMember(dest => dest.ServiceFee, opt => opt.MapFrom(src => src.CalculatePaymentFee()))
                  .ForMember(dest => dest.Subtotal, opt => opt.MapFrom(src => src.CalculateSubTotalWithoutVAT()))
                  .ForMember(dest => dest.Total, opt => opt.MapFrom(src => src.CalculateTotal()))
                  .ForMember(dest => dest.Discount, opt => opt.Ignore())
                  .ForMember(dest => dest.VAT, opt => opt.MapFrom(src => src.CalculateVAT()));

                cfg.CreateMap<ProductOrderDetail, CheckoutOrderDetail>()
                  .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Product.Sku))
                  .ForMember(dest => dest.Quantity, opt => opt.MapFrom(src => src.Quantity))
                  .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Product.DisplayName(null)))
                  .ForMember(dest => dest.UnitPrice, opt => opt.MapFrom(src => src.CalculatePriceWithDiscount()));                

            OrderMapper = config.CreateMapper();
            //Mapper.AssertConfigurationIsValid();
        }

Checking out

try
            {
                var order = currentCart.GetOrder();

                var checkoutOrder = OrderMapper.Map<CheckoutOrder>(order);
                string baseUrl = WebUtils.GetApplicationUrlPath(HttpContext.ApplicationInstance.Context);
                checkoutOrder.CallBackUrlOnPaymentSucceed = $"{baseUrl}{CurrentUser.LanguageCode}/checkout-completed";
                checkoutOrder.CallBackUrlOnPaymentFailed = $"{baseUrl}{CurrentUser.LanguageCode}/checkout-cancelled";

                checkoutOrder.OrderDetails.AddRange(OrderMapper.Map<List<CheckoutOrderDetail>>(order.ProductOrderDetails));
                checkoutOrder.OrderDetails.AddRange(OrderMapper.Map<List<CheckoutOrderDetail>>(order.TicketOrderDetails));

                var payment = PaymentBase.CreatePayment(checkoutOrder);
                if (payment.PaymentMethod == CS.PaymentMethod.PayPal)
                {
                    PayPalPayment paypal = payment as PayPalPayment;
                    paypal.IsSandbox = string.Equals(order.PaymentMethod["Mode"], "sandbox");
                    paypal.ClientId = order.PaymentMethod["ClientId"];
                    paypal.ClientSecret = order.PaymentMethod["ClientSecret"];
                }

                if (Request.QueryString.Count == 0)
                {
                    var response = payment.DoPayment();
                    order.PaymentTransactionId = response.PaymentTransactionId;

                    // Save the order
                    currentCart.SaveOrder(order);

                    return Redirect(response.PaymentServiceUrl);
                }

                order.PayerId = Request.QueryString["PayerID"];
                if (payment.RequestPaymentStatus(order.PaymentTransactionId, order.PayerId, out string message) != PaymentStatus.Success)
                {
                    order.PaymentError = message;
                    // Save order
                    order.OrderStatusId = OrderStatus.Cancelled.Id;
                    currentCart.SaveOrder(order);

                    return Redirect($"/{CurrentUser.LanguageCode}/checkout-cancelled/");
                }
                // Tickets are sent immediately
                order.OrderStatusId = (order.ProductOrderDetails.IsNullOrEmpty()) ? OrderStatus.Sent.Id : OrderStatus.Started.Id;

                order.Paid = true;
                order.PaidAmount = order.CalculateTotal();

                currentCart.CompleteOrder(order);

                if (order.ProductOrderDetails.Any())
                {
                    // Send order confirmation mail.
                    MailController.Instance(Request, model.Content, CurrentUser.LanguageCode).ConfirmOrderMail(order).Send();
                }
                if (order.TicketOrderDetails.Any()) // tickets bought
                {
                    MailController.Instance(Request, model.Content, CurrentUser.LanguageCode).SendTicketsPDF(order).Send();
                }
            }
            catch (OrderAlreadyProcessedException)
            {
                // Clear cart.
                currentCart.ClearCart();
            }

Release Notes

- Changed from .netstandard 2.0 to .net framework 4.7.1
- Dazzling.Studio.Utils as nuget package

This package is not used by any popular GitHub repositories.

Version History

Version Downloads Last updated
1.0.6 42 9/28/2019
1.0.5 35 9/28/2019
1.0.4 36 9/28/2019
1.0.3 41 9/26/2019
1.0.2 48 9/23/2019
1.0.1 42 9/17/2019
1.0.0 48 9/9/2019