using System; namespace IOL.VippsEcommerce.Models { /// /// Configuration fields for the vipps api and integration. /// public class VippsConfiguration { /// /// Url for the vipps api. This property is required. /// https://apitest.vipps.no /// https://api.vipps.no /// Corresponding environment variable name: VIPPS_API_URL /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_API_URL)] public string ApiUrl { get; set; } /// /// Client ID for the merchant (the "username"). This property is required. /// Corresponding environment variable name: VIPPS_CLIENT_ID /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_CLIENT_ID)] public string ClientId { get; set; } /// /// Client Secret for the merchant (the "password"). This property is required. /// Corresponding environment variable name: VIPPS_CLIENT_SECRET /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_CLIENT_SECRET)] public string ClientSecret { get; set; } /// /// Primary subscription key for the API product. /// The primary subscription key take precedence over the secondary subscription key. /// Either primary subscription key or secondary subscription key is required. /// Corresponding environment variable name: VIPPS_SUBSCRIPTION_KEY_PRIMARY /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SUBSCRIPTION_KEY_PRIMARY)] public string PrimarySubscriptionKey { get; set; } /// /// Secondary subscription key for the API product. /// The primary subscription key take precedence over the secondary subscription key. /// Either primary subscription key or secondary subscription key is required. /// Corresponding environment variable name: VIPPS_SUBSCRIPTION_KEY_SECONDARY /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SUBSCRIPTION_KEY_SECONDARY)] public string SecondarySubscriptionKey { get; set; } /// /// The Merchant Serial Number (MSN) is a unique id for the sale unit that this payment is made for. /// Corresponding environment variable name: VIPPS_MSN /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_MSN)] public string MerchantSerialNumber { get; set; } /// /// The name of the ecommerce solution. One word in lowercase letters is good. /// Corresponding environment variable name: VIPPS_SYSTEM_NAME /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SYSTEM_NAME)] public string SystemName { get; set; } /// /// The version number of the ecommerce solution. /// Corresponding environment variable name: VIPPS_SYSTEM_VERSION /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SYSTEM_VERSION)] public string SystemVersion { get; set; } /// /// The name of the ecommerce plugin (if applicable). One word in lowercase letters is good. /// Corresponding environment variable name: VIPPS_SYSTEM_PLUGIN_NAME /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SYSTEM_PLUGIN_NAME)] public string SystemPluginName { get; set; } /// /// The version number of the ecommerce plugin (if applicable). /// Corresponding environment variable name: VIPPS_SYSTEM_PLUGIN_VERSION /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SYSTEM_PLUGIN_VERSION)] public string SystemPluginVersion { get; set; } /// /// Optional path to a writable directory wherein a credential cache file can be placed. /// Corresponding environment variable name: VIPPS_CACHE_PATH /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_CACHE_PATH)] public string CacheDirectoryPath { get; set; } /// /// Optional key for AES encryption of the credential cache file. /// Corresponding environment variable name: VIPPS_CACHE_KEY /// [VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_CACHE_KEY)] public string CacheEncryptionKey { get; set; } /// /// Specify how to retrieve configuration and/or in what order. Defaults to VippsConfigurationMode.ONLY_OBJECT. /// public VippsConfigurationMode ConfigurationMode { get; set; } = VippsConfigurationMode.ONLY_OBJECT; /// /// Get value from configuration, either from Dependency injection or from the environment. /// /// Configuration key. /// A string containing the configuration value. public string GetValue(string key) { switch (ConfigurationMode) { case VippsConfigurationMode.ONLY_OBJECT: return GetValueFromObject(key); case VippsConfigurationMode.ONLY_ENVIRONMENT: return Environment.GetEnvironmentVariable(key); case VippsConfigurationMode.OBJECT_THEN_ENVIRONMENT: return GetValueFromObject(key) ?? Environment.GetEnvironmentVariable(key); case VippsConfigurationMode.ENVIRONMENT_THEN_OBJECT: return Environment.GetEnvironmentVariable(key) ?? GetValueFromObject(key); default: return default; } } /// /// Ensure that the configuration can be used to issue requests to the vipps api. /// Throws if a required value is null or whitespace. /// public void Verify() { if (GetValue(VippsConfigurationKeyNames.VIPPS_API_URL).IsNullOrWhiteSpace()) { throw new ArgumentNullException(VippsConfigurationKeyNames.VIPPS_API_URL, "VippsEcommerceService: VIPPS_API_URL is not provided in configuration."); } if (GetValue(VippsConfigurationKeyNames.VIPPS_CLIENT_ID).IsNullOrWhiteSpace()) { throw new ArgumentNullException(VippsConfigurationKeyNames.VIPPS_CLIENT_ID, "VippsEcommerceService: VIPPS_CLIENT_ID is not provided in configuration."); } if (GetValue(VippsConfigurationKeyNames.VIPPS_CLIENT_SECRET).IsNullOrWhiteSpace()) { throw new ArgumentNullException(VippsConfigurationKeyNames.VIPPS_CLIENT_SECRET, "VippsEcommerceService: VIPPS_CLIENT_SECRET is not provided in configuration."); } if (GetValue(VippsConfigurationKeyNames.VIPPS_SUBSCRIPTION_KEY_PRIMARY).IsNullOrWhiteSpace() && GetValue(VippsConfigurationKeyNames.VIPPS_SUBSCRIPTION_KEY_SECONDARY).IsNullOrWhiteSpace()) { throw new ArgumentNullException(VippsConfigurationKeyNames.VIPPS_SUBSCRIPTION_KEY_PRIMARY + VippsConfigurationKeyNames.VIPPS_SUBSCRIPTION_KEY_SECONDARY, "VippsEcommerceService: Neither VIPPS_SUBSCRIPTION_KEY_PRIMARY nor VIPPS_SUBSCRIPTION_KEY_SECONDARY was provided in configuration."); } } private string GetValueFromObject(string key) { foreach (var prop in typeof(VippsConfiguration).GetProperties()) { foreach (var attribute in prop.CustomAttributes) { foreach (var argument in attribute.ConstructorArguments) { if (argument.Value as string == key) { #if DEBUG var value = prop.GetValue(this, null)?.ToString(); Console.WriteLine("Key: " + key + " Value: " + value); return value; #else return prop.GetValue(this, null)?.ToString(); #endif } } } } return default; } } }