Skip to content

Commit ef5bc84

Browse files
committed
handle transfer.created webhook
1 parent 30622ed commit ef5bc84

File tree

3 files changed

+43
-10
lines changed

3 files changed

+43
-10
lines changed

lib/algora/bounties/bounties.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ defmodule Algora.Bounties do
556556
|> Enum.map(&LineItem.to_stripe/1)
557557
|> Payments.create_stripe_session(%{
558558
description: description,
559-
metadata: %{"version" => "2", "group_id" => tx_group_id}
559+
metadata: %{"version" => Payments.metadata_version(), "group_id" => tx_group_id}
560560
}) do
561561
{:ok, session.url}
562562
end

lib/algora/payments/payments.ex

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ defmodule Algora.Payments do
1616

1717
require Logger
1818

19+
def metadata_version, do: "2"
20+
1921
def broadcast do
2022
Phoenix.PubSub.broadcast(Algora.PubSub, "payments:all", :payments_updated)
2123
end
@@ -322,12 +324,18 @@ defmodule Algora.Payments do
322324
case Algora.Stripe.create_transfer(%{
323325
amount: MoneyUtils.to_minor_units(transaction.net_amount),
324326
currency: MoneyUtils.to_stripe_currency(transaction.net_amount),
325-
destination: account.provider_id
327+
destination: account.provider_id,
328+
metadata: %{"version" => metadata_version()}
326329
}) do
327330
{:ok, transfer} ->
328331
# it's fine if this fails since we'll receive a webhook
329332
transaction
330-
|> change(%{status: :succeeded, provider_id: transfer.id, provider_meta: Util.normalize_struct(transfer)})
333+
|> change(%{
334+
status: :succeeded,
335+
succeeded_at: DateTime.utc_now(),
336+
provider_id: transfer.id,
337+
provider_meta: Util.normalize_struct(transfer)
338+
})
331339
|> Repo.update()
332340

333341
{:ok, transfer}

lib/algora_web/controllers/webhooks/stripe_controller.ex

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
defmodule AlgoraWeb.Webhooks.StripeController do
22
@behaviour Stripe.WebhookHandler
33

4+
import Ecto.Changeset
45
import Ecto.Query
56

67
alias Algora.Payments
78
alias Algora.Payments.Jobs.ExecutePendingTransfers
89
alias Algora.Payments.Transaction
910
alias Algora.Repo
11+
alias Algora.Util
1012

1113
require Logger
1214

13-
@metadata_version "2"
15+
@metadata_version Payments.metadata_version()
1416

1517
@impl true
1618
def handle_event(%Stripe.Event{
1719
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}}}
1921
})
2022
when is_binary(group_id) do
2123
Repo.transact(fn ->
@@ -62,11 +64,34 @@ defmodule AlgoraWeb.Webhooks.StripeController do
6264
end
6365

6466
@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
81+
end
82+
83+
defp maybe_update_transaction(transaction, transfer) do
84+
if transaction.status == :succeeded do
85+
{:ok, transaction}
86+
else
87+
transaction
88+
|> change(%{
89+
status: :succeeded,
90+
succeeded_at: DateTime.utc_now(),
91+
provider_meta: Util.normalize_struct(transfer)
92+
})
93+
|> Repo.update()
94+
end
7095
end
7196

7297
@impl true

0 commit comments

Comments
 (0)