DEV Community

Alexander Nitrovich
Alexander Nitrovich

Posted on • Originally published at blog.eurovalidate.com

Validate EU VAT in Phoenix

In this guide, we'll explore the implementation of EU VAT validation in a Phoenix (Elixir) application using the EuroValidate API. For businesses operating within the EU, verifying VAT numbers is essential to ensure compliance and avoid costly errors. Our step-by-step tutorial will guide you through setting up a Phoenix project, integrating the VAT validation API, and handling responses, including error scenarios. By the end, you'll have a practical understanding of how to handle VAT validation securely and efficiently within your Phoenix applications.

Setting Up Your Phoenix Project

First, we need to either create a new Phoenix application or use an existing one. If you're starting fresh, you can create a new Phoenix project by running:

mix phx.new vat_validation_app --no-ecto
cd vat_validation_app
Enter fullscreen mode Exit fullscreen mode

Next, add HTTPoison, which we'll use for making HTTP requests, to your project's dependencies. Edit your mix.exs file and add httpoison, and jason (for JSON parsing) as follows:

defp deps do
  [
    {:phoenix, "~> 1.6.0"},
    {:httpoison, "~> 1.8"},
    {:jason, "~> 1.2"}
  ]
end
Enter fullscreen mode Exit fullscreen mode

Run mix deps.get to install the new dependencies.

Integrating the VAT Validation API

To connect with our VAT validation API, you'll need an API key. Keep this key secure by storing it in your project's configuration files.

Configuring Your API Key

In config/config.exs, add your API key configuration:

config :vat_validation_app, vat_api_key: "YOUR_API_KEY"
Enter fullscreen mode Exit fullscreen mode

API Endpoint Overview

The API endpoint for VAT validation is: GET /v1/vat/{number}.

Here's a brief example of using curl to validate a VAT number:

curl -H "Authorization: Bearer YOUR_API_KEY" https://api.eurovalidate.com/v1/vat/NL820646660B01
Enter fullscreen mode Exit fullscreen mode

Implementing VAT Validation in Phoenix

Create a module to encapsulate the VAT validation logic:

defmodule MyApp.VatValidator do
  @api_url "https://api.eurovalidate.com/v1/vat"
  @api_key Application.get_env(:vat_validation_app, :vat_api_key)

  def validate(vat_number) when is_binary(vat_number) do
    url = "#{@api_url}/#{vat_number}"
    headers = [{"Authorization", "Bearer #{@api_key}"}, {"Content-Type", "application/json"}]

    case HTTPoison.get(url, headers) do
      {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
        {:ok, parse_response(body)}

      {:ok, %HTTPoison.Response{status_code: code}} when code in 400..499 ->
        {:error, "Client error: #{code}"}

      {:error, %HTTPoison.Error{reason: reason}} ->
        {:error, "Request failed: #{reason}"}
    end
  end

  defp parse_response(body) do
    body
    |> Jason.decode!()
    |> Map.get("data")
  end
end
Enter fullscreen mode Exit fullscreen mode

Integrating the Module within a Phoenix Controller

Next, integrate this validator within a controller:

defmodule MyAppWeb.VatController do
  use MyAppWeb, :controller

  alias MyApp.VatValidator

  def validate(conn, %{"vat_number" => vat_number}) do
    case VatValidator.validate(vat_number) do
      {:ok, result} ->
        json(conn, %{status: "success", data: result})

      {:error, message} ->
        conn
        |> put_status(:bad_request)
        |> json(%{status: "error", message: message})
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

Updating Routes

Update your router.ex to include a new route for VAT validation:

scope "/api", MyAppWeb do
  post "/vat/validate", VatController, :validate
end
Enter fullscreen mode Exit fullscreen mode

Testing Your Integration

Testing ensures our integration is reliable. Use Mox to mock HTTPoison requests in your test environment. Here’s an example test using ExUnit and Mox:

defmodule MyApp.VatValidatorTest do
  use ExUnit.Case, async: true
  import Mox

  setup :verify_on_exit!

  test "successfully validates a VAT number" do
    MyApp.HTTPoisonMock
    |> expect(:get, fn _, _ -> 
      {:ok, %HTTPoison.Response{status_code: 200, body: ~s({"data":{"status":"valid"}})}} 
      end)

    assert {:ok, %{"status" => "valid"}} = MyApp.VatValidator.validate("NL820646660B01")
  end
end
Enter fullscreen mode Exit fullscreen mode

Debugging Common Issues

When integrating, watch for common issues like network failures or invalid API keys. Ensure the correct configuration and error handling are in place to address these situations effectively.

Conclusion and Next Steps

Integrating the VAT validation API into your Phoenix application helps maintain compliance and improves transaction accuracy. We've walked through a practical example, but the journey doesn't stop here. Explore our API documentation for deeper insights and additional features.

Call to Action

Get started with EuroValidate today by signing up for a free API key at EuroValidate. We invite you to join our developer community forum to share feedback and gain support from like-minded professionals.

Top comments (0)