@@ -2,10 +2,14 @@ defmodule Algora.Payments do
22 @ moduledoc false
33 import Ecto.Query
44
5+ alias Algora.Accounts
6+ alias Algora.Accounts.User
7+ alias Algora.Payments.Account
58 alias Algora.Payments.Customer
69 alias Algora.Payments.PaymentMethod
710 alias Algora.Payments.Transaction
811 alias Algora.Repo
12+ alias Algora.Util
913
1014 require Logger
1115
@@ -128,4 +132,95 @@ defmodule Algora.Payments do
128132 |> order_by ( [ t ] , desc: t . inserted_at )
129133 |> Repo . all ( )
130134 end
135+
136+ def get_account ( user_id , region ) do
137+ Account
138+ |> where ( [ a ] , a . user_id == ^ user_id and a . region == ^ region )
139+ |> Repo . one ( )
140+ end
141+
142+ @ spec create_account ( user :: User . t ( ) , attrs :: % { optional ( atom ( ) ) => any ( ) } ) ::
143+ { :ok , Account . t ( ) } | { :error , any ( ) }
144+ def create_account ( user , attrs ) do
145+ with { :ok , stripe_account } <- create_stripe_account ( attrs ) do
146+ attrs = % {
147+ provider: "stripe" ,
148+ provider_id: stripe_account . id ,
149+ provider_meta: Util . normalize_struct ( stripe_account ) ,
150+ type: attrs . type ,
151+ region: :US ,
152+ user_id: user . id ,
153+ country: attrs . country
154+ }
155+
156+ % Account { }
157+ |> Account . changeset ( attrs )
158+ |> Repo . insert ( )
159+ end
160+ end
161+
162+ @ spec create_stripe_account ( attrs :: % { optional ( atom ( ) ) => any ( ) } ) ::
163+ { :ok , Stripe.Account . t ( ) } | { :error , Stripe.Error . t ( ) }
164+ defp create_stripe_account ( % { country: country , type: type } ) do
165+ case Stripe.Account . create ( % { country: country , type: type } ) do
166+ { :ok , account } -> { :ok , account }
167+ { :error , _reason } -> Stripe.Account . create ( % { type: type } )
168+ end
169+ end
170+
171+ @ spec create_account_link ( account :: Account . t ( ) , base_url :: String . t ( ) ) ::
172+ { :ok , Stripe.AccountLink . t ( ) } | { :error , Stripe.Error . t ( ) }
173+ def create_account_link ( account , base_url ) do
174+ Stripe.AccountLink . create ( % {
175+ account: account . provider_id ,
176+ refresh_url: "#{ base_url } /callbacks/stripe/refresh" ,
177+ return_url: "#{ base_url } /callbacks/stripe/return" ,
178+ type: "account_onboarding"
179+ } )
180+ end
181+
182+ @ spec create_login_link ( account :: Account . t ( ) ) ::
183+ { :ok , Stripe.Account . t ( ) } | { :error , Stripe.Error . t ( ) }
184+ def create_login_link ( account ) do
185+ Stripe.Account . create_login_link ( account . provider_id , % { } )
186+ end
187+
188+ @ spec refresh_stripe_account ( user_id :: binary ( ) ) ::
189+ { :ok , Account . t ( ) } | { :error , :account_not_found } | { :error , any ( ) }
190+ def refresh_stripe_account ( user_id ) do
191+ case get_account ( user_id , :US ) do
192+ nil ->
193+ { :error , :account_not_found }
194+
195+ account ->
196+ with { :ok , stripe_account } <- Stripe.Account . retrieve ( account . provider_id ) do
197+ attrs = % {
198+ charges_enabled: stripe_account . charges_enabled ,
199+ details_submitted: stripe_account . details_submitted ,
200+ country: stripe_account . country ,
201+ service_agreement: stripe_account . tos_acceptance . service_agreement ,
202+ provider_meta: Util . normalize_struct ( stripe_account )
203+ }
204+
205+ account
206+ |> Account . changeset ( attrs )
207+ |> Repo . update ( )
208+ |> case do
209+ { :ok , updated_account } ->
210+ if stripe_account . charges_enabled do
211+ account . user_id
212+ |> Accounts . get_user! ( )
213+ |> Accounts . update_settings ( % { country: stripe_account . country } )
214+ end
215+
216+ # TODO: enqueue pending transfers
217+
218+ { :ok , updated_account }
219+
220+ error ->
221+ error
222+ end
223+ end
224+ end
225+ end
131226end
0 commit comments