/// <summary> /// Load active payment methods /// </summary> /// <param name="customer">Filter payment methods by customer and apply payment method restrictions; null to load all records</param> /// <param name="cart">Filter payment methods by cart amount; null to load all records</param> /// <param name="storeId">Filter payment methods by store identifier; pass 0 to load all records</param> /// <param name="types">Filter payment methods by payment method types</param> /// <param name="provideFallbackMethod">Provide a fallback payment method if none is active</param> /// <returns>Payment methods</returns> public virtual IEnumerable<Provider<IPaymentMethod>> LoadActivePaymentMethods( Customer customer = null, IList<OrganizedShoppingCartItem> cart = null, int storeId = 0, PaymentMethodType[] types = null, bool provideFallbackMethod = true) { IList<IPaymentMethodFilter> allFilters = null; IEnumerable<Provider<IPaymentMethod>> allProviders = null; var filterRequest = new PaymentFilterRequest { Cart = cart, StoreId = storeId, Customer = customer }; if (types != null && types.Any()) allProviders = LoadAllPaymentMethods(storeId).Where(x => types.Contains(x.Value.PaymentMethodType)); else allProviders = LoadAllPaymentMethods(storeId); var activeProviders = allProviders .Where(p => { if (!p.Value.IsActive || !_paymentSettings.ActivePaymentMethodSystemNames.Contains(p.Metadata.SystemName, StringComparer.InvariantCultureIgnoreCase)) return false; // payment method filtering if (allFilters == null) allFilters = GetAllPaymentMethodFilters(); filterRequest.PaymentMethod = p; if (allFilters.Any(x => x.IsExcluded(filterRequest))) return false; return true; }); if (!activeProviders.Any() && provideFallbackMethod) { var fallbackMethod = allProviders.FirstOrDefault(x => x.IsPaymentMethodActive(_paymentSettings)); if (fallbackMethod == null) fallbackMethod = allProviders.FirstOrDefault(); if (fallbackMethod != null) { return new Provider<IPaymentMethod>[] { fallbackMethod }; } else { if (DataSettings.DatabaseIsInstalled()) throw new SmartException(T("Payment.OneActiveMethodProviderRequired")); } } return activeProviders; }
/// <summary> /// Load active payment methods /// </summary> /// <param name="customer">Filter payment methods by customer and apply payment method restrictions; null to load all records</param> /// <param name="cart">Filter payment methods by cart amount; null to load all records</param> /// <param name="storeId">Filter payment methods by store identifier; pass 0 to load all records</param> /// <param name="types">Filter payment methods by payment method types</param> /// <param name="provideFallbackMethod">Provide a fallback payment method if none is active</param> /// <returns>Payment methods</returns> public virtual IEnumerable<Provider<IPaymentMethod>> LoadActivePaymentMethods( Customer customer = null, IList<OrganizedShoppingCartItem> cart = null, int storeId = 0, PaymentMethodType[] types = null, bool provideFallbackMethod = true) { List<int> customerRoleIds = null; int? selectedShippingMethodId = null; decimal? orderSubTotal = null; decimal? orderTotal = null; IList<PaymentMethod> allMethods = null; IEnumerable<Provider<IPaymentMethod>> allProviders = null; if (types != null && types.Any()) allProviders = LoadAllPaymentMethods(storeId).Where(x => types.Contains(x.Value.PaymentMethodType)); else allProviders = LoadAllPaymentMethods(storeId); var activeProviders = allProviders .Where(p => { if (!p.Value.IsActive || !_paymentSettings.ActivePaymentMethodSystemNames.Contains(p.Metadata.SystemName, StringComparer.InvariantCultureIgnoreCase)) return false; if (customer != null) { if (allMethods == null) allMethods = GetAllPaymentMethods(); var method = allMethods.FirstOrDefault(x => x.PaymentMethodSystemName.IsCaseInsensitiveEqual(p.Metadata.SystemName)); if (method != null) { // method restricted by customer role id? var excludedRoleIds = method.ExcludedCustomerRoleIds.ToIntArray(); if (excludedRoleIds.Any()) { if (customerRoleIds == null) customerRoleIds = customer.CustomerRoles.Where(r => r.Active).Select(r => r.Id).ToList(); if (customerRoleIds != null && !customerRoleIds.Except(excludedRoleIds).Any()) return false; } // method restricted by selected shipping method? var excludedShippingMethodIds = method.ExcludedShippingMethodIds.ToIntArray(); if (excludedShippingMethodIds.Any()) { if (!selectedShippingMethodId.HasValue) { var selectedShipping = customer.GetAttribute<ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, storeId); selectedShippingMethodId = (selectedShipping == null ? 0 : selectedShipping.ShippingMethodId); } if ((selectedShippingMethodId ?? 0) != 0 && excludedShippingMethodIds.Contains(selectedShippingMethodId.Value)) return false; } // method restricted by country of selected billing or shipping address? var excludedCountryIds = method.ExcludedCountryIds.ToIntArray(); if (excludedCountryIds.Any()) { int countryId = 0; if (method.CountryExclusionContext == CountryRestrictionContextType.ShippingAddress) countryId = (customer.ShippingAddress != null ? (customer.ShippingAddress.CountryId ?? 0) : 0); else countryId = (customer.BillingAddress != null ? (customer.BillingAddress.CountryId ?? 0) : 0); if (countryId != 0 && excludedCountryIds.Contains(countryId)) return false; } // method restricted by min\max order amount? if ((method.MinimumOrderAmount.HasValue || method.MaximumOrderAmount.HasValue) && cart != null) { decimal compareAmount = decimal.Zero; if (method.AmountRestrictionContext == AmountRestrictionContextType.SubtotalAmount) { if (!orderSubTotal.HasValue) { decimal orderSubTotalDiscountAmountBase = decimal.Zero; Discount orderSubTotalAppliedDiscount = null; decimal subTotalWithoutDiscountBase = decimal.Zero; decimal subTotalWithDiscountBase = decimal.Zero; _orderTotalCalculationService.GetShoppingCartSubTotal(cart, out orderSubTotalDiscountAmountBase, out orderSubTotalAppliedDiscount, out subTotalWithoutDiscountBase, out subTotalWithDiscountBase); orderSubTotal = _currencyService.ConvertFromPrimaryStoreCurrency(subTotalWithoutDiscountBase, _services.WorkContext.WorkingCurrency); } compareAmount = orderSubTotal.Value; } else if (method.AmountRestrictionContext == AmountRestrictionContextType.TotalAmount) { if (!orderTotal.HasValue) { orderTotal = _orderTotalCalculationService.GetShoppingCartTotal(cart) ?? decimal.Zero; orderTotal = _currencyService.ConvertFromPrimaryStoreCurrency(orderTotal.Value, _services.WorkContext.WorkingCurrency); } compareAmount = orderTotal.Value; } if (method.MinimumOrderAmount.HasValue && compareAmount < method.MinimumOrderAmount.Value) return false; if (method.MaximumOrderAmount.HasValue && compareAmount > method.MaximumOrderAmount.Value) return false; } } } return true; }); if (!activeProviders.Any() && provideFallbackMethod) { var fallbackMethod = allProviders.FirstOrDefault(x => x.IsPaymentMethodActive(_paymentSettings)); if (fallbackMethod == null) fallbackMethod = allProviders.FirstOrDefault(); if (fallbackMethod != null) { return new Provider<IPaymentMethod>[] { fallbackMethod }; } else { if (DataSettings.DatabaseIsInstalled()) throw Error.Application("At least one payment method provider is required to be active."); } } return activeProviders; }