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) }; } }
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()); }
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); } }