Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial pass at Plaid EU #1555

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,7 @@ STRIPE_WEBHOOK_SECRET=
#
PLAID_CLIENT_ID=
PLAID_SECRET=
PLAID_ENV=
PLAID_ENV=
PLAID_EU_CLIENT_ID=
PLAID_EU_SECRET=
Shpigford marked this conversation as resolved.
Show resolved Hide resolved
PLAID_EU_ENV=
3 changes: 2 additions & 1 deletion app/controllers/concerns/accountable_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def set_link_token
@link_token = Current.family.get_link_token(
webhooks_url: webhooks_url,
redirect_url: accounts_url,
accountable_type: accountable_type.name
accountable_type: accountable_type.name,
region: Current.family.country.to_s.downcase == "us" ? :us : :eu
)
end

Expand Down
8 changes: 8 additions & 0 deletions app/models/concerns/plaidable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ module Plaidable
def plaid_provider
Provider::Plaid.new if Rails.application.config.plaid
end

def plaid_eu_provider
Provider::Plaid.new if Rails.application.config.plaid_eu
end
end

private
def plaid_provider
self.class.plaid_provider
end

def plaid_eu_provider
self.class.plaid_eu_provider
end
Shpigford marked this conversation as resolved.
Show resolved Hide resolved
end
16 changes: 12 additions & 4 deletions app/models/family.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,22 @@
super || accounts.manual.any?(&:syncing?) || plaid_items.any?(&:syncing?)
end

def get_link_token(webhooks_url:, redirect_url:, accountable_type: nil)
return nil unless plaid_provider
def get_link_token(webhooks_url:, redirect_url:, accountable_type: nil, region: :us)
provider = case region
when :eu
self.class.plaid_eu_provider
else
self.class.plaid_provider
end

Check failure on line 54 in app/models/family.rb

View workflow job for this annotation

GitHub Actions / ci / lint

Layout/EndAlignment: `end` at 54, 15 is not aligned with `provider = case` at 49, 4.

plaid_provider.get_link_token(
return nil unless provider

provider.get_link_token(
user_id: id,
webhooks_url: webhooks_url,
redirect_url: redirect_url,
accountable_type: accountable_type
accountable_type: accountable_type,
eu: region == :eu
).link_token
end

Expand Down
12 changes: 10 additions & 2 deletions app/models/provider/plaid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ def initialize
@client = self.class.client
end

def get_link_token(user_id:, webhooks_url:, redirect_url:, accountable_type: nil)
def get_link_token(user_id:, webhooks_url:, redirect_url:, accountable_type: nil, eu: false)
request = Plaid::LinkTokenCreateRequest.new({
user: { client_user_id: user_id },
client_name: "Maybe Finance",
products: [ get_primary_product(accountable_type) ],
additional_consented_products: get_additional_consented_products(accountable_type),
country_codes: [ "US" ],
country_codes: get_country_codes(eu),
language: "en",
webhook: webhooks_url,
redirect_uri: redirect_url,
Expand Down Expand Up @@ -198,4 +198,12 @@ def get_primary_product(accountable_type)
def get_additional_consented_products(accountable_type)
MAYBE_SUPPORTED_PLAID_PRODUCTS - [ get_primary_product(accountable_type) ]
end

def get_country_codes(eu)
if eu
[ "ES", "NL", "FR", "IE", "DE", "IT", "PL", "DK", "NO", "SE", "EE", "LT", "LV", "PT", "BE" ] # EU supported countries
else
[ "US" ] # US only
end
end
end
33 changes: 26 additions & 7 deletions app/views/accounts/new/_method_selector.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,35 @@
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
<%= lucide_icon("keyboard", class: "text-gray-500 w-5 h-5") %>
</span>
<%= t("accounts.new.method_selector.manual_entry") %>
<%= t(".manual_entry") %>
<% end %>

<% if link_token.present? %>
<button data-controller="plaid" data-action="plaid#open modal#close" data-plaid-link-token-value="<%= @link_token %>" class="flex items-center gap-4 w-full text-center focus:outline-none focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2">
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
<%= lucide_icon("link-2", class: "text-gray-500 w-5 h-5") %>
</span>
<%= t("accounts.new.method_selector.connected_entry") %>
</button>
<% if Current.family.country.to_s.downcase != "us" %>
<%# US Link %>
<button data-controller="plaid" data-action="plaid#open modal#close" data-plaid-link-token-value="<%= Current.family.get_link_token(webhooks_url: webhooks_plaid_url, redirect_url: accounts_url, accountable_type: accountable_type.name, region: :us) %>" class="flex items-center gap-4 w-full text-center focus:outline-none focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2">
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
<%= lucide_icon("link-2", class: "text-gray-500 w-5 h-5") %>
</span>
<%= t(".connected_entry_us") %>
</button>

<%# EU Link %>
<button data-controller="plaid" data-action="plaid#open modal#close" data-plaid-link-token-value="<%= Current.family.get_link_token(webhooks_url: webhooks_plaid_url, redirect_url: accounts_url, accountable_type: accountable_type.name, region: :eu) %>" class="flex items-center gap-4 w-full text-center focus:outline-none focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2">
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
<%= lucide_icon("link-2", class: "text-gray-500 w-5 h-5") %>
</span>
<%= t(".connected_entry_eu") %>
</button>
<% else %>
<%# Default US-only Link %>
<button data-controller="plaid" data-action="plaid#open modal#close" data-plaid-link-token-value="<%= @link_token %>" class="flex items-center gap-4 w-full text-center focus:outline-none focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2">
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
<%= lucide_icon("link-2", class: "text-gray-500 w-5 h-5") %>
</span>
<%= t(".connected_entry") %>
</button>
<% end %>
Shpigford marked this conversation as resolved.
Show resolved Hide resolved
<% end %>
</div>
<% end %>
8 changes: 8 additions & 0 deletions config/initializers/plaid.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
Rails.application.configure do
config.plaid = nil
config.plaid_eu = nil

if ENV["PLAID_CLIENT_ID"].present? && ENV["PLAID_SECRET"].present?
config.plaid = Plaid::Configuration.new
config.plaid.server_index = Plaid::Configuration::Environment[ENV["PLAID_ENV"] || "sandbox"]
config.plaid.api_key["PLAID-CLIENT-ID"] = ENV["PLAID_CLIENT_ID"]
config.plaid.api_key["PLAID-SECRET"] = ENV["PLAID_SECRET"]
end

if ENV["PLAID_EU_CLIENT_ID"].present? && ENV["PLAID_EU_SECRET"].present?
config.plaid_eu = Plaid::Configuration.new
config.plaid_eu.server_index = Plaid::Configuration::Environment[ENV["PLAID_EU_ENV"] || "sandbox"]
config.plaid_eu.api_key["PLAID-CLIENT-ID"] = ENV["PLAID_EU_CLIENT_ID"]
config.plaid_eu.api_key["PLAID-SECRET"] = ENV["PLAID_EU_SECRET"]
end
end
2 changes: 2 additions & 0 deletions config/locales/views/accounts/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ en:
import_accounts: Import accounts
method_selector:
connected_entry: Link account
connected_entry_us: Link US account
connected_entry_eu: Link EU account
manual_entry: Enter account balance
title: How would you like to add it?
title: What would you like to add?
Expand Down
41 changes: 41 additions & 0 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading