/// <summary> /// Process a payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public override ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest) { var result = new ProcessPaymentResult { NewPaymentStatus = PaymentStatus.Pending }; return result; }
/// <summary> /// Process a payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public override ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest) { var result = new ProcessPaymentResult(); result.AllowStoringCreditCardNumber = true; switch (_manualPaymentSettings.TransactMode) { case TransactMode.Pending: result.NewPaymentStatus = PaymentStatus.Pending; break; case TransactMode.Authorize: result.NewPaymentStatus = PaymentStatus.Authorized; break; case TransactMode.AuthorizeAndCapture: result.NewPaymentStatus = PaymentStatus.Paid; break; default: { result.AddError(_localizationService.GetResource("Common.Payment.TranactionTypeNotSupported")); return result; } } return result; }
/// <summary> /// Process a payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public override ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest) { var result = new ProcessPaymentResult(); result.AllowStoringDirectDebit = true; result.NewPaymentStatus = PaymentStatus.Pending; return result; }
public override ProcessPaymentRequest GetPaymentInfo(FormCollection form) { var paymentInfo = new ProcessPaymentRequest(); paymentInfo.DirectDebitAccountHolder = form["DirectDebitAccountHolder"]; paymentInfo.DirectDebitAccountNumber = form["DirectDebitAccountNumber"]; paymentInfo.DirectDebitBankCode = form["DirectDebitBankCode"]; paymentInfo.DirectDebitBankName = form["DirectDebitBankName"]; paymentInfo.DirectDebitBic = form["DirectDebitBic"]; paymentInfo.DirectDebitCountry = form["DirectDebitCountry"]; paymentInfo.DirectDebitIban = form["DirectDebitIban"]; return paymentInfo; }
/// <summary> /// Process a payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public override ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest) { var result = new ProcessPaymentResult(); result.NewPaymentStatus = PaymentStatus.Pending; var settings = _commonServices.Settings.LoadSetting<PayPalStandardPaymentSettings>(processPaymentRequest.StoreId); if (settings.BusinessEmail.IsEmpty() || settings.PdtToken.IsEmpty()) { result.AddError(T("Plugins.Payments.PayPalStandard.InvalidCredentials")); } return result; }
public override ProcessPaymentRequest GetPaymentInfo(FormCollection form) { var paymentInfo = new ProcessPaymentRequest(); paymentInfo.CreditCardType = form["CreditCardType"]; paymentInfo.CreditCardName = form["CardholderName"]; paymentInfo.CreditCardNumber = form["CardNumber"]; paymentInfo.CreditCardExpireMonth = int.Parse(form["ExpireMonth"]); paymentInfo.CreditCardExpireYear = int.Parse(form["ExpireYear"]); paymentInfo.CreditCardCvv2 = form["CardCode"]; return paymentInfo; }
public ActionResult OpcConfirmOrder() { try { //validation var cart = _workContext.CurrentCustomer.GetCartItems(ShoppingCartType.ShoppingCart, _storeContext.CurrentStore.Id); if (cart.Count == 0) throw new Exception("Your cart is empty"); if (!UseOnePageCheckout()) throw new Exception("One page checkout is disabled"); if ((_workContext.CurrentCustomer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed)) throw new Exception("Anonymous checkout is not allowed"); //prevent 2 orders being placed within an X seconds time frame if (!IsMinimumOrderPlacementIntervalValid(_workContext.CurrentCustomer)) throw new Exception(_localizationService.GetResource("Checkout.MinOrderPlacementInterval")); //place order var processPaymentRequest = _httpContext.Session["OrderPaymentInfo"] as ProcessPaymentRequest; if (processPaymentRequest == null) { //Check whether payment workflow is required if (IsPaymentWorkflowRequired(cart)) { throw new Exception("Payment information is not entered"); } else processPaymentRequest = new ProcessPaymentRequest(); } processPaymentRequest.StoreId = _storeContext.CurrentStore.Id; processPaymentRequest.CustomerId = _workContext.CurrentCustomer.Id; processPaymentRequest.PaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute<string>( SystemCustomerAttributeNames.SelectedPaymentMethod, _genericAttributeService, _storeContext.CurrentStore.Id); var placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest); if (placeOrderResult.Success) { _httpContext.Session["OrderPaymentInfo"] = null; var postProcessPaymentRequest = new PostProcessPaymentRequest() { Order = placeOrderResult.PlacedOrder }; var paymentMethod = _paymentService.LoadPaymentMethodBySystemName(placeOrderResult.PlacedOrder.PaymentMethodSystemName); if (paymentMethod != null) { if (paymentMethod.PaymentMethodType == PaymentMethodType.Redirection) { //Redirection will not work because it's AJAX request. //That's why we don't process it here (we redirect a user to another page where he'll be redirected) //redirect return Json(new { redirect = string.Format("{0}checkout/OpcCompleteRedirectionPayment", _webHelper.GetStoreLocation()) }); } else { _paymentService.PostProcessPayment(postProcessPaymentRequest); //success return Json(new { success = 1 }); } } else { //payment method could be null if order total is 0 //success return Json(new { success = 1 }); } } else { //error var confirmOrderModel = new CheckoutConfirmModel(); foreach (var error in placeOrderResult.Errors) confirmOrderModel.Warnings.Add(error); return Json(new { update_section = new UpdateSectionJsonModel() { name = "confirm-order", html = this.RenderPartialViewToString("OpcConfirmOrder", confirmOrderModel) }, goto_section = "confirm_order" }); } } catch (Exception exc) { Logger.Warning(exc.Message, exc, _workContext.CurrentCustomer); return Json(new { error = 1, message = exc.Message }); } }
public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest request) { // initiate Amazon payment. We do not add errors to request.Errors cause of asynchronous processing. var result = new ProcessPaymentResult(); var errors = new List<string>(); bool informCustomerAboutErrors = false; bool informCustomerAddErrors = false; try { var orderGuid = request.OrderGuid.ToString(); var store = _storeService.GetStoreById(request.StoreId); var currency = _services.WorkContext.WorkingCurrency; var settings = _services.Settings.LoadSetting<AmazonPaySettings>(store.Id); var state = _httpContext.GetAmazonPayState(_services.Localization); var client = new AmazonPayClient(settings); informCustomerAboutErrors = settings.InformCustomerAboutErrors; informCustomerAddErrors = settings.InformCustomerAddErrors; _api.Authorize(client, result, errors, state.OrderReferenceId, request.OrderTotal, currency.CurrencyCode, orderGuid); } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc, errors: errors); } catch (Exception exc) { LogError(exc, errors: errors); } if (informCustomerAboutErrors && errors != null && errors.Count > 0) { // customer needs to be informed of an amazon error here. hooking OrderPlaced.CustomerNotification won't work // cause of asynchronous processing. solution: we add a customer order note that is also send as an email. var state = new AmazonPayActionState() { OrderGuid = request.OrderGuid }; if (informCustomerAddErrors) { state.Errors = new List<string>(); state.Errors.AddRange(errors); } AsyncRunner.Run((container, x) => { var obj = x as AmazonPayActionState; container.Resolve<IAmazonPayService>().AddCustomerOrderNoteLoop(obj); }, state, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); } return result; }
/// <summary> /// Process next recurring psayment /// </summary> /// <param name="recurringPayment">Recurring payment</param> public virtual void ProcessNextRecurringPayment(RecurringPayment recurringPayment) { if (recurringPayment == null) throw new ArgumentNullException("recurringPayment"); try { if (!recurringPayment.IsActive) throw new SmartException(T("Payment.RecurringPaymentNotActive")); var initialOrder = recurringPayment.InitialOrder; if (initialOrder == null) throw new SmartException(T("Order.InitialOrderDoesNotExistForRecurringPayment")); var customer = initialOrder.Customer; if (customer == null) throw new SmartException(T("Customer.DoesNotExist")); var nextPaymentDate = recurringPayment.NextPaymentDate; if (!nextPaymentDate.HasValue) throw new SmartException(T("Payment.CannotCalculateNextPaymentDate")); var paymentInfo = new ProcessPaymentRequest { StoreId = initialOrder.StoreId, CustomerId = customer.Id, OrderGuid = Guid.NewGuid(), IsRecurringPayment = true, InitialOrderId = initialOrder.Id, RecurringCycleLength = recurringPayment.CycleLength, RecurringCyclePeriod = recurringPayment.CyclePeriod, RecurringTotalCycles = recurringPayment.TotalCycles, }; //place a new order var result = this.PlaceOrder(paymentInfo, new Dictionary<string, string>()); if (result.Success) { if (result.PlacedOrder == null) throw new SmartException(T("Order.NotFound", "".NaIfEmpty())); var rph = new RecurringPaymentHistory { RecurringPayment = recurringPayment, CreatedOnUtc = DateTime.UtcNow, OrderId = result.PlacedOrder.Id }; recurringPayment.RecurringPaymentHistory.Add(rph); _orderService.UpdateRecurringPayment(recurringPayment); } else if (result.Errors.Count > 0) { throw new SmartException(string.Join(" ", result.Errors)); } } catch (Exception exception) { _logger.ErrorsAll(exception); throw; } }
/// <summary> /// Process a payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public virtual ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest) { if (processPaymentRequest.OrderTotal == decimal.Zero) { var result = new ProcessPaymentResult() { NewPaymentStatus = PaymentStatus.Paid }; return result; } else { //We should strip out any white space or dash in the CC number entered. if (!String.IsNullOrWhiteSpace(processPaymentRequest.CreditCardNumber)) { processPaymentRequest.CreditCardNumber = processPaymentRequest.CreditCardNumber.Replace(" ", ""); processPaymentRequest.CreditCardNumber = processPaymentRequest.CreditCardNumber.Replace("-", ""); } var paymentMethod = LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName); if (paymentMethod == null) throw new SmartException("Payment method couldn't be loaded"); return paymentMethod.Value.ProcessPayment(processPaymentRequest); } }
public override ProcessPaymentRequest GetPaymentInfo(FormCollection form) { var paymentInfo = new ProcessPaymentRequest(); return paymentInfo; }
public override ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest) { var result = _apiService.ProcessPayment(processPaymentRequest); return result; }
/// <summary> /// Process recurring payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public virtual ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest) { throw Error.NotSupported(); }
public ActionResult ConfirmOrder(FormCollection form) { //validation var cart = _workContext.CurrentCustomer.GetCartItems(ShoppingCartType.ShoppingCart, _storeContext.CurrentStore.Id); if (cart.Count == 0) return RedirectToRoute("ShoppingCart"); if ((_workContext.CurrentCustomer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed)) return new HttpUnauthorizedResult(); //model var model = new CheckoutConfirmModel(); try { var processPaymentRequest = _httpContext.Session["OrderPaymentInfo"] as ProcessPaymentRequest; if (processPaymentRequest == null) { //Check whether payment workflow is required if (IsPaymentWorkflowRequired(cart)) return RedirectToAction("PaymentMethod"); processPaymentRequest = new ProcessPaymentRequest(); } //prevent 2 orders being placed within an X seconds time frame if (!IsMinimumOrderPlacementIntervalValid(_workContext.CurrentCustomer)) throw new Exception(_localizationService.GetResource("Checkout.MinOrderPlacementInterval")); //place order processPaymentRequest.StoreId = _storeContext.CurrentStore.Id; processPaymentRequest.CustomerId = _workContext.CurrentCustomer.Id; processPaymentRequest.PaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute<string>( SystemCustomerAttributeNames.SelectedPaymentMethod, _genericAttributeService, _storeContext.CurrentStore.Id); var placeOrderExtraData = new Dictionary<string, string>(); placeOrderExtraData["CustomerComment"] = form["customercommenthidden"]; var placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest, placeOrderExtraData); if (placeOrderResult.Success) { var postProcessPaymentRequest = new PostProcessPaymentRequest { Order = placeOrderResult.PlacedOrder }; _paymentService.PostProcessPayment(postProcessPaymentRequest); _httpContext.Session["PaymentData"] = null; _httpContext.Session["OrderPaymentInfo"] = null; _httpContext.RemoveCheckoutState(); if (_webHelper.IsRequestBeingRedirected || _webHelper.IsPostBeingDone) { //redirection or POST has been done in PostProcessPayment return Content("Redirected"); } else { //if no redirection has been done (to a third-party payment page) //theoretically it's not possible return RedirectToAction("Completed"); } } else { foreach (var error in placeOrderResult.Errors) model.Warnings.Add(error); } } catch (Exception exc) { Logger.Warning(exc.Message, exc); model.Warnings.Add(exc.Message); } //If we got this far, something failed, redisplay form //if (model.Warnings.Count > 0) // TempData["ConfirmOrderWarnings"] = model.Warnings; //return RedirectToRoute("CheckoutConfirm"); return View(model); }
/// <summary> /// Process recurring payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public override ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest) { var result = new ProcessPaymentResult(); result.AllowStoringDirectDebit = true; result.AddError(_localizationService.GetResource("Common.Payment.NoRecurringPaymentSupport")); return result; }
/// <summary> /// Process recurring payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public override ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest) { var result = new ProcessPaymentResult(); result.AddError("Recurring method not supported"); return result; }
/// <summary> /// Process a payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public override ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest) { var result = new ProcessPaymentResult(); result.NewPaymentStatus = PaymentStatus.Paid; return result; }
/// <summary> /// Process recurring payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public virtual ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest) { throw Error.NotSupported(); }
/// <summary> /// Process payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public abstract ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest);
/// <summary> /// Process payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public abstract ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest);
public ActionResult ConfirmOrder(FormCollection form) { //validation var storeId = _storeContext.CurrentStore.Id; var customer = _workContext.CurrentCustomer; var cart = customer.GetCartItems(ShoppingCartType.ShoppingCart, storeId); if (cart.Count == 0) return RedirectToRoute("ShoppingCart"); if ((customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed)) return new HttpUnauthorizedResult(); var model = new CheckoutConfirmModel(); PlaceOrderResult placeOrderResult = null; PostProcessPaymentRequest postProcessPaymentRequest = null; try { var processPaymentRequest = _httpContext.Session["OrderPaymentInfo"] as ProcessPaymentRequest; if (processPaymentRequest == null) { //Check whether payment workflow is required if (IsPaymentWorkflowRequired(cart)) return RedirectToAction("PaymentMethod"); processPaymentRequest = new ProcessPaymentRequest(); } //prevent 2 orders being placed within an X seconds time frame if (!IsMinimumOrderPlacementIntervalValid(customer)) throw new Exception(T("Checkout.MinOrderPlacementInterval")); //place order processPaymentRequest.StoreId = storeId; processPaymentRequest.CustomerId = customer.Id; processPaymentRequest.PaymentMethodSystemName = customer.GetAttribute<string>(SystemCustomerAttributeNames.SelectedPaymentMethod, _genericAttributeService, storeId); var placeOrderExtraData = new Dictionary<string, string>(); placeOrderExtraData["CustomerComment"] = form["customercommenthidden"]; placeOrderExtraData["SubscribeToNewsLetter"] = form["SubscribeToNewsLetterHidden"]; placeOrderExtraData["AcceptThirdPartyEmailHandOver"] = form["AcceptThirdPartyEmailHandOverHidden"]; placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest, placeOrderExtraData); if (!placeOrderResult.Success) { model.Warnings.AddRange(placeOrderResult.Errors.Select(x => HtmlUtils.ConvertPlainTextToHtml(x))); } } catch (Exception exception) { Logger.Warning(exception.Message, exception); if (!model.Warnings.Any(x => x == exception.Message)) { model.Warnings.Add(exception.Message); } } if (placeOrderResult == null || !placeOrderResult.Success || model.Warnings.Any()) { return View(model); } try { postProcessPaymentRequest = new PostProcessPaymentRequest { Order = placeOrderResult.PlacedOrder }; _paymentService.PostProcessPayment(postProcessPaymentRequest); } catch (Exception exception) { NotifyError(exception); } finally { _httpContext.Session["PaymentData"] = null; _httpContext.Session["OrderPaymentInfo"] = null; _httpContext.RemoveCheckoutState(); } if (postProcessPaymentRequest != null && postProcessPaymentRequest.RedirectUrl.HasValue()) { return Redirect(postProcessPaymentRequest.RedirectUrl); } return RedirectToAction("Completed"); }
/// <summary> /// Places an order /// </summary> /// <param name="processPaymentRequest">Process payment request</param> /// <returns>Place order result</returns> public virtual PlaceOrderResult PlaceOrder(ProcessPaymentRequest processPaymentRequest, Dictionary<string, string> extraData) { //think about moving functionality of processing recurring orders (after the initial order was placed) to ProcessNextRecurringPayment() method if (processPaymentRequest == null) throw new ArgumentNullException("processPaymentRequest"); if (processPaymentRequest.OrderGuid == Guid.Empty) processPaymentRequest.OrderGuid = Guid.NewGuid(); var result = new PlaceOrderResult(); var utcNow = DateTime.UtcNow; try { #region Order details (customer, totals) //Recurring orders. Load initial order Order initialOrder = _orderService.GetOrderById(processPaymentRequest.InitialOrderId); if (processPaymentRequest.IsRecurringPayment) { if (initialOrder == null) throw new ArgumentException("Initial order is not set for recurring payment"); processPaymentRequest.PaymentMethodSystemName = initialOrder.PaymentMethodSystemName; } //customer var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId); if (customer == null) throw new ArgumentException("Customer is not set"); //affilites int affiliateId = 0; var affiliate = _affiliateService.GetAffiliateById(customer.AffiliateId); if (affiliate != null && affiliate.Active && !affiliate.Deleted) affiliateId = affiliate.Id; //customer currency string customerCurrencyCode = ""; decimal customerCurrencyRate = decimal.Zero; if (!processPaymentRequest.IsRecurringPayment) { var currencyTmp = _currencyService.GetCurrencyById(customer.GetAttribute<int>(SystemCustomerAttributeNames.CurrencyId, processPaymentRequest.StoreId)); var customerCurrency = (currencyTmp != null && currencyTmp.Published) ? currencyTmp : _workContext.WorkingCurrency; customerCurrencyCode = customerCurrency.CurrencyCode; var primaryStoreCurrency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); customerCurrencyRate = customerCurrency.Rate / primaryStoreCurrency.Rate; } else { customerCurrencyCode = initialOrder.CustomerCurrencyCode; customerCurrencyRate = initialOrder.CurrencyRate; } //customer language Language customerLanguage = null; if (!processPaymentRequest.IsRecurringPayment) { customerLanguage = _languageService.GetLanguageById(customer.GetAttribute<int>( SystemCustomerAttributeNames.LanguageId, processPaymentRequest.StoreId)); } else { customerLanguage = _languageService.GetLanguageById(initialOrder.CustomerLanguageId); } if (customerLanguage == null || !customerLanguage.Published) customerLanguage = _workContext.WorkingLanguage; //check whether customer is guest if (customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed) throw new SmartException("Anonymous checkout is not allowed"); var storeId = _storeContext.CurrentStore.Id; //load and validate customer shopping cart IList<OrganizedShoppingCartItem> cart = null; if (!processPaymentRequest.IsRecurringPayment) { //load shopping cart cart = customer.GetCartItems(ShoppingCartType.ShoppingCart, processPaymentRequest.StoreId); if (cart.Count == 0) throw new SmartException("Cart is empty"); //validate the entire shopping cart var warnings = _shoppingCartService.GetShoppingCartWarnings(cart, customer.GetAttribute<string>(SystemCustomerAttributeNames.CheckoutAttributes), true); if (warnings.Count > 0) { var warningsSb = new StringBuilder(); foreach (string warning in warnings) { warningsSb.Append(warning); warningsSb.Append(";"); } throw new SmartException(warningsSb.ToString()); } //validate individual cart items foreach (var sci in cart) { var sciWarnings = _shoppingCartService.GetShoppingCartItemWarnings(customer, sci.Item.ShoppingCartType, sci.Item.Product, processPaymentRequest.StoreId, sci.Item.AttributesXml, sci.Item.CustomerEnteredPrice, sci.Item.Quantity, false, childItems: sci.ChildItems); if (sciWarnings.Count > 0) { var warningsSb = new StringBuilder(); foreach (string warning in sciWarnings) { warningsSb.Append(warning); warningsSb.Append(";"); } throw new SmartException(warningsSb.ToString()); } } } //min totals validation if (!processPaymentRequest.IsRecurringPayment) { bool minOrderSubtotalAmountOk = ValidateMinOrderSubtotalAmount(cart); if (!minOrderSubtotalAmountOk) { decimal minOrderSubtotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderSubtotalAmount, _workContext.WorkingCurrency); throw new SmartException(string.Format(_localizationService.GetResource("Checkout.MinOrderSubtotalAmount"), _priceFormatter.FormatPrice(minOrderSubtotalAmount, true, false))); } bool minOrderTotalAmountOk = ValidateMinOrderTotalAmount(cart); if (!minOrderTotalAmountOk) { decimal minOrderTotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderTotalAmount, _workContext.WorkingCurrency); throw new SmartException(string.Format(_localizationService.GetResource("Checkout.MinOrderTotalAmount"), _priceFormatter.FormatPrice(minOrderTotalAmount, true, false))); } } //tax display type var customerTaxDisplayType = TaxDisplayType.IncludingTax; if (!processPaymentRequest.IsRecurringPayment) { customerTaxDisplayType = _workContext.GetTaxDisplayTypeFor(customer, processPaymentRequest.StoreId); } else { customerTaxDisplayType = initialOrder.CustomerTaxDisplayType; } //checkout attributes string checkoutAttributeDescription, checkoutAttributesXml; if (!processPaymentRequest.IsRecurringPayment) { checkoutAttributesXml = customer.GetAttribute<string>(SystemCustomerAttributeNames.CheckoutAttributes); checkoutAttributeDescription = _checkoutAttributeFormatter.FormatAttributes(checkoutAttributesXml, customer); } else { checkoutAttributesXml = initialOrder.CheckoutAttributesXml; checkoutAttributeDescription = initialOrder.CheckoutAttributeDescription; } //applied discount (used to store discount usage history) var appliedDiscounts = new List<Discount>(); //sub total decimal orderSubTotalInclTax, orderSubTotalExclTax; decimal orderSubTotalDiscountInclTax = 0, orderSubTotalDiscountExclTax = 0; if (!processPaymentRequest.IsRecurringPayment) { //sub total (incl tax) decimal orderSubTotalDiscountAmount1 = decimal.Zero; Discount orderSubTotalAppliedDiscount1 = null; decimal subTotalWithoutDiscountBase1 = decimal.Zero; decimal subTotalWithDiscountBase1 = decimal.Zero; _orderTotalCalculationService.GetShoppingCartSubTotal(cart, true, out orderSubTotalDiscountAmount1, out orderSubTotalAppliedDiscount1, out subTotalWithoutDiscountBase1, out subTotalWithDiscountBase1); orderSubTotalInclTax = subTotalWithoutDiscountBase1; orderSubTotalDiscountInclTax = orderSubTotalDiscountAmount1; //discount history if (orderSubTotalAppliedDiscount1 != null && !appliedDiscounts.ContainsDiscount(orderSubTotalAppliedDiscount1)) appliedDiscounts.Add(orderSubTotalAppliedDiscount1); //sub total (excl tax) decimal orderSubTotalDiscountAmount2 = decimal.Zero; Discount orderSubTotalAppliedDiscount2 = null; decimal subTotalWithoutDiscountBase2 = decimal.Zero; decimal subTotalWithDiscountBase2 = decimal.Zero; _orderTotalCalculationService.GetShoppingCartSubTotal(cart, false, out orderSubTotalDiscountAmount2, out orderSubTotalAppliedDiscount2, out subTotalWithoutDiscountBase2, out subTotalWithDiscountBase2); orderSubTotalExclTax = subTotalWithoutDiscountBase2; orderSubTotalDiscountExclTax = orderSubTotalDiscountAmount2; } else { orderSubTotalInclTax = initialOrder.OrderSubtotalInclTax; orderSubTotalExclTax = initialOrder.OrderSubtotalExclTax; } //shipping info bool shoppingCartRequiresShipping = false; if (!processPaymentRequest.IsRecurringPayment) { shoppingCartRequiresShipping = cart.RequiresShipping(); } else { shoppingCartRequiresShipping = initialOrder.ShippingStatus != ShippingStatus.ShippingNotRequired; } string shippingMethodName = "", shippingRateComputationMethodSystemName = ""; if (shoppingCartRequiresShipping) { if (!processPaymentRequest.IsRecurringPayment) { var shippingOption = customer.GetAttribute<ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, processPaymentRequest.StoreId); if (shippingOption != null) { shippingMethodName = shippingOption.Name; shippingRateComputationMethodSystemName = shippingOption.ShippingRateComputationMethodSystemName; } } else { shippingMethodName = initialOrder.ShippingMethod; shippingRateComputationMethodSystemName = initialOrder.ShippingRateComputationMethodSystemName; } } //shipping total decimal? orderShippingTotalInclTax, orderShippingTotalExclTax = null; if (!processPaymentRequest.IsRecurringPayment) { decimal taxRate = decimal.Zero; Discount shippingTotalDiscount = null; orderShippingTotalInclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart, true, out taxRate, out shippingTotalDiscount); orderShippingTotalExclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart, false); if (!orderShippingTotalInclTax.HasValue || !orderShippingTotalExclTax.HasValue) throw new SmartException("Shipping total couldn't be calculated"); if (shippingTotalDiscount != null && !appliedDiscounts.ContainsDiscount(shippingTotalDiscount)) appliedDiscounts.Add(shippingTotalDiscount); } else { orderShippingTotalInclTax = initialOrder.OrderShippingInclTax; orderShippingTotalExclTax = initialOrder.OrderShippingExclTax; } //payment total decimal paymentAdditionalFeeInclTax, paymentAdditionalFeeExclTax; if (!processPaymentRequest.IsRecurringPayment) { decimal paymentAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, processPaymentRequest.PaymentMethodSystemName); paymentAdditionalFeeInclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, true, customer); paymentAdditionalFeeExclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, false, customer); } else { paymentAdditionalFeeInclTax = initialOrder.PaymentMethodAdditionalFeeInclTax; paymentAdditionalFeeExclTax = initialOrder.PaymentMethodAdditionalFeeExclTax; } //tax total decimal orderTaxTotal = decimal.Zero; string vatNumber = "", taxRates = ""; if (!processPaymentRequest.IsRecurringPayment) { //tax amount SortedDictionary<decimal, decimal> taxRatesDictionary = null; orderTaxTotal = _orderTotalCalculationService.GetTaxTotal(cart, out taxRatesDictionary); //VAT number var customerVatStatus = (VatNumberStatus)customer.GetAttribute<int>(SystemCustomerAttributeNames.VatNumberStatusId); if (_taxSettings.EuVatEnabled && customerVatStatus == VatNumberStatus.Valid) vatNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.VatNumber); //tax rates foreach (var kvp in taxRatesDictionary) { var taxRate = kvp.Key; var taxValue = kvp.Value; taxRates += string.Format("{0}:{1}; ", taxRate.ToString(CultureInfo.InvariantCulture), taxValue.ToString(CultureInfo.InvariantCulture)); } } else { orderTaxTotal = initialOrder.OrderTax; //VAT number vatNumber = initialOrder.VatNumber; } processPaymentRequest.OrderTax = orderTaxTotal; //order total (and applied discounts, gift cards, reward points) decimal? orderTotal = null; decimal orderDiscountAmount = decimal.Zero; List<AppliedGiftCard> appliedGiftCards = null; int redeemedRewardPoints = 0; decimal redeemedRewardPointsAmount = decimal.Zero; if (!processPaymentRequest.IsRecurringPayment) { Discount orderAppliedDiscount = null; orderTotal = _orderTotalCalculationService.GetShoppingCartTotal(cart, out orderDiscountAmount, out orderAppliedDiscount, out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount); if (!orderTotal.HasValue) throw new SmartException("Order total couldn't be calculated"); //discount history if (orderAppliedDiscount != null && !appliedDiscounts.ContainsDiscount(orderAppliedDiscount)) appliedDiscounts.Add(orderAppliedDiscount); } else { orderDiscountAmount = initialOrder.OrderDiscount; orderTotal = initialOrder.OrderTotal; } processPaymentRequest.OrderTotal = orderTotal.Value; #endregion #region Addresses & pre payment workflow // give payment processor the opportunity to fullfill billing address var preProcessPaymentResult = _paymentService.PreProcessPayment(processPaymentRequest); if (!preProcessPaymentResult.Success) { foreach (var paymentError in preProcessPaymentResult.Errors) { result.AddError(string.Format("Payment error: {0}", paymentError)); } throw new SmartException("Error while pre-processing the payment"); } Address billingAddress = null; if (!processPaymentRequest.IsRecurringPayment) { if (customer.BillingAddress == null) throw new SmartException("Billing address is not provided"); if (!customer.BillingAddress.Email.IsEmail()) throw new SmartException("Email is not valid"); billingAddress = (Address)customer.BillingAddress.Clone(); } else { if (initialOrder.BillingAddress == null) throw new SmartException("Billing address is not available"); billingAddress = (Address)initialOrder.BillingAddress.Clone(); } if (billingAddress.Country != null && !billingAddress.Country.AllowsBilling) throw new SmartException(string.Format("Country '{0}' is not allowed for billing", billingAddress.Country.Name)); Address shippingAddress = null; if (shoppingCartRequiresShipping) { if (!processPaymentRequest.IsRecurringPayment) { if (customer.ShippingAddress == null) throw new SmartException("Shipping address is not provided"); if (!customer.ShippingAddress.Email.IsEmail()) throw new SmartException("Email is not valid"); shippingAddress = (Address)customer.ShippingAddress.Clone(); } else { if (initialOrder.ShippingAddress == null) throw new SmartException("Shipping address is not available"); shippingAddress = (Address)initialOrder.ShippingAddress.Clone(); } if (shippingAddress.Country != null && !shippingAddress.Country.AllowsShipping) throw new SmartException(string.Format("Country '{0}' is not allowed for shipping", shippingAddress.Country.Name)); } #endregion #region Payment workflow //skip payment workflow if order total equals zero bool skipPaymentWorkflow = false; if (orderTotal.Value == decimal.Zero) skipPaymentWorkflow = true; //payment workflow Provider<IPaymentMethod> paymentMethod = null; if (!skipPaymentWorkflow) { paymentMethod = _paymentService.LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName); if (paymentMethod == null) throw new SmartException("Payment method couldn't be loaded"); //ensure that payment method is active if (!paymentMethod.IsPaymentMethodActive(_paymentSettings)) throw new SmartException("Payment method is not active"); } else processPaymentRequest.PaymentMethodSystemName = ""; //recurring or standard shopping cart? bool isRecurringShoppingCart = false; if (!processPaymentRequest.IsRecurringPayment) { isRecurringShoppingCart = cart.IsRecurring(); if (isRecurringShoppingCart) { int recurringCycleLength = 0; RecurringProductCyclePeriod recurringCyclePeriod; int recurringTotalCycles = 0; string recurringCyclesError = cart.GetRecurringCycleInfo(_localizationService, out recurringCycleLength, out recurringCyclePeriod, out recurringTotalCycles); if (!string.IsNullOrEmpty(recurringCyclesError)) throw new SmartException(recurringCyclesError); processPaymentRequest.RecurringCycleLength = recurringCycleLength; processPaymentRequest.RecurringCyclePeriod = recurringCyclePeriod; processPaymentRequest.RecurringTotalCycles = recurringTotalCycles; } } else { isRecurringShoppingCart = true; } //process payment ProcessPaymentResult processPaymentResult = null; if (!skipPaymentWorkflow) { if (!processPaymentRequest.IsRecurringPayment) { if (isRecurringShoppingCart) { //recurring cart var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName); switch (recurringPaymentType) { case RecurringPaymentType.NotSupported: throw new SmartException("Recurring payments are not supported by selected payment method"); case RecurringPaymentType.Manual: case RecurringPaymentType.Automatic: processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest); break; default: throw new SmartException("Not supported recurring payment type"); } } else { //standard cart processPaymentResult = _paymentService.ProcessPayment(processPaymentRequest); } } else { if (isRecurringShoppingCart) { //Old credit card info processPaymentRequest.CreditCardType = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardType) : ""; processPaymentRequest.CreditCardName = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardName) : ""; processPaymentRequest.CreditCardNumber = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardNumber) : ""; //MaskedCreditCardNumber processPaymentRequest.CreditCardCvv2 = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardCvv2) : ""; try { processPaymentRequest.CreditCardExpireMonth = initialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(initialOrder.CardExpirationMonth)) : 0; processPaymentRequest.CreditCardExpireYear = initialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(initialOrder.CardExpirationYear)) : 0; } catch {} var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName); switch (recurringPaymentType) { case RecurringPaymentType.NotSupported: throw new SmartException("Recurring payments are not supported by selected payment method"); case RecurringPaymentType.Manual: processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest); break; case RecurringPaymentType.Automatic: //payment is processed on payment gateway site processPaymentResult = new ProcessPaymentResult(); break; default: throw new SmartException("Not supported recurring payment type"); } } else { throw new SmartException("No recurring products"); } } } else { //payment is not required if (processPaymentResult == null) processPaymentResult = new ProcessPaymentResult(); processPaymentResult.NewPaymentStatus = PaymentStatus.Paid; } if (processPaymentResult == null) throw new SmartException("processPaymentResult is not available"); #endregion if (processPaymentResult.Success) { //save order in data storage //uncomment this line to support transactions //using (var scope = new System.Transactions.TransactionScope()) { #region Save order details var shippingStatus = ShippingStatus.NotYetShipped; if (!shoppingCartRequiresShipping) shippingStatus = ShippingStatus.ShippingNotRequired; var order = new Order() { StoreId = processPaymentRequest.StoreId, OrderGuid = processPaymentRequest.OrderGuid, CustomerId = customer.Id, CustomerLanguageId = customerLanguage.Id, CustomerTaxDisplayType = customerTaxDisplayType, CustomerIp = _webHelper.GetCurrentIpAddress(), OrderSubtotalInclTax = orderSubTotalInclTax, OrderSubtotalExclTax = orderSubTotalExclTax, OrderSubTotalDiscountInclTax = orderSubTotalDiscountInclTax, OrderSubTotalDiscountExclTax = orderSubTotalDiscountExclTax, OrderShippingInclTax = orderShippingTotalInclTax.Value, OrderShippingExclTax = orderShippingTotalExclTax.Value, PaymentMethodAdditionalFeeInclTax = paymentAdditionalFeeInclTax, PaymentMethodAdditionalFeeExclTax = paymentAdditionalFeeExclTax, TaxRates = taxRates, OrderTax = orderTaxTotal, OrderTotal = orderTotal.Value, RefundedAmount = decimal.Zero, OrderDiscount = orderDiscountAmount, CheckoutAttributeDescription = checkoutAttributeDescription, CheckoutAttributesXml = checkoutAttributesXml, CustomerCurrencyCode = customerCurrencyCode, CurrencyRate = customerCurrencyRate, AffiliateId = affiliateId, OrderStatus = OrderStatus.Pending, AllowStoringCreditCardNumber = processPaymentResult.AllowStoringCreditCardNumber, CardType = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardType) : string.Empty, CardName = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardName) : string.Empty, CardNumber = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardNumber) : string.Empty, MaskedCreditCardNumber = _encryptionService.EncryptText(_paymentService.GetMaskedCreditCardNumber(processPaymentRequest.CreditCardNumber)), CardCvv2 = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardCvv2) : string.Empty, CardExpirationMonth = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireMonth.ToString()) : string.Empty, CardExpirationYear = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireYear.ToString()) : string.Empty, AllowStoringDirectDebit = processPaymentResult.AllowStoringDirectDebit, DirectDebitAccountHolder = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitAccountHolder) : string.Empty, DirectDebitAccountNumber = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitAccountNumber) : string.Empty, DirectDebitBankCode = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitBankCode) : string.Empty, DirectDebitBankName = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitBankName) : string.Empty, DirectDebitBIC = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitBic) : string.Empty, DirectDebitCountry = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitCountry) : string.Empty, DirectDebitIban = processPaymentResult.AllowStoringDirectDebit ? _encryptionService.EncryptText(processPaymentRequest.DirectDebitIban) : string.Empty, PaymentMethodSystemName = processPaymentRequest.PaymentMethodSystemName, AuthorizationTransactionId = processPaymentResult.AuthorizationTransactionId, AuthorizationTransactionCode = processPaymentResult.AuthorizationTransactionCode, AuthorizationTransactionResult = processPaymentResult.AuthorizationTransactionResult, CaptureTransactionId = processPaymentResult.CaptureTransactionId, CaptureTransactionResult = processPaymentResult.CaptureTransactionResult, SubscriptionTransactionId = processPaymentResult.SubscriptionTransactionId, PurchaseOrderNumber = processPaymentRequest.PurchaseOrderNumber, PaymentStatus = processPaymentResult.NewPaymentStatus, PaidDateUtc = null, BillingAddress = billingAddress, ShippingAddress = shippingAddress, ShippingStatus = shippingStatus, ShippingMethod = shippingMethodName, ShippingRateComputationMethodSystemName = shippingRateComputationMethodSystemName, VatNumber = vatNumber, CreatedOnUtc = utcNow, UpdatedOnUtc = utcNow, CustomerOrderComment = extraData.ContainsKey("CustomerComment") ? extraData["CustomerComment"] : "" }; _orderService.InsertOrder(order); result.PlacedOrder = order; if (!processPaymentRequest.IsRecurringPayment) { //move shopping cart items to order products foreach (var sc in cart) { //prices decimal taxRate = decimal.Zero; decimal scUnitPrice = _priceCalculationService.GetUnitPrice(sc, true); decimal scSubTotal = _priceCalculationService.GetSubTotal(sc, true); decimal scUnitPriceInclTax = _taxService.GetProductPrice(sc.Item.Product, scUnitPrice, true, customer, out taxRate); decimal scUnitPriceExclTax = _taxService.GetProductPrice(sc.Item.Product, scUnitPrice, false, customer, out taxRate); decimal scSubTotalInclTax = _taxService.GetProductPrice(sc.Item.Product, scSubTotal, true, customer, out taxRate); decimal scSubTotalExclTax = _taxService.GetProductPrice(sc.Item.Product, scSubTotal, false, customer, out taxRate); //discounts Discount scDiscount = null; decimal discountAmount = _priceCalculationService.GetDiscountAmount(sc, out scDiscount); decimal discountAmountInclTax = _taxService.GetProductPrice(sc.Item.Product, discountAmount, true, customer, out taxRate); decimal discountAmountExclTax = _taxService.GetProductPrice(sc.Item.Product, discountAmount, false, customer, out taxRate); if (scDiscount != null && !appliedDiscounts.ContainsDiscount(scDiscount)) appliedDiscounts.Add(scDiscount); //attributes string attributeDescription = _productAttributeFormatter.FormatAttributes(sc.Item.Product, sc.Item.AttributesXml, customer); var itemWeight = _shippingService.GetShoppingCartItemWeight(sc); //save order item var orderItem = new OrderItem() { OrderItemGuid = Guid.NewGuid(), Order = order, ProductId = sc.Item.ProductId, UnitPriceInclTax = scUnitPriceInclTax, UnitPriceExclTax = scUnitPriceExclTax, PriceInclTax = scSubTotalInclTax, PriceExclTax = scSubTotalExclTax, AttributeDescription = attributeDescription, AttributesXml = sc.Item.AttributesXml, Quantity = sc.Item.Quantity, DiscountAmountInclTax = discountAmountInclTax, DiscountAmountExclTax = discountAmountExclTax, DownloadCount = 0, IsDownloadActivated = false, LicenseDownloadId = 0, ItemWeight = itemWeight, ProductCost = _priceCalculationService.GetProductCost(sc.Item.Product, sc.Item.AttributesXml) }; if (sc.Item.Product.ProductType == ProductType.BundledProduct && sc.ChildItems != null) { var listBundleData = new List<ProductBundleItemOrderData>(); foreach (var childItem in sc.ChildItems) { decimal bundleItemSubTotal = _taxService.GetProductPrice(childItem.Item.Product, _priceCalculationService.GetSubTotal(childItem, true), out taxRate); string attributesInfo = _productAttributeFormatter.FormatAttributes(childItem.Item.Product, childItem.Item.AttributesXml, order.Customer, renderPrices: false, allowHyperlinks: false); childItem.BundleItemData.ToOrderData(listBundleData, bundleItemSubTotal, childItem.Item.AttributesXml, attributesInfo); } orderItem.SetBundleData(listBundleData); } order.OrderItems.Add(orderItem); _orderService.UpdateOrder(order); //gift cards if (sc.Item.Product.IsGiftCard) { string giftCardRecipientName, giftCardRecipientEmail, giftCardSenderName, giftCardSenderEmail, giftCardMessage; _productAttributeParser.GetGiftCardAttribute(sc.Item.AttributesXml, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); for (int i = 0; i < sc.Item.Quantity; i++) { var gc = new GiftCard() { GiftCardType = sc.Item.Product.GiftCardType, PurchasedWithOrderItem = orderItem, Amount = scUnitPriceExclTax, IsGiftCardActivated = false, GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(), RecipientName = giftCardRecipientName, RecipientEmail = giftCardRecipientEmail, SenderName = giftCardSenderName, SenderEmail = giftCardSenderEmail, Message = giftCardMessage, IsRecipientNotified = false, CreatedOnUtc = utcNow }; _giftCardService.InsertGiftCard(gc); } } //inventory _productService.AdjustInventory(sc, true); } //clear shopping cart cart.ToList().ForEach(sci => _shoppingCartService.DeleteShoppingCartItem(sci.Item, false)); } else { //recurring payment var initialOrderItems = initialOrder.OrderItems; foreach (var orderItem in initialOrderItems) { //save item var newOrderItem = new OrderItem() { OrderItemGuid = Guid.NewGuid(), Order = order, ProductId = orderItem.ProductId, UnitPriceInclTax = orderItem.UnitPriceInclTax, UnitPriceExclTax = orderItem.UnitPriceExclTax, PriceInclTax = orderItem.PriceInclTax, PriceExclTax = orderItem.PriceExclTax, AttributeDescription = orderItem.AttributeDescription, AttributesXml = orderItem.AttributesXml, Quantity = orderItem.Quantity, DiscountAmountInclTax = orderItem.DiscountAmountInclTax, DiscountAmountExclTax = orderItem.DiscountAmountExclTax, DownloadCount = 0, IsDownloadActivated = false, LicenseDownloadId = 0, ItemWeight = orderItem.ItemWeight, BundleData = orderItem.BundleData, ProductCost = orderItem.ProductCost }; order.OrderItems.Add(newOrderItem); _orderService.UpdateOrder(order); //gift cards if (orderItem.Product.IsGiftCard) { string giftCardRecipientName, giftCardRecipientEmail, giftCardSenderName, giftCardSenderEmail, giftCardMessage; _productAttributeParser.GetGiftCardAttribute(orderItem.AttributesXml, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); for (int i = 0; i < orderItem.Quantity; i++) { var gc = new GiftCard() { GiftCardType = orderItem.Product.GiftCardType, PurchasedWithOrderItem = newOrderItem, Amount = orderItem.UnitPriceExclTax, IsGiftCardActivated = false, GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(), RecipientName = giftCardRecipientName, RecipientEmail = giftCardRecipientEmail, SenderName = giftCardSenderName, SenderEmail = giftCardSenderEmail, Message = giftCardMessage, IsRecipientNotified = false, CreatedOnUtc = utcNow }; _giftCardService.InsertGiftCard(gc); } } //inventory _productService.AdjustInventory(orderItem, true, orderItem.Quantity); } } //discount usage history if (!processPaymentRequest.IsRecurringPayment) { foreach (var discount in appliedDiscounts) { var duh = new DiscountUsageHistory() { Discount = discount, Order = order, CreatedOnUtc = utcNow }; _discountService.InsertDiscountUsageHistory(duh); } } //gift card usage history if (!processPaymentRequest.IsRecurringPayment && appliedGiftCards != null) { foreach (var agc in appliedGiftCards) { decimal amountUsed = agc.AmountCanBeUsed; var gcuh = new GiftCardUsageHistory() { GiftCard = agc.GiftCard, UsedWithOrder = order, UsedValue = amountUsed, CreatedOnUtc = utcNow }; agc.GiftCard.GiftCardUsageHistory.Add(gcuh); _giftCardService.UpdateGiftCard(agc.GiftCard); } } //reward points history if (redeemedRewardPointsAmount > decimal.Zero) { customer.AddRewardPointsHistoryEntry(-redeemedRewardPoints, string.Format(_localizationService.GetResource("RewardPoints.Message.RedeemedForOrder", order.CustomerLanguageId), order.GetOrderNumber()), order, redeemedRewardPointsAmount); _customerService.UpdateCustomer(customer); } //recurring orders if (!processPaymentRequest.IsRecurringPayment && isRecurringShoppingCart) { //create recurring payment (the first payment) var rp = new RecurringPayment() { CycleLength = processPaymentRequest.RecurringCycleLength, CyclePeriod = processPaymentRequest.RecurringCyclePeriod, TotalCycles = processPaymentRequest.RecurringTotalCycles, StartDateUtc = utcNow, IsActive = true, CreatedOnUtc = utcNow, InitialOrder = order, }; _orderService.InsertRecurringPayment(rp); var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName); switch (recurringPaymentType) { case RecurringPaymentType.NotSupported: { //not supported } break; case RecurringPaymentType.Manual: { //first payment var rph = new RecurringPaymentHistory() { RecurringPayment = rp, CreatedOnUtc = utcNow, OrderId = order.Id, }; rp.RecurringPaymentHistory.Add(rph); _orderService.UpdateRecurringPayment(rp); } break; case RecurringPaymentType.Automatic: { //will be created later (process is automated) } break; default: break; } } #endregion #region Notifications, notes and attributes //notes, messages order.OrderNotes.Add(new OrderNote() { Note = T("OrderPlaced"), DisplayToCustomer = false, CreatedOnUtc = utcNow }); _orderService.UpdateOrder(order); //send email notifications int orderPlacedStoreOwnerNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedStoreOwnerNotification(order, _localizationSettings.DefaultAdminLanguageId); if (orderPlacedStoreOwnerNotificationQueuedEmailId > 0) { order.OrderNotes.Add(new OrderNote() { Note = string.Format(T("MerchantEmailQueued"), orderPlacedStoreOwnerNotificationQueuedEmailId), DisplayToCustomer = false, CreatedOnUtc = utcNow }); _orderService.UpdateOrder(order); } int orderPlacedCustomerNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedCustomerNotification(order, order.CustomerLanguageId); if (orderPlacedCustomerNotificationQueuedEmailId > 0) { order.OrderNotes.Add(new OrderNote() { Note = string.Format(T("CustomerEmailQueued"), orderPlacedCustomerNotificationQueuedEmailId), DisplayToCustomer = false, CreatedOnUtc = utcNow }); _orderService.UpdateOrder(order); } //check order status CheckOrderStatus(order); //reset checkout data if (!processPaymentRequest.IsRecurringPayment) _customerService.ResetCheckoutData(customer, processPaymentRequest.StoreId, clearCouponCodes: true, clearCheckoutAttributes: true); // check for generic attributes to be inserted automatically foreach (var customProperty in processPaymentRequest.CustomProperties.Where(x => x.Key.HasValue() && x.Value.AutoCreateGenericAttribute)) { _genericAttributeService.SaveAttribute<object>(order, customProperty.Key, customProperty.Value.Value, order.StoreId); } //uncomment this line to support transactions //scope.Complete(); //raise event _eventPublisher.PublishOrderPlaced(order); if (!processPaymentRequest.IsRecurringPayment) { _customerActivityService.InsertActivity( "PublicStore.PlaceOrder", _localizationService.GetResource("ActivityLog.PublicStore.PlaceOrder"), order.GetOrderNumber()); } //raise event if (order.PaymentStatus == PaymentStatus.Paid) { _eventPublisher.PublishOrderPaid(order); } #endregion } } else { foreach (var paymentError in processPaymentResult.Errors) result.AddError(paymentError); } } catch (Exception exc) { _logger.Error(exc.Message, exc); result.AddError(exc.Message); } #region Process errors string error = ""; for (int i = 0; i < result.Errors.Count; i++) { error += string.Format("Error {0}: {1}", i + 1, result.Errors[i]); if (i != result.Errors.Count - 1) error += ". "; } if (!String.IsNullOrEmpty(error)) { //log it string logError = string.Format("Error while placing order. {0}", error); _logger.Error(logError); } #endregion return result; }
/// <summary> /// Pre process payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Pre process payment result</returns> public virtual PreProcessPaymentResult PreProcessPayment(ProcessPaymentRequest processPaymentRequest) { var result = new PreProcessPaymentResult(); return(result); }
public ActionResult ConfirmOrder(FormCollection form) { //validation var cart = _workContext.CurrentCustomer.GetCartItems(ShoppingCartType.ShoppingCart, _storeContext.CurrentStore.Id); if (cart.Count == 0) return RedirectToRoute("ShoppingCart"); if ((_workContext.CurrentCustomer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed)) return new HttpUnauthorizedResult(); //model var model = new CheckoutConfirmModel(); try { var processPaymentRequest = _httpContext.Session["OrderPaymentInfo"] as ProcessPaymentRequest; if (processPaymentRequest == null) { //Check whether payment workflow is required if (IsPaymentWorkflowRequired(cart)) return RedirectToAction("PaymentMethod"); processPaymentRequest = new ProcessPaymentRequest(); } //prevent 2 orders being placed within an X seconds time frame if (!IsMinimumOrderPlacementIntervalValid(_workContext.CurrentCustomer)) throw new Exception(_localizationService.GetResource("Checkout.MinOrderPlacementInterval")); //place order processPaymentRequest.StoreId = _storeContext.CurrentStore.Id; processPaymentRequest.CustomerId = _workContext.CurrentCustomer.Id; processPaymentRequest.PaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute<string>( SystemCustomerAttributeNames.SelectedPaymentMethod, _genericAttributeService, _storeContext.CurrentStore.Id); var placeOrderExtraData = new Dictionary<string, string>(); placeOrderExtraData["CustomerComment"] = form["customercommenthidden"]; var placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest, placeOrderExtraData); // _httpContext.Session["Cart"] = processPaymentRequest; _httpContext.Session["PlaceOrderId"] = placeOrderResult.PlacedOrder.Id; _httpContext.Session["Total"] = placeOrderResult.PlacedOrder.OrderTotal; if (placeOrderResult.Success) { var postProcessPaymentRequest = new PostProcessPaymentRequest { Order = placeOrderResult.PlacedOrder }; _paymentService.PostProcessPayment(postProcessPaymentRequest); _httpContext.Session["PaymentData"] = null; _httpContext.Session["OrderPaymentInfo"] = null; _httpContext.RemoveCheckoutState(); if (postProcessPaymentRequest.RedirectUrl.HasValue()) { return Redirect(postProcessPaymentRequest.RedirectUrl); } return RedirectToAction("Completed"); } else { model.Warnings.AddRange(placeOrderResult.Errors); } } catch (Exception exc) { Logger.Warning(exc.Message, exc); model.Warnings.Add(exc.Message); } return View(model); }
/// <summary> /// Process recurring payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public virtual ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest) { var result = new ProcessPaymentResult(); result.AddError(T("Common.Payment.NoRecurringPaymentSupport")); return result; }
/// <summary> /// Process next recurring psayment /// </summary> /// <param name="recurringPayment">Recurring payment</param> public virtual void ProcessNextRecurringPayment(RecurringPayment recurringPayment) { if (recurringPayment == null) throw new ArgumentNullException("recurringPayment"); try { if (!recurringPayment.IsActive) throw new SmartException("Recurring payment is not active"); var initialOrder = recurringPayment.InitialOrder; if (initialOrder == null) throw new SmartException("Initial order could not be loaded"); var customer = initialOrder.Customer; if (customer == null) throw new SmartException("Customer could not be loaded"); var nextPaymentDate = recurringPayment.NextPaymentDate; if (!nextPaymentDate.HasValue) throw new SmartException("Next payment date could not be calculated"); //payment info var paymentInfo = new ProcessPaymentRequest() { StoreId = initialOrder.StoreId, CustomerId = customer.Id, OrderGuid = Guid.NewGuid(), IsRecurringPayment = true, InitialOrderId = initialOrder.Id, RecurringCycleLength = recurringPayment.CycleLength, RecurringCyclePeriod = recurringPayment.CyclePeriod, RecurringTotalCycles = recurringPayment.TotalCycles, }; //place a new order var result = this.PlaceOrder(paymentInfo, new Dictionary<string, string>()); if (result.Success) { if (result.PlacedOrder == null) throw new SmartException("Placed order could not be loaded"); var rph = new RecurringPaymentHistory() { RecurringPayment = recurringPayment, CreatedOnUtc = DateTime.UtcNow, OrderId = result.PlacedOrder.Id, }; recurringPayment.RecurringPaymentHistory.Add(rph); _orderService.UpdateRecurringPayment(recurringPayment); } else { string error = ""; for (int i = 0; i < result.Errors.Count; i++) { error += string.Format("Error {0}: {1}", i, result.Errors[i]); if (i != result.Errors.Count - 1) error += ". "; } throw new SmartException(error); } } catch (Exception exc) { _logger.Error(string.Format("Error while processing recurring order. {0}", exc.Message), exc); throw; } }
/// <summary> /// Pre process payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Pre process payment result</returns> public virtual PreProcessPaymentResult PreProcessPayment(ProcessPaymentRequest processPaymentRequest) { var result = new PreProcessPaymentResult(); return result; }
/// <summary> /// Pre process a payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Pre process payment result</returns> public virtual PreProcessPaymentResult PreProcessPayment(ProcessPaymentRequest processPaymentRequest) { if (processPaymentRequest.OrderTotal == decimal.Zero) { var result = new PreProcessPaymentResult(); return result; } else { var paymentMethod = LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName); if (paymentMethod == null) throw new SmartException("Payment method couldn't be loaded"); return paymentMethod.Value.PreProcessPayment(processPaymentRequest); } }
public PreProcessPaymentResult PreProcessPayment(ProcessPaymentRequest request) { // fulfill the Amazon checkout var result = new PreProcessPaymentResult(); try { var orderGuid = request.OrderGuid.ToString(); var store = _storeService.GetStoreById(request.StoreId); var customer = _customerService.GetCustomerById(request.CustomerId); var currency = _services.WorkContext.WorkingCurrency; var settings = _services.Settings.LoadSetting<AmazonPaySettings>(store.Id); var state = _httpContext.GetAmazonPayState(_services.Localization); var client = new AmazonPayClient(settings); if (!IsActive(store.Id, true)) { //_httpContext.ResetCheckoutState(); result.AddError(T("Plugins.Payments.AmazonPay.PaymentMethodNotActive", store.Name)); return result; } var preConfirmDetails = _api.SetOrderReferenceDetails(client, state.OrderReferenceId, request.OrderTotal, currency.CurrencyCode, orderGuid, store.Name); _api.GetConstraints(preConfirmDetails, result.Errors); if (!result.Success) return result; _api.ConfirmOrderReference(client, state.OrderReferenceId); // address and payment cannot be changed if order is in open state, amazon widgets then might show an error. //state.IsOrderConfirmed = true; var cart = customer.GetCartItems(ShoppingCartType.ShoppingCart, store.Id); var isShippable = cart.RequiresShipping(); // note: billing address is only available after authorization is in a non-pending and non-declined state. var details = _api.GetOrderReferenceDetails(client, state.OrderReferenceId); _api.FindAndApplyAddress(details, customer, isShippable, false); if (details.IsSetBuyer() && details.Buyer.IsSetEmail() && settings.CanSaveEmailAndPhone(customer.Email)) { customer.Email = details.Buyer.Email; } _customerService.UpdateCustomer(customer); if (details.IsSetBuyer() && details.Buyer.IsSetPhone() && settings.CanSaveEmailAndPhone(customer.GetAttribute<string>(SystemCustomerAttributeNames.Phone, store.Id))) { _genericAttributeService.SaveAttribute<string>(customer, SystemCustomerAttributeNames.Phone, details.Buyer.Phone); } } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc, errors: result.Errors); } catch (Exception exc) { LogError(exc, errors: result.Errors); } return result; }
/// <summary> /// Process recurring payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public virtual ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest) { if (processPaymentRequest.OrderTotal == decimal.Zero) { var result = new ProcessPaymentResult() { NewPaymentStatus = PaymentStatus.Paid }; return result; } else { var paymentMethod = LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName); if (paymentMethod == null) throw new SmartException("Payment method couldn't be loaded"); try { return paymentMethod.Value.ProcessRecurringPayment(processPaymentRequest); } catch (NotSupportedException) { var result = new ProcessPaymentResult(); result.AddError(_localizationService.GetResource("Common.Payment.NoRecurringPaymentSupport")); return result; } catch { throw; } } }
/// <summary> /// Process a payment /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public override ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest) { var result = new ProcessPaymentResult(); result.NewPaymentStatus = PaymentStatus.Pending; // codehint: sm-add if (_paypalStandardPaymentSettings.BusinessEmail.IsNullOrEmpty() || _paypalStandardPaymentSettings.PdtToken.IsNullOrEmpty()) { result.AddError(_localizationService.GetResource("Plugins.Payments.PayPalStandard.InvalidCredentials")); } return result; }