@@ -2,10 +2,14 @@ defmodule Algora.Payments do
2
2
@ moduledoc false
3
3
import Ecto.Query
4
4
5
+ alias Algora.Accounts
6
+ alias Algora.Accounts.User
7
+ alias Algora.Payments.Account
5
8
alias Algora.Payments.Customer
6
9
alias Algora.Payments.PaymentMethod
7
10
alias Algora.Payments.Transaction
8
11
alias Algora.Repo
12
+ alias Algora.Util
9
13
10
14
require Logger
11
15
@@ -128,4 +132,95 @@ defmodule Algora.Payments do
128
132
|> order_by ( [ t ] , desc: t . inserted_at )
129
133
|> Repo . all ( )
130
134
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
131
226
end
0 commit comments