@@ -4,47 +4,67 @@ defmodule AlgoraWeb.Webhooks.StripeController do
4
4
import Ecto.Query
5
5
6
6
alias Algora.Payments
7
- alias Algora.Payments.Jobs.ExecuteTransfer
7
+ alias Algora.Payments.Jobs.ExecutePendingTransfers
8
8
alias Algora.Payments.Transaction
9
9
alias Algora.Repo
10
10
11
11
require Logger
12
12
13
+ @ metadata_version "2"
14
+
13
15
@ impl true
14
16
def handle_event ( % Stripe.Event {
15
17
type: "charge.succeeded" ,
16
- data: % { object: % { metadata: % { "version" => "2" , "group_id" => group_id } } }
18
+ data: % { object: % { metadata: % { "version" => @ metadata_version , "group_id" => group_id } } }
17
19
} )
18
20
when is_binary ( group_id ) do
19
- { :ok , count } =
20
- Repo . transact ( fn ->
21
- { count , _ } =
22
- Repo . update_all ( from ( t in Transaction , where: t . group_id == ^ group_id ) ,
23
- set: [ status: :succeeded , succeeded_at: DateTime . utc_now ( ) ]
24
- )
25
-
26
- # TODO: get pending transfers (recipient with active payout accounts)
27
- transfers = [ ]
28
-
29
- Enum . map ( transfers , fn % { transfer_id: transfer_id , user_id: user_id } ->
30
- % { transfer_id: transfer_id , user_id: user_id }
31
- |> ExecuteTransfer . new ( )
32
- |> Oban . insert ( )
21
+ Repo . transact ( fn ->
22
+ update_result =
23
+ Repo . update_all ( from ( t in Transaction , where: t . group_id == ^ group_id ) ,
24
+ set: [ status: :succeeded , succeeded_at: DateTime . utc_now ( ) ]
25
+ )
26
+
27
+ # TODO: split into two groups:
28
+ # - has active payout account -> execute pending transfers
29
+ # - has no active payout account -> notify user to connect payout account
30
+ jobs_result =
31
+ from ( t in Transaction ,
32
+ where: t . group_id == ^ group_id ,
33
+ where: t . type == :credit ,
34
+ where: t . status == :succeeded
35
+ )
36
+ |> Repo . all ( )
37
+ |> Enum . map ( fn % { user_id: user_id } -> user_id end )
38
+ |> Enum . uniq ( )
39
+ |> Enum . reduce_while ( :ok , fn user_id , :ok ->
40
+ case % { user_id: user_id , group_id: group_id }
41
+ |> ExecutePendingTransfers . new ( )
42
+ |> Oban . insert ( ) do
43
+ { :ok , _job } -> { :cont , :ok }
44
+ error -> { :halt , error }
45
+ end
33
46
end )
34
47
35
- { :ok , count }
36
- end )
48
+ with { count , _ } when count > 0 <- update_result ,
49
+ :ok <- jobs_result do
50
+ Payments . broadcast ( )
51
+ else
52
+ { :error , reason } ->
53
+ Logger . error ( "Failed to update transactions: #{ inspect ( reason ) } " )
54
+ { :error , :failed_to_update_transactions }
37
55
38
- if count == 0 do
39
- { :error , :no_transactions_found }
40
- else
41
- Payments . broadcast ( )
42
- { :ok , nil }
43
- end
56
+ _error ->
57
+ Logger . error ( "Failed to update transactions" )
58
+ { :error , :failed_to_update_transactions }
59
+ end
60
+ end )
44
61
end
45
62
46
63
@ impl true
47
64
def handle_event ( % Stripe.Event { type: "transfer.created" } = event ) do
65
+ # TODO: update transaction
66
+ # TODO: broadcast
67
+ # TODO: notify user
48
68
Logger . info ( "Stripe #{ event . type } event: #{ event . id } " )
49
69
end
50
70
0 commit comments