defmodule CampApi.PaymentLinks.Qonto do use GenServer use CampApiWeb, :verified_routes def base_url() do if Application.get_env(CampApi, :qonto, :staging) do "https://thirdparty-sandbox.staging.qonto.co" else "" end end def oauth_url() do if Application.get_env(CampApi, :qonto, :staging) do "https://oauth-sandbox.staging.qonto.co" else "https://oauth.qonto.com" end end def client_id() do if Application.get_env(CampApi, :qonto, :staging) do "d78920aa-e35f-4bfd-97df-e457f8337e2d" else "" end end def client_secret() do if Application.get_env(CampApi, :qonto, :staging) do "EqrS29dZYPy1Nfg8V8Bt6aRR1u" else "" end end def start_link(_) do GenServer.start_link(__MODULE__, %{}, name: __MODULE__) end def request(method, url, body) do GenServer.call(__MODULE__, {:request, method, url, body}) end def init(%{}) do oauth_client = OAuth2.Client.new( strategy: OAuth2.Strategy.AuthCode, client_id: client_id(), client_secret: client_secret(), site: oauth_url(), redirect_uri: url(~p"/api/qonto_auth"), authorize_url: "/oauth2/auth", token_url: "/oauth2/token" ) |> OAuth2.Client.put_serializer("application/json;charset=UTF-8", Jason) |> OAuth2.Client.put_serializer("application/json", Jason) {:ok, %{status: :disconnected, auth_state: nil, oauth_client: oauth_client}, {:continue, nil}} end def handle_continue(_, state) do auth_state = :crypto.strong_rand_bytes(24) |> Base.url_encode64(padding: false) # auth_url = %URI{ # # scheme: "https", # # host: oauth_url(), # URI.parse(oauth_url()) | # path: "/oauth2/auth", # query: # URI.encode_query(%{ # client_id: client_id(), # redirect_uri: url(~p"/api/qonto_auth"), # scope: "payment_link.write payment_link.read", # response_type: "code", # state: auth_state # # organization_id: TODO # }) # } auth_url = OAuth2.Client.authorize_url!(state.oauth_client, state: auth_state, scope: "payment_link.write payment_link.read") IO.puts("Plz go to the following URL:") IO.puts(auth_url) {:noreply, %{state | status: :pending, auth_state: auth_state}} end def create_token(code, auth_state) do GenServer.call(__MODULE__, {:create_token, code, auth_state}) end def handle_call({:create_token, code, auth_state}, _from, state) do # with state.status == :pending && state.auth_state == auth_state, # {:ok, %{body: %{"json" => %{"access_token" => access_token, "refresh_token" => refresh_token}}}} <- Req.post(base_url: oauth_url(), url: "/outh2/token", # {:reply, :ok, %{state | status: :connected, # headers = if Application.get_env(CampApi, :qonto, :staging) do [ {"x-qonto-staging-token", "0CxYRit4ZV7uwjoUluN93XgQvOt7bke96Nn0x5MUg2w="}, {"authorization", ""} ] else [] end with state.status == :pending && state.auth_state == auth_state, {:ok, oauth_client} <- OAuth2.Client.get_token(state.oauth_client, [code: code, client_secret: state.oauth_client.client_secret], headers) do {:reply, :ok, %{state | status: :connected, oauth_client: oauth_client}} else _ -> {:reply, :error, state} end end # def handle_call({:request, method, url, body}, _from, state) do # access_token = # headers = # if Application.get_env(CampApi, :qonto, :staging) do # [ # authorization: "Bearer #{state.access_token}", # x_qonto_staging_token: "0CxYRit4ZV7uwjoUluN93XgQvOt7bke96Nn0x5MUg2w=" # ] # else # [] # end # # Req.request(method: method, base_url: base_url(), url: url, headers: headers, json: body) # end def handle_call({:request, method, url, body}, _from, state) do url = base_url() <> url headers = if Application.get_env(CampApi, :qonto, :staging) do [ # x_qonto_staging_token: "0CxYRit4ZV7uwjoUluN93XgQvOt7bke96Nn0x5MUg2w=" {"x-qonto-staging-token", "0CxYRit4ZV7uwjoUluN93XgQvOt7bke96Nn0x5MUg2w="} ] else [] end case OAuth2.Request.request(method, state.oauth_client, url, Jason.encode!(body), headers, []) do {:ok, resp} -> {:reply, {:ok, resp}, state} _ -> {:reply, :error, state} end end end