public CheckoutResult CheckoutWithOnSitePayment(CheckoutOrderInfo checkoutOrderInfo)
        {
            if (!checkoutOrderInfo.RequiresPayment)
            {
                checkoutOrderInfo.PaymentProvider = PaymentProviderName.None;
            }

            CheckoutOrderValidator checkoutOrderValidator = new CheckoutOrderValidator();
            ValidationResult       validationResult       = checkoutOrderValidator.Validate(checkoutOrderInfo);

            if (validationResult.IsValid)
            {
                Order pendingOrder = CreateOrder(checkoutOrderInfo, OrderStatusName.Processing);

                if (checkoutOrderInfo.PaymentProvider != PaymentProviderName.None)
                {
                    PaymentStatusName paymentStatus = pendingOrder.PaymentStatus;
                    if (pendingOrder.PaymentStatus != PaymentStatusName.Completed)
                    {
                        PaymentProvider paymentProcessor = PaymentProviderFactory.GetProvider(checkoutOrderInfo.PaymentProvider, storeContext.CurrentStore);

                        HttpWebResponse response = paymentProcessor.SubmitDirectPaymentRequest(pendingOrder, checkoutOrderInfo.CreditCard);
                        paymentStatus = paymentProcessor.ProcessDirectPaymentResponse(pendingOrder, response);
                    }

                    OrderStatusName orderStatus = (paymentStatus == PaymentStatusName.Completed) ? OrderStatusName.Processing : pendingOrder.OrderStatus;
                    UpdateOrderStatus(pendingOrder, orderStatus, paymentStatus);

                    pendingOrder.Save();
                }
                else
                {
                    // does not require payment (free order / order total == 0)
                    UpdateOrderStatus(pendingOrder, OrderStatusName.Processing, PaymentStatusName.Completed);
                }

                return(DoPostCheckoutProcessing(pendingOrder, true));
            }
            else
            {
                // failed validation
                return(new CheckoutResult()
                {
                    SubmittedOrder = null,
                    Errors = validationResult.Errors.ToList().ConvertAll(e => e.ErrorMessage)
                });
            }
        }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            //ModuleConfiguration.ModuleTitle = "Checkout";

            cartController = new CartController(StoreContext);
            //cart = cartController.GetCart(false);

            checkoutOrderInfo = Session[StoreContext.SessionKeys.CheckoutOrderInfo] as CheckoutOrderInfo;
            if (checkoutOrderInfo == null)
            {
                checkoutOrderInfo = new CheckoutOrderInfo()
                {
                    Cart = cartController.GetCart(false)
                };
            }
        }
