# app/services/veqen.rb
require "net/http"
require "json"
class Veqen
URL = URI("https://veqen-app.com/v1/signup/check")
def self.screen(email:, ip: nil, phone: nil)
http = Net::HTTP.new(URL.host, URL.port)
http.use_ssl = URL.scheme == "https"
http.open_timeout = 2
http.read_timeout = 4
request = Net::HTTP::Post.new(URL, "Content-Type" => "application/json",
"Authorization" => "Bearer #{ENV.fetch('VEQEN_API_KEY')}")
request.body = { email: email, ip: ip, phone: phone }.compact.to_json
response = http.request(request)
response.is_a?(Net::HTTPSuccess) ? JSON.parse(response.body) : nil
rescue StandardError
nil # fail open
end
end
# app/controllers/registrations_controller.rb
class RegistrationsController < ApplicationController
def create
check = Veqen.screen(email: params[:email], ip: request.remote_ip)
verdict = check ? check.dig("risk", "verdict") : "review"
if verdict == "refuse"
flash.now[:alert] = "Please use a permanent email address."
return render :new, status: :unprocessable_entity
end
@user = User.create!(email: params[:email], password: params[:password],
canonical_email: check&.dig("email", "canonical"),
needs_verification: verdict == "review")
redirect_to onboarding_path
end
end
request.remote_ip respects X-Forwarded-For from trusted proxies (configure config.action_dispatch.trusted_proxies if needed).