@@ -2,10 +2,15 @@ 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.Stripe.ConnectCountries
13
+ alias Algora.Util
9
14
10
15
require Logger
11
16
@@ -128,4 +133,119 @@ defmodule Algora.Payments do
128
133
|> order_by ( [ t ] , desc: t . inserted_at )
129
134
|> Repo . all ( )
130
135
end
136
+
137
+ @ spec fetch_or_create_account ( user :: User . t ( ) , country :: String . t ( ) ) ::
138
+ { :ok , Account . t ( ) } | { :error , Ecto.Changeset . t ( ) }
139
+ def fetch_or_create_account ( user , country ) do
140
+ case fetch_account ( user ) do
141
+ { :ok , account } -> { :ok , account }
142
+ { :error , :not_found } -> create_account ( user , country )
143
+ end
144
+ end
145
+
146
+ @ spec fetch_account ( user :: User . t ( ) ) ::
147
+ { :ok , Account . t ( ) } | { :error , :not_found }
148
+ def fetch_account ( user ) do
149
+ Repo . fetch_by ( Account , user_id: user . id )
150
+ end
151
+
152
+ @ spec create_account ( user :: User . t ( ) , country :: String . t ( ) ) ::
153
+ { :ok , Account . t ( ) } | { :error , Ecto.Changeset . t ( ) }
154
+ def create_account ( user , country ) do
155
+ type = ConnectCountries . account_type ( country )
156
+
157
+ with { :ok , stripe_account } <- create_stripe_account ( % { country: country , type: type } ) do
158
+ attrs = % {
159
+ provider: "stripe" ,
160
+ provider_id: stripe_account . id ,
161
+ provider_meta: Util . normalize_struct ( stripe_account ) ,
162
+ type: type ,
163
+ user_id: user . id ,
164
+ country: country
165
+ }
166
+
167
+ % Account { }
168
+ |> Account . changeset ( attrs )
169
+ |> Repo . insert ( )
170
+ end
171
+ end
172
+
173
+ @ spec create_stripe_account ( attrs :: map ( ) ) ::
174
+ { :ok , Stripe.Account . t ( ) } | { :error , Stripe.Error . t ( ) }
175
+ defp create_stripe_account ( % { country: country , type: type } ) do
176
+ case Stripe.Account . create ( % { country: country , type: to_string ( type ) } ) do
177
+ { :ok , account } -> { :ok , account }
178
+ { :error , _reason } -> Stripe.Account . create ( % { type: to_string ( type ) } )
179
+ end
180
+ end
181
+
182
+ @ spec create_account_link ( account :: Account . t ( ) , base_url :: String . t ( ) ) ::
183
+ { :ok , Stripe.AccountLink . t ( ) } | { :error , Stripe.Error . t ( ) }
184
+ def create_account_link ( account , base_url ) do
185
+ Stripe.AccountLink . create ( % {
186
+ account: account . provider_id ,
187
+ refresh_url: "#{ base_url } /callbacks/stripe/refresh" ,
188
+ return_url: "#{ base_url } /callbacks/stripe/return" ,
189
+ type: "account_onboarding"
190
+ } )
191
+ end
192
+
193
+ @ spec create_login_link ( account :: Account . t ( ) ) ::
194
+ { :ok , Stripe.LoginLink . t ( ) } | { :error , Stripe.Error . t ( ) }
195
+ def create_login_link ( account ) do
196
+ Stripe.LoginLink . create ( account . provider_id , % { } )
197
+ end
198
+
199
+ @ spec update_account ( account :: Account . t ( ) , stripe_account :: Stripe.Account . t ( ) ) ::
200
+ { :ok , Account . t ( ) } | { :error , Ecto.Changeset . t ( ) }
201
+ def update_account ( account , stripe_account ) do
202
+ account
203
+ |> Account . changeset ( % {
204
+ provider: "stripe" ,
205
+ provider_id: stripe_account . id ,
206
+ provider_meta: Util . normalize_struct ( stripe_account ) ,
207
+ charges_enabled: stripe_account . charges_enabled ,
208
+ payouts_enabled: stripe_account . payouts_enabled ,
209
+ payout_interval: stripe_account . settings . payouts . schedule . interval ,
210
+ payout_speed: stripe_account . settings . payouts . schedule . delay_days ,
211
+ default_currency: stripe_account . default_currency ,
212
+ details_submitted: stripe_account . details_submitted ,
213
+ country: stripe_account . country ,
214
+ service_agreement: get_service_agreement ( stripe_account )
215
+ } )
216
+ |> Repo . update ( )
217
+ end
218
+
219
+ @ spec refresh_stripe_account ( user :: User . t ( ) ) ::
220
+ { :ok , Account . t ( ) } | { :error , Ecto.Changeset . t ( ) } | { :error , :not_found } | { :error , Stripe.Error . t ( ) }
221
+ def refresh_stripe_account ( user ) do
222
+ with { :ok , account } <- fetch_account ( user ) ,
223
+ { :ok , stripe_account } <- Stripe.Account . retrieve ( account . provider_id , [ ] ) ,
224
+ { :ok , updated_account } <- update_account ( account , stripe_account ) do
225
+ user = Accounts . get_user ( account . user_id )
226
+
227
+ if user && stripe_account . charges_enabled do
228
+ Accounts . update_settings ( user , % { country: stripe_account . country } )
229
+ end
230
+
231
+ { :ok , updated_account }
232
+ end
233
+ end
234
+
235
+ @ spec get_service_agreement ( account :: Stripe.Account . t ( ) ) :: String . t ( )
236
+ defp get_service_agreement ( % { tos_acceptance: % { service_agreement: agreement } } = _account ) when not is_nil ( agreement ) do
237
+ agreement
238
+ end
239
+
240
+ @ spec get_service_agreement ( account :: Stripe.Account . t ( ) ) :: String . t ( )
241
+ defp get_service_agreement ( % { capabilities: capabilities } ) do
242
+ if is_nil ( capabilities [ :card_payments ] ) , do: "recipient" , else: "full"
243
+ end
244
+
245
+ @ spec delete_account ( account :: Account . t ( ) ) :: { :ok , Account . t ( ) } | { :error , Ecto.Changeset . t ( ) }
246
+ def delete_account ( account ) do
247
+ with { :ok , _stripe_account } <- Stripe.Account . delete ( account . provider_id ) do
248
+ Repo . delete ( account )
249
+ end
250
+ end
131
251
end
0 commit comments