1
1
defmodule AlgoraWeb.Webhooks.StripeController do
2
2
@ behaviour Stripe.WebhookHandler
3
3
4
+ import Ecto.Changeset
4
5
import Ecto.Query
5
6
6
7
alias Algora.Payments
7
8
alias Algora.Payments.Jobs.ExecutePendingTransfers
8
9
alias Algora.Payments.Transaction
9
10
alias Algora.Repo
11
+ alias Algora.Util
10
12
11
13
require Logger
12
14
13
- @ metadata_version "2"
15
+ @ metadata_version Payments . metadata_version ( )
14
16
15
17
@ impl true
16
18
def handle_event ( % Stripe.Event {
17
19
type: "charge.succeeded" ,
18
- data: % { object: % { metadata: % { "version" => @ metadata_version , "group_id" => group_id } } }
20
+ data: % { object: % Stripe.Charge { metadata: % { "version" => @ metadata_version , "group_id" => group_id } } }
19
21
} )
20
22
when is_binary ( group_id ) do
21
23
Repo . transact ( fn ->
@@ -62,11 +64,20 @@ defmodule AlgoraWeb.Webhooks.StripeController do
62
64
end
63
65
64
66
@ impl true
65
- def handle_event ( % Stripe.Event { type: "transfer.created" } = event ) do
66
- # TODO: update transaction
67
- # TODO: broadcast
68
- # TODO: notify user
69
- Logger . info ( "Stripe #{ event . type } event: #{ event . id } " )
67
+ def handle_event ( % Stripe.Event {
68
+ type: "transfer.created" ,
69
+ data: % { object: % Stripe.Transfer { metadata: % { "version" => @ metadata_version } } = transfer }
70
+ } ) do
71
+ with { :ok , transaction } <- Repo . fetch_by ( Transaction , provider: "stripe" , provider_id: transfer . id ) ,
72
+ { :ok , _transaction } <- maybe_update_transaction ( transaction , transfer ) do
73
+ # TODO: notify user
74
+ Payments . broadcast ( )
75
+ { :ok , nil }
76
+ else
77
+ error ->
78
+ Logger . error ( "Failed to update transaction: #{ inspect ( error ) } " )
79
+ { :error , :failed_to_update_transaction }
80
+ end
70
81
end
71
82
72
83
@ impl true
@@ -76,4 +87,18 @@ defmodule AlgoraWeb.Webhooks.StripeController do
76
87
77
88
@ impl true
78
89
def handle_event ( _event ) , do: :ok
90
+
91
+ defp maybe_update_transaction ( transaction , transfer ) do
92
+ if transaction . status == :succeeded do
93
+ { :ok , transaction }
94
+ else
95
+ transaction
96
+ |> change ( % {
97
+ status: :succeeded ,
98
+ succeeded_at: DateTime . utc_now ( ) ,
99
+ provider_meta: Util . normalize_struct ( transfer )
100
+ } )
101
+ |> Repo . update ( )
102
+ end
103
+ end
79
104
end
0 commit comments