defmodule ExUSPS do @moduledoc false def validate_address(opts \\ []) do :AddressValidateRequest |> XmlBuilder.element(%{USERID: get_user_id()}, [XmlBuilder.element(:Address, opts)]) |> XmlBuilder.generate() |> request_url("Verify") |> request() end def lookup_zip_code(opts \\ []) do :ZipCodeLookupRequest |> XmlBuilder.element(%{USERID: get_user_id()}, [XmlBuilder.element(:Address, opts)]) |> XmlBuilder.generate() |> request_url("ZipCodeLookup") |> request() end def lookup_city_state(opts \\ []) do :CityStateLookupRequest |> XmlBuilder.element(%{USERID: get_user_id()}, [XmlBuilder.element(:ZipCode, opts)]) |> XmlBuilder.generate() |> request_url("CityStateLookup") |> request() end @base_url "http://production.shippingapis.com/ShippingAPI.dll" @missing_auth_info_message "The user_id is required to use USPS APIs." defp request(endpoint) do HTTPoison.request :post, endpoint end defp request_url(xml, api_name) do encoded_xml = URI.encode(xml) base_url = get_api_endpoint() query_params = "API=#{api_name}&XML=#{encoded_xml}" "#{base_url}?#{query_params}" end defp get_user_id do from_env(:ex_usps, :user_id) || raise(AuthenticationError, message: @missing_auth_info_message) end defp get_api_endpoint do from_env(:ex_usps, :api_endpoint) || @base_url end defp from_env(otp_app, key, default \\ nil) defp from_env(otp_app, key, default) do otp_app |> Application.get_env(key, default) |> read_env_from_system(default) end defp read_env_from_system({:system, env}, default) do System.get_env(env) || default end defp read_env_from_system(value, _default) do value end end