Example #3
0
        public static decimal CalculateDiscountAmount(Coupon coupon, CheckoutOrderInfo checkoutOrderInfo)
        {
            // we're assuming it's a valid coupon when this is called, maybe not a good idea??

            decimal discountAmount = 0.0m;

            CouponDiscountType discountType = coupon.DiscountTypeName;

            if (discountType == CouponDiscountType.SubTotal)
            {
                if (coupon.IsAmountOff)
                {
                    discountAmount = coupon.AmountOff.Value;
                }
                else if (coupon.IsPercentOff)
                {
                    discountAmount = coupon.PercentOffDecimal * checkoutOrderInfo.SubTotal;
                }
            }
            else if (discountType == CouponDiscountType.Product)
            {
                List <int> couponProductIds = coupon.GetProductIds().ConvertAll(s => Convert.ToInt32(s));
                List <vCartItemProductInfo> cartProductInfos = checkoutOrderInfo.Cart.GetCartItemsWithProductInfo();
                List <int> cartProductIds = cartProductInfos.ConvertAll(p => p.ProductId.Value);

                List <int> intersectedProductIds = cartProductIds.Intersect(couponProductIds).ToList();
                foreach (int productIdToDiscount in intersectedProductIds)
                {
                    vCartItemProductInfo cartItem = cartProductInfos.Find(pi => pi.ProductId.Value == productIdToDiscount);
                    if (cartItem != null)
                    {
                        if (coupon.IsAmountOff)
                        {
                            discountAmount += (coupon.AmountOff.Value * cartItem.Quantity.Value);
                        }
                        else if (coupon.IsPercentOff)
                        {
                            discountAmount += (coupon.PercentOffDecimal * cartItem.GetPriceForQuantity());
                        }
                    }
                }
            }
            else if (discountType == CouponDiscountType.Shipping)
            {
                if (coupon.IsAmountOff)
                {
                    discountAmount = coupon.AmountOff.Value;
                }
                else if (coupon.IsPercentOff)
                {
                    discountAmount = coupon.PercentOffDecimal * checkoutOrderInfo.ShippingRate.Rate;
                }
            }
            else if (discountType == CouponDiscountType.SubTotalAndShipping)
            {
                if (coupon.IsAmountOff)
                {
                    discountAmount = coupon.AmountOff.Value;
                }
                else if (coupon.IsPercentOff)
                {
                    discountAmount = coupon.PercentOffDecimal * (checkoutOrderInfo.SubTotal + checkoutOrderInfo.ShippingRate.Rate);
                }
            }
            else
            {
                throw new NotImplementedException(string.Format(@"""{0}"" is an unknown CouponDiscountType", discountType));
            }

            //--- check we didn't exceed the "Max Discount Amount Per Order"
            if (coupon.MaxDiscountAmountPerOrder.HasValue && (discountAmount > coupon.MaxDiscountAmountPerOrder.Value))
            {
                discountAmount = coupon.MaxDiscountAmountPerOrder.Value;
            }

            return(discountAmount.RoundForMoney());
        }
Example #4
0
        public static bool IsCouponValidForCheckout(Coupon coupon, CheckoutOrderInfo checkoutOrderInfo, out CouponStatus couponStatus)
        {
            couponStatus = CouponStatus.NotFound;

            //Coupon coupon = Coupon.GetCoupon(couponCode, storeId);
            if (coupon != null)
            {
                //--- "Active" status?
                if (!coupon.IsActive.Value)
                {
                    couponStatus = CouponStatus.NotActive;
                    return(false);
                }

                //--- Active Dates?
                if (coupon.ValidFromDate.HasValue)
                {
                    if (DateTime.Today < coupon.ValidFromDate.Value)
                    {
                        couponStatus = CouponStatus.ActiveDateInvalidFrom;
                        return(false);
                    }
                }
                if (coupon.ValidToDate.HasValue)
                {
                    if (DateTime.Today > coupon.ValidToDate.Value)
                    {
                        couponStatus = CouponStatus.ActiveDateInvalidTo;
                        return(false);
                    }
                }

                List <CheckoutCouponInfo> checkoutCouponInfos = checkoutOrderInfo.GetAppliedCoupons();
                //--- already been applied?
                if (checkoutCouponInfos.Exists(c => c.CouponCode == coupon.Code))
                {
                    couponStatus = CouponStatus.AlreadyApplied;
                    return(false);
                }
                //--- combinable?
                if (!coupon.IsCombinable.Value && checkoutCouponInfos.Count > 0)
                {
                    // this coupon is not combinable and user is trying to combine it
                    couponStatus = CouponStatus.NotCombinable;
                    return(false);
                }
                if (checkoutCouponInfos.Count > 1 && checkoutCouponInfos.Exists(cc => cc.IsCombinable == false))
                {
                    // there's multiple coupons applied but at least 1 of them is NOT combinable
                    couponStatus = CouponStatus.NonCombinableCouponAlreadyInUse;
                    return(false);
                }

                CouponDiscountType discountType = coupon.DiscountTypeName;
                //--- Applies to products?
                if (discountType == CouponDiscountType.Product)
                {
                    // make sure the Product(s) the coupon applies to are in the User's Cart
                    List <int> couponProductIds = coupon.GetProductIds().ConvertAll(s => Convert.ToInt32(s));
                    List <int> cartProductIds   = checkoutOrderInfo.Cart.GetCartProducts().ToList().ConvertAll(p => p.Id.Value);

                    // 'cartProductIds' must contain at least 1 of the 'couponProductIds'
                    List <int> intersectedIds = cartProductIds.Intersect(couponProductIds).ToList();
                    if (intersectedIds.Count == 0)
                    {
                        couponStatus = CouponStatus.NoEligibleProduct;
                        return(false);
                    }
                }

                //--- Applies to shipping?
                if (discountType == CouponDiscountType.Shipping)
                {
                    // make sure one of the Shipping Option(s) the coupon applies to has been selected by the User
                    if (checkoutOrderInfo.ShippingProvider != ShippingProviderType.UNKNOWN)
                    {
                        if (!coupon.GetShippingRateTypes().Contains(checkoutOrderInfo.ShippingRate.ServiceType))
                        {
                            couponStatus = CouponStatus.NoEligibleShipping;
                            return(false);
                        }
                    }
                }

                //--- min. cart total
                if (coupon.MinOrderAmount.HasValue && (checkoutOrderInfo.Total < coupon.MinOrderAmount.Value))
                {
                    couponStatus = CouponStatus.MinOrderAmountNotReached;
                    return(false);
                }

                // TODO - Max # redemptions per user
                // Probably need to implement some kind of "User GUID" cookie value at the store level to track unique users/visitors
                // since we can't reliably use UserId (won't work for anonymous checkout) or IP address (different users behind same IP)

                //--- max. # redemptions - lifetime
                if (coupon.MaxUsesLifetime.HasValue)
                {
                    int numLifetimeRedemptions = coupon.GetNumberOfRedemptions();
                    if (numLifetimeRedemptions >= coupon.MaxUsesLifetime.Value)
                    {
                        couponStatus = CouponStatus.ExceededMaxLifetimeRedemptions;
                        return(false);
                    }
                }

                couponStatus = CouponStatus.Valid;
                return(true);
            }
            return(false);
        }
        protected void UpdateCheckoutSession(CheckoutOrderInfo orderInfo)
        {
            //orderInfo.ReCalculateOrderTotals();

            Session[StoreContext.SessionKeys.CheckoutOrderInfo] = orderInfo;
        }
        /// <summary>
        /// Create a "PendingOffsite" Order by copying the CheckoutOrderInfo into an actual Order in the database.
        /// </summary>
        /// <param name="checkoutOrderInfo"></param>
        /// <returns></returns>
        public Order CreateOrder(CheckoutOrderInfo checkoutOrderInfo, OrderStatusName orderStatus)
        {
            using (esTransactionScope transaction = new esTransactionScope())
            {
                Order pendingOrder = new Order();

                if (checkoutOrderInfo.PaymentProvider != PaymentProviderName.CardCaptureOnly)
                {
                    //--- check if we have an existing pending order for this Cart....
                    Order existingOrderByCartId = Order.GetOrderByCartId(checkoutOrderInfo.Cart.Id.Value);
                    if (existingOrderByCartId != null)
                    {
                        //existingOrderByCartId.MarkAsDeleted();
                        existingOrderByCartId.OrderStatus = OrderStatusName.Failed;
                        existingOrderByCartId.Save();
                    }
                }

                //pendingOrder.OrderStatus = OrderStatusName.PendingOffsite;
                pendingOrder.OrderStatus   = orderStatus;
                pendingOrder.PaymentStatus = PaymentStatusName.Pending;

                //---- copy the Checkout Order Info into our Order database object
                pendingOrder.StoreId           = storeContext.CurrentStore.Id.Value;
                pendingOrder.UserId            = storeContext.UserId;
                pendingOrder.CreatedFromCartId = checkoutOrderInfo.Cart.Id;
                pendingOrder.CreatedByIP       = HttpContext.Current.Request.UserHostAddress;
                pendingOrder.OrderNumber       = ""; // we'll update it later

                pendingOrder.CustomerFirstName = checkoutOrderInfo.BillingAddress.FirstName;
                pendingOrder.CustomerLastName  = checkoutOrderInfo.BillingAddress.LastName;
                pendingOrder.CustomerEmail     = checkoutOrderInfo.BillingAddress.Email;

                pendingOrder.BillAddress1    = checkoutOrderInfo.BillingAddress.Address1;
                pendingOrder.BillAddress2    = !string.IsNullOrEmpty(checkoutOrderInfo.BillingAddress.Address2) ? checkoutOrderInfo.BillingAddress.Address2 : String.Empty;
                pendingOrder.BillCity        = checkoutOrderInfo.BillingAddress.City;
                pendingOrder.BillRegion      = checkoutOrderInfo.BillingAddress.Region;
                pendingOrder.BillPostalCode  = checkoutOrderInfo.BillingAddress.PostalCode;
                pendingOrder.BillCountryCode = checkoutOrderInfo.BillingAddress.Country;
                pendingOrder.BillTelephone   = checkoutOrderInfo.BillingAddress.Telephone;

                pendingOrder.ShipRecipientName         = string.Format("{0} {1}", checkoutOrderInfo.ShippingAddress.FirstName, checkoutOrderInfo.ShippingAddress.LastName);
                pendingOrder.ShipRecipientBusinessName = checkoutOrderInfo.ShippingAddress.BusinessName ?? "";
                pendingOrder.ShipAddress1    = checkoutOrderInfo.ShippingAddress.Address1;
                pendingOrder.ShipAddress2    = checkoutOrderInfo.ShippingAddress.Address2;
                pendingOrder.ShipCity        = checkoutOrderInfo.ShippingAddress.City;
                pendingOrder.ShipRegion      = checkoutOrderInfo.ShippingAddress.Region;
                pendingOrder.ShipPostalCode  = checkoutOrderInfo.ShippingAddress.PostalCode;
                pendingOrder.ShipCountryCode = checkoutOrderInfo.ShippingAddress.Country;
                pendingOrder.ShipTelephone   = checkoutOrderInfo.ShippingAddress.Telephone;

                //--- Shipping Provider Stuff
                pendingOrder.ShippingServiceProvider = checkoutOrderInfo.ShippingProvider.ToString();
                pendingOrder.ShippingServiceOption   = checkoutOrderInfo.ShippingRate.ServiceTypeDescription ?? "";
                pendingOrder.ShippingServiceType     = checkoutOrderInfo.ShippingRate.ServiceType ?? "";
                pendingOrder.ShippingServicePrice    = checkoutOrderInfo.ShippingRate.Rate;

                //--- Order Notes
                pendingOrder.OrderNotes = checkoutOrderInfo.OrderNotes ?? "";

                //---- Cart Items
                List <vCartItemProductInfo> cartItems = checkoutOrderInfo.Cart.GetCartItemsWithProductInfo();
                foreach (vCartItemProductInfo cartItem in cartItems)
                {
                    Product product = cartItem.GetProduct();

                    OrderItem newItem = pendingOrder.OrderItemCollectionByOrderId.AddNew();
                    newItem.ProductId = product.Id;
                    newItem.Name      = product.Name;
                    newItem.Sku       = product.Sku;
                    if (product.DeliveryMethodId == 2)
                    {
                        newItem.DigitalFilename        = product.DigitalFilename;
                        newItem.DigitalFileDisplayName = product.DigitalFileDisplayName;
                    }
                    newItem.ProductFieldData = cartItem.ProductFieldData;
                    newItem.Quantity         = cartItem.Quantity;
                    newItem.WeightTotal      = cartItem.GetWeightForQuantity();
                    newItem.PriceTotal       = cartItem.GetPriceForQuantity();
                }

                pendingOrder.SubTotal       = checkoutOrderInfo.SubTotal;
                pendingOrder.ShippingAmount = checkoutOrderInfo.ShippingRate.Rate;
                pendingOrder.DiscountAmount = checkoutOrderInfo.DiscountAmount;
                pendingOrder.TaxAmount      = checkoutOrderInfo.TaxAmount;
                pendingOrder.Total          = checkoutOrderInfo.Total;

                //--- Coupons
                foreach (CheckoutCouponInfo checkoutCoupon in checkoutOrderInfo.GetAppliedCoupons())
                {
                    OrderCoupon orderCoupon = pendingOrder.OrderCouponCollectionByOrderId.AddNew();
                    orderCoupon.CouponCode     = checkoutCoupon.CouponCode;
                    orderCoupon.DiscountAmount = checkoutCoupon.DiscountAmount;
                }

                //--- Save limited Credit Card info to order
                pendingOrder.CreditCardType = checkoutOrderInfo.CreditCard.CardType.ToString();
                // the full card number is not saved here for security
                pendingOrder.CreditCardNumberLast4 = checkoutOrderInfo.CreditCard.CardNumber.Right(4);
                pendingOrder.CreditCardExpiration  = string.Format("{0} / {1}", checkoutOrderInfo.CreditCard.ExpireMonth2Digits, checkoutOrderInfo.CreditCard.ExpireYear);
                // Credit Card CVV not saved here for security
                pendingOrder.CreditCardNameOnCard = checkoutOrderInfo.CreditCard.NameOnCard;

                pendingOrder.Save();

                // update the order number
                pendingOrder.OrderNumber = storeContext.CurrentStore.GetSetting(StoreSettingNames.OrderNumberPrefix) + pendingOrder.Id;
                pendingOrder.Save();

                transaction.Complete();

                int orderId = pendingOrder.Id.Value;
                pendingOrder.LoadByPrimaryKey(orderId);

                return(pendingOrder);
            }
        }