/// <summary> /// Check WWW prefix at the beginning of the URL and properly redirect if necessary /// </summary> /// <param name="context">Authorization filter context</param> /// <param name="withWww">Whether URL must start with WWW</param> private void RedirectRequest(AuthorizationFilterContext context, bool withWww) { //get scheme depending on securing connection var urlScheme = $"{_webHelper.GetCurrentRequestProtocol()}{Uri.SchemeDelimiter}"; //compose start of URL with WWW var urlWith3W = $"{urlScheme}www."; //get requested URL var currentUrl = _webHelper.GetThisPageUrl(true); //whether requested URL starts with WWW var urlStartsWith3W = currentUrl.StartsWith(urlWith3W, StringComparison.OrdinalIgnoreCase); //page should have WWW prefix, so set 301 (permanent) redirection to URL with WWW if (withWww && !urlStartsWith3W) { context.Result = new RedirectResult(currentUrl.Replace(urlScheme, urlWith3W), true); } //page shouldn't have WWW prefix, so set 301 (permanent) redirection to URL without WWW if (!withWww && urlStartsWith3W) { context.Result = new RedirectResult(currentUrl.Replace(urlWith3W, urlScheme), true); } }
public virtual async Task <IActionResult> ActiveDiscussionsRss(int forumId = 0) { if (!_forumSettings.ForumsEnabled) { return(RedirectToRoute("Homepage")); } if (!_forumSettings.ActiveDiscussionsFeedEnabled) { return(RedirectToRoute("Boards")); } var topics = await _forumService.GetActiveTopicsAsync(forumId, 0, _forumSettings.ActiveDiscussionsFeedCount); var url = Url.RouteUrl("ActiveDiscussionsRSS", null, _webHelper.GetCurrentRequestProtocol()); var feedTitle = await _localizationService.GetResourceAsync("Forum.ActiveDiscussionsFeedTitle"); var feedDescription = await _localizationService.GetResourceAsync("Forum.ActiveDiscussionsFeedDescription"); var store = await _storeContext.GetCurrentStoreAsync(); var feed = new RssFeed( string.Format(feedTitle, await _localizationService.GetLocalizedAsync(store, x => x.Name)), feedDescription, new Uri(url), DateTime.UtcNow); var items = new List <RssItem>(); var viewsText = await _localizationService.GetResourceAsync("Forum.Views"); var repliesText = await _localizationService.GetResourceAsync("Forum.Replies"); foreach (var topic in topics) { var topicUrl = Url.RouteUrl("TopicSlug", new { id = topic.Id, slug = await _forumService.GetTopicSeNameAsync(topic) }, _webHelper.GetCurrentRequestProtocol()); var content = $"{repliesText}: {(topic.NumPosts > 0 ? topic.NumPosts - 1 : 0)}, {viewsText}: {topic.Views}"; items.Add(new RssItem(topic.Subject, content, new Uri(topicUrl), $"urn:store:{store.Id}:activeDiscussions:topic:{topic.Id}", topic.LastPostTime ?? topic.UpdatedOnUtc)); } feed.Items = items; return(new RssActionResult(feed, _webHelper.GetThisPageUrl(false))); }
public virtual async Task <IActionResult> ListRss(int languageId) { var feed = new RssFeed( $"{await _localizationService.GetLocalizedAsync(await _storeContext.GetCurrentStoreAsync(), x => x.Name)}: News", "News", new Uri(_webHelper.GetStoreLocation()), DateTime.UtcNow); if (!_newsSettings.Enabled) { return(new RssActionResult(feed, _webHelper.GetThisPageUrl(false))); } var items = new List <RssItem>(); var newsItems = await _newsService.GetAllNewsAsync(languageId, (await _storeContext.GetCurrentStoreAsync()).Id); foreach (var n in newsItems) { var newsUrl = Url.RouteUrl("NewsItem", new { SeName = await _urlRecordService.GetSeNameAsync(n, n.LanguageId, ensureTwoPublishedLanguages: false) }, _webHelper.GetCurrentRequestProtocol()); items.Add(new RssItem(n.Title, n.Short, new Uri(newsUrl), $"urn:store:{(await _storeContext.GetCurrentStoreAsync()).Id}:news:blog:{n.Id}", n.CreatedOnUtc)); } feed.Items = items; return(new RssActionResult(feed, _webHelper.GetThisPageUrl(false))); }
/// <summary> /// Post process payment (used by payment gateways that require redirecting to a third-party URL) /// </summary> /// <param name="postProcessPaymentRequest">Payment info required for an order processing</param> /// <returns>The <see cref="Task"/></returns> public async Task PostProcessPaymentAsync(PostProcessPaymentRequest postProcessPaymentRequest) { if (postProcessPaymentRequest is null) { throw new ArgumentNullException(nameof(postProcessPaymentRequest)); } var order = postProcessPaymentRequest.Order; var result = await _openPayService.PlaceOrderAsync(order); if (!string.IsNullOrEmpty(result.HandoverUrl)) { _httpContextAccessor.HttpContext.Response.Redirect(result.HandoverUrl); } else { await _logger.ErrorAsync($"{Defaults.SystemName}: {string.Join(Environment.NewLine, result.Errors)}"); var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext); var failUrl = urlHelper.RouteUrl(Defaults.OrderDetailsRouteName, new { orderId = order.Id }, _webHelper.GetCurrentRequestProtocol()); _notificationService.ErrorNotification( await _localizationService.GetResourceAsync("Plugins.Payments.OpenPay.FailedOrderCreation")); _httpContextAccessor.HttpContext.Response.Redirect(failUrl); } }
/// <summary> /// Get URL for rule configuration /// </summary> /// <param name="discountId">Discount identifier</param> /// <param name="discountRequirementId">Discount requirement identifier (if editing)</param> /// <returns>URL</returns> public string GetConfigurationUrl(int discountId, int?discountRequirementId) { var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext); return(urlHelper.Action("Configure", "DiscountRulesHasAllProducts", new { discountId = discountId, discountRequirementId = discountRequirementId }, _webHelper.GetCurrentRequestProtocol())); }
/// <summary> /// Handle shopping cart changed event /// </summary> /// <param name="cartItem">Shopping cart item</param> /// <returns>A task that represents the asynchronous operation</returns> public async Task HandleShoppingCartChangedEventAsync(ShoppingCartItem cartItem) { //whether marketing automation is enabled if (!_sendinblueSettings.UseMarketingAutomation) { return; } var customer = await _customerService.GetCustomerByIdAsync(cartItem.CustomerId); try { //create API client var client = CreateMarketingAutomationClient(); //first, try to identify current customer await client.IdentifyAsync(new Identify(customer.Email)); //get shopping cart GUID var shoppingCartGuid = await _genericAttributeService .GetAttributeAsync <Guid?>(customer, SendinblueDefaults.ShoppingCartGuidAttribute); //create track event object var trackEvent = new TrackEvent(customer.Email, string.Empty); //get current customer's shopping cart var store = await _storeContext.GetCurrentStoreAsync(); var cart = await _shoppingCartService .GetShoppingCartAsync(customer, ShoppingCartType.ShoppingCart, store.Id); if (cart.Any()) { //get URL helper var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext); //get shopping cart amounts var(_, cartDiscount, _, cartSubtotal, _) = await _orderTotalCalculationService.GetShoppingCartSubTotalAsync(cart, await _workContext.GetTaxDisplayTypeAsync() == TaxDisplayType.IncludingTax); var cartTax = await _orderTotalCalculationService.GetTaxTotalAsync(cart, false); var cartShipping = await _orderTotalCalculationService.GetShoppingCartShippingTotalAsync(cart); var(cartTotal, _, _, _, _, _) = await _orderTotalCalculationService.GetShoppingCartTotalAsync(cart, false, false); //get products data by shopping cart items var itemsData = await cart.Where(item => item.ProductId != 0).SelectAwait(async item => { var product = await _productService.GetProductByIdAsync(item.ProductId); //try to get product attribute combination var combination = await _productAttributeParser.FindProductAttributeCombinationAsync(product, item.AttributesXml); //get default product picture var picture = await _pictureService.GetProductPictureAsync(product, item.AttributesXml); //get product SEO slug name var seName = await _urlRecordService.GetSeNameAsync(product); //create product data return(new { id = product.Id, name = product.Name, variant_id = combination?.Id ?? product.Id, variant_name = combination?.Sku ?? product.Name, sku = combination?.Sku ?? product.Sku, category = await(await _categoryService.GetProductCategoriesByProductIdAsync(item.ProductId)).AggregateAwaitAsync(",", async(all, pc) => { var res = (await _categoryService.GetCategoryByIdAsync(pc.CategoryId)).Name; res = all == "," ? res : all + ", " + res; return res; }), url = urlHelper.RouteUrl("Product", new { SeName = seName }, _webHelper.GetCurrentRequestProtocol()), image = (await _pictureService.GetPictureUrlAsync(picture)).Url, quantity = item.Quantity, price = (await _shoppingCartService.GetSubTotalAsync(item, true)).subTotal }); }).ToArrayAsync(); //prepare cart data var cartData = new { affiliation = store.Name, subtotal = cartSubtotal, shipping = cartShipping ?? decimal.Zero, total_before_tax = cartSubtotal + cartShipping ?? decimal.Zero, tax = cartTax, discount = cartDiscount, revenue = cartTotal ?? decimal.Zero, url = urlHelper.RouteUrl("ShoppingCart", null, _webHelper.GetCurrentRequestProtocol()), currency = (await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId))?.CurrencyCode, //gift_wrapping = string.Empty, //currently we can't get this value items = itemsData }; //if there is a single item in the cart, so the cart is just created if (cart.Count == 1) { shoppingCartGuid = Guid.NewGuid(); } else { //otherwise cart is updated shoppingCartGuid ??= Guid.NewGuid(); } trackEvent.EventName = SendinblueDefaults.CartUpdatedEventName; trackEvent.EventData = new { id = $"cart:{shoppingCartGuid}", data = cartData }; } else { //there are no items in the cart, so the cart is deleted shoppingCartGuid ??= Guid.NewGuid(); trackEvent.EventName = SendinblueDefaults.CartDeletedEventName; trackEvent.EventData = new { id = $"cart:{shoppingCartGuid}" }; } //track event await client.TrackEventAsync(trackEvent); //update GUID for the current customer's shopping cart await _genericAttributeService.SaveAttributeAsync(customer, SendinblueDefaults.ShoppingCartGuidAttribute, shoppingCartGuid); } catch (Exception exception) { //log full error await _logger.ErrorAsync($"Sendinblue Marketing Automation error: {exception.Message}.", exception, customer); } }
/// <summary> /// Places order and returns the handover URL to redirect user when order is placed successful; otherwise returns null with the errors as <see cref="IList{string}"/> /// </summary> /// <param name="order">The order</param> /// <returns>The <see cref="Task"/> containing the handover URL to redirect user when order is placed successful; otherwise returns null with the errors as <see cref="IList{string}"/></returns> public virtual async Task <(string HandoverUrl, IList <string> Errors)> PlaceOrderAsync(Order order) { if (order is null) { throw new ArgumentNullException(nameof(order)); } var validationResult = await ValidateAsync(); if (!validationResult.IsValid) { return(null, validationResult.Errors); } var errors = new List <string>(); var shippingAddressId = order.PickupInStore ? order.PickupAddressId : order.ShippingAddressId; if (!shippingAddressId.HasValue) { errors.Add($"Cannot process payment for order {order.CustomOrderNumber}. The shipping address not found."); return(null, errors); } var shippingAddress = await _addressService.GetAddressByIdAsync(shippingAddressId.Value); if (shippingAddress == null) { errors.Add($"Cannot process payment for order {order.CustomOrderNumber}. The shipping address not found."); return(null, errors); } if (!shippingAddress.StateProvinceId.HasValue) { errors.Add($"Cannot process payment for order {order.CustomOrderNumber}. The state not found."); return(null, errors); } var shippingState = await _stateProvinceService.GetStateProvinceByIdAsync(shippingAddress.StateProvinceId.Value); if (shippingState == null) { errors.Add($"Cannot process payment for order {order.CustomOrderNumber}. The state not found."); return(null, errors); } var deliveryAddress = new CustomerAddress { Line1 = shippingAddress.Address1, Line2 = shippingAddress.Address2, Suburb = shippingAddress.City ?? shippingAddress.County, PostCode = shippingAddress.ZipPostalCode, State = shippingState.Abbreviation }; var customer = await _customerService.GetCustomerByIdAsync(order.CustomerId); if (customer == null) { errors.Add($"Cannot process payment for order {order.CustomOrderNumber}. The customer not found."); return(null, errors); } var customerDetails = new PersonalDetails { Email = shippingAddress.Email ?? customer.Email, DeliveryAddress = deliveryAddress }; if (!string.IsNullOrWhiteSpace(shippingAddress.PhoneNumber)) { customerDetails.PhoneNumber = shippingAddress.PhoneNumber; } else if (_customerSettings.PhoneEnabled) { customerDetails.PhoneNumber = await _genericAttributeService .GetAttributeAsync <string>(customer, NopCustomerDefaults.PhoneAttribute); } if (!order.PickupInStore && !string.IsNullOrWhiteSpace(shippingAddress.FirstName)) { customerDetails.FirstName = shippingAddress.FirstName; } else { customerDetails.FirstName = _customerSettings.FirstNameEnabled ? await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.FirstNameAttribute) : _customerSettings.UsernamesEnabled ? customer.Username : customer.Email; } if (!order.PickupInStore && !string.IsNullOrWhiteSpace(shippingAddress.LastName)) { customerDetails.FamilyName = shippingAddress.LastName; } else { customerDetails.FamilyName = _customerSettings.LastNameEnabled ? await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.LastNameAttribute) : _customerSettings.UsernamesEnabled ? customer.Username : customer.Email; } // billing address not required var billingAddress = await _addressService.GetAddressByIdAsync(order.BillingAddressId); if (billingAddress != null) { var billingState = await _stateProvinceService.GetStateProvinceByIdAsync(billingAddress.StateProvinceId.Value); if (billingState != null) { customerDetails.ResidentialAddress = new CustomerAddress { Line1 = billingAddress.Address1, Line2 = billingAddress.Address2, Suburb = billingAddress.City ?? billingAddress.County, PostCode = billingAddress.ZipPostalCode, State = billingState.Abbreviation }; if (string.IsNullOrEmpty(customerDetails.PhoneNumber)) { customerDetails.PhoneNumber = billingAddress.PhoneNumber; } } } var currentRequestProtocol = _webHelper.GetCurrentRequestProtocol(); var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext); var callbackUrl = urlHelper.RouteUrl(Defaults.SuccessfulPaymentWebhookRouteName, null, currentRequestProtocol); var failUrl = urlHelper.RouteUrl(Defaults.OrderDetailsRouteName, new { orderId = order.Id }, currentRequestProtocol); var customerJourney = new CustomerJourney { Origin = "Online", Online = new OnlineJourneyDetails { CallbackUrl = callbackUrl, CancelUrl = failUrl, FailUrl = failUrl, CustomerDetails = customerDetails, PlanCreationType = "pending", DeliveryMethod = order.PickupInStore ? "Pickup" : "Delivery" } }; var createOrderRequest = new CreateOrderRequest { PurchasePrice = (int)(order.OrderTotal * 100), CustomerJourney = customerJourney, RetailerOrderNo = order.Id.ToString() }; var orderItems = await _orderService.GetOrderItemsAsync(order.Id); if (orderItems?.Any() == true) { var cartItems = new List <CartItem>(); foreach (var item in orderItems) { var product = await _productService.GetProductByIdAsync(item.ProductId); if (product == null) { errors.Add($"Cannot process payment for order {order.CustomOrderNumber}. Cannot get the product by id '{item.ProductId}'."); return(null, errors); } var productName = string.Empty; if (string.IsNullOrEmpty(item.AttributesXml)) { productName = product.Name; } else { var attributeInfo = await _productAttributeFormatter.FormatAttributesAsync(product, item.AttributesXml, customer, ", "); productName = $"{product.Name} ({attributeInfo})"; } var cartItem = new CartItem { Name = productName, Code = product.Id.ToString(), Quantity = item.Quantity.ToString(), UnitPrice = (int)(item.UnitPriceInclTax * 100), Charge = (int)(item.PriceInclTax * 100) }; cartItems.Add(cartItem); } createOrderRequest.CartItems = cartItems.ToArray(); } try { var openPayOrder = await _openPayApi.CreateOrderAsync(createOrderRequest); var formPost = openPayOrder?.NextAction?.FormPost; if (!string.IsNullOrEmpty(formPost?.FormPostUrl) && formPost?.FormFields?.Any() == true) { // add query directly to eliminate character escaping var redirectUrl = $"{formPost?.FormPostUrl}?{string.Join("&", formPost.FormFields.Select(field => $"{field.Name}={field.Value}"))}"; return(redirectUrl, errors); } errors.Add($"Cannot process payment for order {order.CustomOrderNumber}. Cannot get the handover URL to redirect user to OpenPay gateway."); } catch (ApiException ex) { errors.Add(ex.Message); } return(null, errors); }
/// <returns>A task that represents the asynchronous operation</returns> public virtual async Task <IActionResult> NewProductsRss() { var feed = new RssFeed( $"{await _localizationService.GetLocalizedAsync(await _storeContext.GetCurrentStoreAsync(), x => x.Name)}: New products", "Information about products", new Uri(_webHelper.GetStoreLocation()), DateTime.UtcNow); if (!_catalogSettings.NewProductsEnabled) { return(new RssActionResult(feed, _webHelper.GetThisPageUrl(false))); } var items = new List <RssItem>(); var storeId = (await _storeContext.GetCurrentStoreAsync()).Id; var products = await _productService.GetProductsMarkedAsNewAsync(storeId); foreach (var product in products) { var productUrl = Url.RouteUrl("Product", new { SeName = await _urlRecordService.GetSeNameAsync(product) }, _webHelper.GetCurrentRequestProtocol()); var productName = await _localizationService.GetLocalizedAsync(product, x => x.Name); var productDescription = await _localizationService.GetLocalizedAsync(product, x => x.ShortDescription); var item = new RssItem(productName, productDescription, new Uri(productUrl), $"urn:store:{(await _storeContext.GetCurrentStoreAsync()).Id}:newProducts:product:{product.Id}", product.CreatedOnUtc); items.Add(item); //uncomment below if you want to add RSS enclosure for pictures //var picture = _pictureService.GetPicturesByProductId(product.Id, 1).FirstOrDefault(); //if (picture != null) //{ // var imageUrl = _pictureService.GetPictureUrl(picture, _mediaSettings.ProductDetailsPictureSize); // item.ElementExtensions.Add(new XElement("enclosure", new XAttribute("type", "image/jpeg"), new XAttribute("url", imageUrl), new XAttribute("length", picture.PictureBinary.Length))); //} } feed.Items = items; return(new RssActionResult(feed, _webHelper.GetThisPageUrl(false))); }
public virtual async Task <IActionResult> ListRss(int languageId) { var feed = new RssFeed( $"{await _localizationService.GetLocalizedAsync(await _storeContext.GetCurrentStoreAsync(), x => x.Name)}: Blog", "Blog", new Uri(_webHelper.GetStoreLocation()), DateTime.UtcNow); if (!_blogSettings.Enabled) { return(new RssActionResult(feed, _webHelper.GetThisPageUrl(false))); } var items = new List <RssItem>(); var blogPosts = await _blogService.GetAllBlogPostsAsync((await _storeContext.GetCurrentStoreAsync()).Id, languageId); foreach (var blogPost in blogPosts) { var blogPostUrl = Url.RouteUrl("BlogPost", new { SeName = await _urlRecordService.GetSeNameAsync(blogPost, blogPost.LanguageId, ensureTwoPublishedLanguages: false) }, _webHelper.GetCurrentRequestProtocol()); items.Add(new RssItem(blogPost.Title, blogPost.Body, new Uri(blogPostUrl), $"urn:store:{(await _storeContext.GetCurrentStoreAsync()).Id}:blog:post:{blogPost.Id}", blogPost.CreatedOnUtc)); } feed.Items = items; return(new RssActionResult(feed, _webHelper.GetThisPageUrl(false))); }
public async Task <IActionResult> Configure(ConfigurationModel model) { if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManagePaymentMethods)) { return(AccessDeniedView()); } if (!ModelState.IsValid) { return(await Configure()); } //load settings for a chosen store scope var storeScope = await _storeContext.GetActiveStoreScopeConfigurationAsync(); var settings = await _settingService.LoadSettingAsync <PayPalSmartPaymentButtonsSettings>(storeScope); //first delete the unused webhook on a previous client, if changed if ((!model.ClientId?.Equals(settings.ClientId) ?? true) && !string.IsNullOrEmpty(settings.ClientId) && !string.IsNullOrEmpty(settings.SecretKey)) { await _serviceManager.DeleteWebhookAsync(settings); } //set new settings values settings.ClientId = model.ClientId; settings.SecretKey = model.SecretKey; settings.UseSandbox = model.UseSandbox; settings.PaymentType = (PaymentType)model.PaymentTypeId; settings.DisplayButtonsOnShoppingCart = model.DisplayButtonsOnShoppingCart; settings.DisplayButtonsOnProductDetails = model.DisplayButtonsOnProductDetails; settings.DisplayLogoInHeaderLinks = model.DisplayLogoInHeaderLinks; settings.LogoInHeaderLinks = model.LogoInHeaderLinks; settings.DisplayLogoInFooter = model.DisplayLogoInFooter; settings.LogoInFooter = model.LogoInFooter; //ensure that webhook created, display warning in case of fail if (!string.IsNullOrEmpty(settings.ClientId) && !string.IsNullOrEmpty(settings.SecretKey)) { var webhookUrl = Url.RouteUrl(Defaults.WebhookRouteName, null, _webHelper.GetCurrentRequestProtocol()); var(webhook, webhookError) = await _serviceManager.CreateWebHookAsync(settings, webhookUrl); settings.WebhookId = webhook?.Id; if (string.IsNullOrEmpty(settings.WebhookId)) { var url = Url.Action("List", "Log"); var warning = string.Format(await _localizationService.GetResourceAsync("Plugins.Payments.PayPalSmartPaymentButtons.WebhookWarning"), url); _notificationService.WarningNotification(warning, false); } } //save settings await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.WebhookId, true, storeScope, false); await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.ClientId, model.ClientId_OverrideForStore, storeScope, false); await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.SecretKey, model.SecretKey_OverrideForStore, storeScope, false); await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.UseSandbox, model.UseSandbox_OverrideForStore, storeScope, false); await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.PaymentType, model.PaymentTypeId_OverrideForStore, storeScope, false); await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.DisplayButtonsOnShoppingCart, model.DisplayButtonsOnShoppingCart_OverrideForStore, storeScope, false); await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.DisplayButtonsOnProductDetails, model.DisplayButtonsOnProductDetails_OverrideForStore, storeScope, false); await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.DisplayLogoInHeaderLinks, model.DisplayLogoInHeaderLinks_OverrideForStore, storeScope, false); await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.LogoInHeaderLinks, model.LogoInHeaderLinks_OverrideForStore, storeScope, false); await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.DisplayLogoInFooter, model.DisplayLogoInFooter_OverrideForStore, storeScope, false); await _settingService.SaveSettingOverridablePerStoreAsync(settings, setting => setting.LogoInFooter, model.LogoInFooter_OverrideForStore, storeScope, false); await _settingService.ClearCacheAsync(); //ensure credentials are valid if (!string.IsNullOrEmpty(settings.ClientId) && !string.IsNullOrEmpty(settings.SecretKey)) { var(_, errorMessage) = await _serviceManager.GetAccessTokenAsync(settings); if (!string.IsNullOrEmpty(errorMessage)) { var url = Url.Action("List", "Log"); var error = string.Format(await _localizationService.GetResourceAsync("Plugins.Payments.PayPalSmartPaymentButtons.Credentials.Invalid"), url); _notificationService.ErrorNotification(error, false); } else { _notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Plugins.Payments.PayPalSmartPaymentButtons.Credentials.Valid")); } } _notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Plugins.Saved")); return(await Configure()); }
/// <summary> /// Prepare topic model /// </summary> /// <param name="model">Topic model</param> /// <param name="topic">Topic</param> /// <param name="excludeProperties">Whether to exclude populating of some properties of model</param> /// <returns>Topic model</returns> public virtual async Task <TopicModel> PrepareTopicModelAsync(TopicModel model, Topic topic, bool excludeProperties = false) { Action <TopicLocalizedModel, int> localizedModelConfiguration = null; if (topic != null) { //fill in model values from the entity if (model == null) { model = topic.ToModel <TopicModel>(); model.SeName = await _urlRecordService.GetSeNameAsync(topic, 0, true, false); } model.Url = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext) .RouteUrl("Topic", new { SeName = await _urlRecordService.GetSeNameAsync(topic) }, _webHelper.GetCurrentRequestProtocol()); //define localized model configuration action localizedModelConfiguration = async(locale, languageId) => { locale.Title = await _localizationService.GetLocalizedAsync(topic, entity => entity.Title, languageId, false, false); locale.Body = await _localizationService.GetLocalizedAsync(topic, entity => entity.Body, languageId, false, false); locale.MetaKeywords = await _localizationService.GetLocalizedAsync(topic, entity => entity.MetaKeywords, languageId, false, false); locale.MetaDescription = await _localizationService.GetLocalizedAsync(topic, entity => entity.MetaDescription, languageId, false, false); locale.MetaTitle = await _localizationService.GetLocalizedAsync(topic, entity => entity.MetaTitle, languageId, false, false); locale.SeName = await _urlRecordService.GetSeNameAsync(topic, languageId, false, false); }; } //set default values for the new model if (topic == null) { model.DisplayOrder = 1; model.Published = true; } //prepare localized models if (!excludeProperties) { model.Locales = await _localizedModelFactory.PrepareLocalizedModelsAsync(localizedModelConfiguration); } //prepare available topic templates await _baseAdminModelFactory.PrepareTopicTemplatesAsync(model.AvailableTopicTemplates, false); //prepare model customer roles await _aclSupportedModelFactory.PrepareModelCustomerRolesAsync(model, topic, excludeProperties); //prepare model stores await _storeMappingSupportedModelFactory.PrepareModelStoresAsync(model, topic, excludeProperties); return(model); }
/// <summary> /// Post process payment (used by payment gateways that require redirecting to a third-party URL) /// </summary> /// <param name="postProcessPaymentRequest">Payment info required for an order processing</param> /// <returns>A task that represents the asynchronous operation</returns> public async Task PostProcessPaymentAsync(PostProcessPaymentRequest postProcessPaymentRequest) { if (postProcessPaymentRequest is null) { throw new ArgumentNullException(nameof(postProcessPaymentRequest)); } var storeCurrency = await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId) ?? throw new NopException("Primary store currency is not set"); var order = postProcessPaymentRequest.Order; var orderCustomValues = _paymentService.DeserializeCustomValues(order); var paymentChannelKey = await _localizationService.GetResourceAsync("Plugins.Payments.Yuansfer.PaymentChannel.Key"); if (!orderCustomValues.TryGetValue(paymentChannelKey, out var vendor)) { throw new NopException("The payment channel is not set"); } var customer = await _workContext.GetCurrentCustomerAsync(); var goods = new List <object>(); var orderItems = await _orderService.GetOrderItemsAsync(order.Id); foreach (var item in orderItems) { var product = await _productService.GetProductByIdAsync(item.ProductId) ?? throw new InvalidOperationException("Cannot get the product."); var productName = string.Empty; if (string.IsNullOrEmpty(item.AttributesXml)) { productName = product.Name; } else { var attributeInfo = await _productAttributeFormatter.FormatAttributesAsync(product, item.AttributesXml, customer, ", "); productName = $"{product.Name} ({attributeInfo})"; } goods.Add(new { goods_name = productName, quantity = item.Quantity.ToString() }); } var currentRequestProtocol = _webHelper.GetCurrentRequestProtocol(); var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext); var failUrl = urlHelper.RouteUrl(Defaults.OrderDetailsRouteName, new { orderId = order.Id }, currentRequestProtocol); var callbackUrl = urlHelper.RouteUrl(Defaults.CheckoutCompletedRouteName, new { orderId = order.Id }, currentRequestProtocol); var ipnUrl = urlHelper.RouteUrl(Defaults.SecurePayWebhookRouteName, null, currentRequestProtocol); var request = new SecurePayRequest { MerchantId = _yuansferPaymentSettings.MerchantId, StoreId = _yuansferPaymentSettings.StoreId, Vendor = vendor.ToString(), Terminal = "ONLINE", SettleCurrency = "USD", CallbackUrl = callbackUrl, IpnUrl = ipnUrl, GoodsInfo = JsonConvert.SerializeObject(goods), Reference = order.OrderGuid.ToString() }; void redirectToErrorPage(string message) { _notificationService.ErrorNotification(message); var failUrl = urlHelper.RouteUrl(Defaults.OrderDetailsRouteName, new { orderId = order.Id }, currentRequestProtocol); _actionContextAccessor.ActionContext.HttpContext.Response.Redirect(failUrl); }; var transactionAmount = decimal.Zero; var supportedVendorCurrencies = GetSupportedCurrenciesByVendor(request.Vendor); if (supportedVendorCurrencies.SupportedCurrencyCodes .Any(code => code.Equals(storeCurrency.CurrencyCode, StringComparison.InvariantCultureIgnoreCase))) { // primary store currency supported by vendor request.Currency = storeCurrency.CurrencyCode; transactionAmount = order.OrderTotal; } else { // primary store currency not supported by vendor, then convert transaction amount to vendor currency var targetCurrency = await _currencyService.GetCurrencyByCodeAsync(supportedVendorCurrencies.PrimaryCurrencyCode); if (targetCurrency == null) { throw new NopException($"Cannot convert order total to vendor currency. The currency by ISO code '{supportedVendorCurrencies.PrimaryCurrencyCode}' not found."); } request.Currency = targetCurrency.CurrencyCode; transactionAmount = await _currencyService.ConvertCurrencyAsync(order.OrderTotal, storeCurrency, targetCurrency); } // validate amount for some vendors if (request.Vendor == "kakaopay" && transactionAmount < 50) { redirectToErrorPage("Total amount must be greater or equal to 50!"); return; } else if (request.Vendor == "dana" && transactionAmount < 300) { redirectToErrorPage("Total amount must be greater or equal to 300!"); return; } request.Amount = transactionAmount.ToString(CultureInfo.InvariantCulture); var signingParams = new[]