@Override
  public void setSupportedCountries(MerchantStore store, List<String> countryCodes)
      throws ServiceException {

    // transform a list of string to json entry
    ObjectMapper mapper = new ObjectMapper();

    try {
      String value = mapper.writeValueAsString(countryCodes);

      MerchantConfiguration configuration =
          merchantConfigurationService.getMerchantConfiguration(SUPPORTED_COUNTRIES, store);

      if (configuration == null) {
        configuration = new MerchantConfiguration();
        configuration.setKey(SUPPORTED_COUNTRIES);
        configuration.setMerchantStore(store);
      }

      configuration.setValue(value);

      merchantConfigurationService.saveOrUpdate(configuration);

    } catch (Exception e) {
      throw new ServiceException(e);
    }
  }
  @Override
  public void removeShippingQuoteModuleConfiguration(String moduleCode, MerchantStore store)
      throws ServiceException {

    try {
      Map<String, IntegrationConfiguration> modules =
          new HashMap<String, IntegrationConfiguration>();
      MerchantConfiguration merchantConfiguration =
          merchantConfigurationService.getMerchantConfiguration(SHIPPING_MODULES, store);
      if (merchantConfiguration != null) {
        if (!StringUtils.isBlank(merchantConfiguration.getValue())) {
          String decrypted = encryption.decrypt(merchantConfiguration.getValue());
          modules = ConfigurationModulesLoader.loadIntegrationConfigurations(decrypted);
        }

        modules.remove(moduleCode);
        String configs = ConfigurationModulesLoader.toJSONString(modules);
        String encrypted = encryption.encrypt(configs);
        merchantConfiguration.setValue(encrypted);
        merchantConfigurationService.saveOrUpdate(merchantConfiguration);
      }

      MerchantConfiguration configuration =
          merchantConfigurationService.getMerchantConfiguration(moduleCode, store);

      if (configuration != null) { // custom module

        merchantConfigurationService.delete(configuration);
      }

    } catch (Exception e) {
      throw new ServiceException(e);
    }
  }
  @Override
  public void saveCustomShippingConfiguration(
      String moduleCode, CustomIntegrationConfiguration shippingConfiguration, MerchantStore store)
      throws ServiceException {

    ShippingQuoteModule quoteModule = (ShippingQuoteModule) shippingModules.get(moduleCode);
    if (quoteModule == null) {
      throw new ServiceException("Shipping module " + moduleCode + " does not exist");
    }

    String configurationValue = shippingConfiguration.toJSONString();

    try {

      MerchantConfiguration configuration =
          merchantConfigurationService.getMerchantConfiguration(moduleCode, store);

      if (configuration == null) {

        configuration = new MerchantConfiguration();
        configuration.setKey(moduleCode);
        configuration.setMerchantStore(store);
      }
      configuration.setValue(configurationValue);
      merchantConfigurationService.saveOrUpdate(configuration);

    } catch (Exception e) {
      throw new IntegrationException(e);
    }
  }
  @Override
  public void saveShippingQuoteModuleConfiguration(
      IntegrationConfiguration configuration, MerchantStore store) throws ServiceException {

    // validate entries
    try {

      String moduleCode = configuration.getModuleCode();
      ShippingQuoteModule quoteModule = (ShippingQuoteModule) shippingModules.get(moduleCode);
      if (quoteModule == null) {
        throw new ServiceException("Shipping quote module " + moduleCode + " does not exist");
      }
      quoteModule.validateModuleConfiguration(configuration, store);

    } catch (IntegrationException ie) {
      throw ie;
    }

    try {
      Map<String, IntegrationConfiguration> modules =
          new HashMap<String, IntegrationConfiguration>();
      MerchantConfiguration merchantConfiguration =
          merchantConfigurationService.getMerchantConfiguration(SHIPPING_MODULES, store);
      if (merchantConfiguration != null) {
        if (!StringUtils.isBlank(merchantConfiguration.getValue())) {

          String decrypted = encryption.decrypt(merchantConfiguration.getValue());
          modules = ConfigurationModulesLoader.loadIntegrationConfigurations(decrypted);
        }
      } else {
        merchantConfiguration = new MerchantConfiguration();
        merchantConfiguration.setMerchantStore(store);
        merchantConfiguration.setKey(SHIPPING_MODULES);
      }
      modules.put(configuration.getModuleCode(), configuration);

      String configs = ConfigurationModulesLoader.toJSONString(modules);

      String encrypted = encryption.encrypt(configs);
      merchantConfiguration.setValue(encrypted);
      merchantConfigurationService.saveOrUpdate(merchantConfiguration);

    } catch (Exception e) {
      throw new ServiceException(e);
    }
  }
  @Override
  public void saveShippingConfiguration(
      ShippingConfiguration shippingConfiguration, MerchantStore store) throws ServiceException {

    MerchantConfiguration configuration =
        merchantConfigurationService.getMerchantConfiguration(
            ShippingConstants.SHIPPING_CONFIGURATION, store);

    if (configuration == null) {
      configuration = new MerchantConfiguration();
      configuration.setMerchantStore(store);
      configuration.setKey(ShippingConstants.SHIPPING_CONFIGURATION);
    }

    String value = shippingConfiguration.toJSONString();
    configuration.setValue(value);
    merchantConfigurationService.saveOrUpdate(configuration);
  }