defmodule Mercadopago.API do require Logger @moduledoc """ Documentation for Mercadopago.API. This module is about the base HTTP functionality """ @base_url "https://api.mercadopago.com" @doc """ Requests an OAuth token from Mercadopago, returns a tuple containing the token and seconds till expiry. Possible returns: - {:ok, data} - {:error, reason} ## Examples iex> Mercadopago.API.create_token() {:ok, {..}} """ def create_token() do params = %{ "client_id" => Mercadopago.Config.get.client_id, "client_secret" => Mercadopago.Config.get.client_secret, "grant_type" => "client_credentials" } headers = [ {"content-type", "application/x-www-form-urlencoded"} ] case HTTPoison.post(base_url() <> "/oauth/token", Poison.encode!(params), headers) do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> token = body |> Poison.decode!() Logger.info("Access token obtained successfully.") {:ok, {token["access_token"], token["expires_in"]}} {:error, %HTTPoison.Error{reason: reason}} -> Logger.error("Error getting access token: #{inspect(reason)}") {:error, reason} end end @doc """ Make an HTTP GET request to the correct API, adding the authentication required header. Possible returns: - {:ok, data} - {:ok, :not_found} - {:ok, :no_content} - {:error, :bad_network} - {:error, reason} ## Examples iex> Mercadopago.API.get(url) {:ok, {...}} """ def get(url) do case HTTPoison.get(base_url() <> url, headers()) do {:ok, %{status_code: 404}} -> {:error, :not_found} {:ok, %{status_code: 401}} -> {:error, :unauthorised} {:ok, %{status_code: 400}} -> {:error, :not_found} {:ok, %{status_code: 204}} -> {:ok, :no_content} {:ok, %{body: body, status_code: 200}} -> {:ok, Poison.decode!(body, keys: :atoms)} {:ok, %{body: body}}-> {:error, body} _ -> {:error, :bad_network} end end @doc """ Make an HTTP POST request to the correct API, adding the authentication required header. ## Examples iex> Mercadopago.API.post(url, data) {:ok, {...}} """ @spec post(String.t, map | list | nil) :: {:ok, map | :not_found | :no_content | nil} | {:error, :unauthorised | :bad_network | any} def post(url, data) do {:ok, data} = Poison.encode(data) case HTTPoison.post(base_url() <> url, data, headers()) do {:ok, %{status_code: 404}} -> {:error, :not_found} {:ok, %{status_code: 401}} -> {:error, :unauthorised} {:ok, %{status_code: 400}} -> {:error, :bad_request} {:ok, %{status_code: 204}} -> {:ok, nil} {:ok, %{body: body, status_code: 201}} -> {:ok, Poison.decode!(body, keys: :atoms)} {:ok, %{body: body, status_code: 200}} -> {:ok, Poison.decode!(body, keys: :atoms)} {:ok, %{body: body}} = resp -> IO.inspect resp {:error, body} _ -> {:error, :bad_network} end end @doc """ Make an HTTP PUT request to the correct API, adding the authentication required header. ## Examples iex> Mercadopago.API.put(url, data) {:ok, {...}} """ @spec put(String.t, map | list | nil) :: {:ok, map | :not_found | :no_content | nil} | {:error, :unauthorised | :bad_network | any} def put(url, data) do {:ok, data} = Poison.encode(data) case HTTPoison.put(base_url() <> url, data, headers()) do {:ok, %{status_code: 404}} -> {:error, :not_found} {:ok, %{status_code: 401}} -> {:error, :unauthorised} {:ok, %{status_code: 400}} -> {:error, :bad_request} {:ok, %{status_code: 204}} -> {:ok, nil} {:ok, %{body: body, status_code: 201}} -> {:ok, Poison.decode!(body, keys: :atoms)} {:ok, %{body: body, status_code: 200}} -> {:ok, Poison.decode!(body, keys: :atoms)} {:ok, %{body: body}} = resp -> IO.inspect resp {:error, body} _ -> {:error, :bad_network} end end @doc """ Make an HTTP DELETE request to the correct API, adding the authentication required header. ## Examples iex> Mercadopago.API.delete(url) {:ok, {...}} """ def delete(url) do case HTTPoison.delete(base_url() <> url, headers()) do {:ok, %{status_code: 404}} -> {:error, :not_found} {:ok, %{status_code: 401}} -> {:error, :unauthorised} {:ok, %{status_code: 400}} -> {:error, :not_found} {:ok, %{status_code: 204}} -> {:ok, :no_content} {:ok, %{body: body, status_code: 200}} -> {:ok, Poison.decode!(body, keys: :atoms)} {:ok, %{body: body}}-> {:error, body} _ -> {:error, :bad_network} end end defp headers() do [ {"Authorization", "Bearer #{mercadopago_token()}"}, {"Content-Type", "application/json"} ] end defp base_url, do: @base_url defp mercadopago_token, do: Mercadopago.get_token() end