Skip to content

Commit 1bb3eba

Browse files
committed
fix: tipping payment flow
1 parent dc9260a commit 1bb3eba

File tree

2 files changed

+112
-38
lines changed

2 files changed

+112
-38
lines changed

lib/algora/bounties/bounties.ex

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -548,29 +548,49 @@ defmodule Algora.Bounties do
548548

549549
@spec create_tip(
550550
%{creator: User.t(), owner: User.t(), recipient: User.t(), amount: Money.t()},
551-
opts :: [ticket_ref: %{owner: String.t(), repo: String.t(), number: integer()}]
551+
opts :: [ticket_ref: %{owner: String.t(), repo: String.t(), number: integer()}, installation_id: integer()]
552552
) ::
553553
{:ok, String.t()} | {:error, atom()}
554554
def create_tip(%{creator: creator, owner: owner, recipient: recipient, amount: amount}, opts \\ []) do
555-
changeset =
556-
Tip.changeset(%Tip{}, %{
557-
amount: amount,
558-
owner_id: owner.id,
559-
creator_id: creator.id,
560-
recipient_id: recipient.id
561-
})
555+
token_res =
556+
if opts[:installation_id] do
557+
Github.get_installation_token(opts[:installation_id])
558+
else
559+
case Accounts.get_access_token(creator) do
560+
{:ok, token} -> {:ok, token}
561+
{:error, _reason} -> {:ok, nil}
562+
end
563+
end
562564

563-
activity_attrs =
564-
%{
565-
type: :tip_awarded,
566-
notify_users: [recipient.id]
567-
}
565+
ticket_ref = opts[:ticket_ref]
566+
567+
ticket_res =
568+
if ticket_ref do
569+
with {:ok, token} <- token_res do
570+
Workspace.ensure_ticket(token, ticket_ref[:owner], ticket_ref[:repo], ticket_ref[:number])
571+
end
572+
else
573+
{:ok, nil}
574+
end
568575

569576
Repo.transact(fn ->
570-
with {:ok, tip} <- Repo.insert_with_activity(changeset, activity_attrs) do
577+
with {:ok, ticket} <- ticket_res,
578+
{:ok, tip} <-
579+
%Tip{}
580+
|> Tip.changeset(%{
581+
amount: amount,
582+
owner_id: owner.id,
583+
creator_id: creator.id,
584+
recipient_id: recipient.id,
585+
ticket_id: if(ticket, do: ticket.id)
586+
})
587+
|> Repo.insert_with_activity(%{
588+
type: :tip_awarded,
589+
notify_users: [recipient.id]
590+
}) do
571591
create_payment_session(
572592
%{owner: owner, amount: amount, description: "Tip payment for OSS contributions"},
573-
ticket_ref: opts[:ticket_ref],
593+
ticket_ref: ticket_ref,
574594
tip_id: tip.id,
575595
recipient: recipient
576596
)
@@ -622,29 +642,31 @@ defmodule Algora.Bounties do
622642
platform_fee_pct = FeeTier.calculate_fee_percentage(Money.zero(:USD))
623643
transaction_fee_pct = Payments.get_transaction_fee_pct()
624644

625-
if recipient do
626-
[
627-
%LineItem{
628-
amount: amount,
629-
title: "Payment to @#{recipient.provider_login}",
630-
description: description,
631-
image: recipient.avatar_url,
632-
type: :payout
633-
}
634-
]
635-
else
636-
[]
637-
end ++
638-
Enum.map(claims, fn claim ->
639-
%LineItem{
640-
# TODO: ensure shares are normalized
641-
amount: Money.mult!(amount, claim.group_share),
642-
title: "Payment to @#{claim.user.provider_login}",
643-
description: description,
644-
image: claim.user.avatar_url,
645-
type: :payout
646-
}
647-
end) ++
645+
payouts =
646+
if recipient do
647+
[
648+
%LineItem{
649+
amount: amount,
650+
title: "Payment to @#{recipient.provider_login}",
651+
description: description,
652+
image: recipient.avatar_url,
653+
type: :payout
654+
}
655+
]
656+
else
657+
Enum.map(claims, fn claim ->
658+
%LineItem{
659+
# TODO: ensure shares are normalized
660+
amount: Money.mult!(amount, claim.group_share),
661+
title: "Payment to @#{claim.user.provider_login}",
662+
description: description,
663+
image: claim.user.avatar_url,
664+
type: :payout
665+
}
666+
end)
667+
end
668+
669+
payouts ++
648670
[
649671
%LineItem{
650672
amount: Money.mult!(amount, platform_fee_pct),
@@ -698,6 +720,7 @@ defmodule Algora.Bounties do
698720
create_transaction_pairs(%{
699721
claims: opts[:claims] || [],
700722
tip_id: opts[:tip_id],
723+
recipient_id: if(opts[:recipient], do: opts[:recipient].id),
701724
bounty_id: opts[:bounty_id],
702725
claim_id: nil,
703726
amount: amount,
@@ -755,6 +778,7 @@ defmodule Algora.Bounties do
755778
create_transaction_pairs(%{
756779
claims: opts[:claims] || [],
757780
tip_id: opts[:tip_id],
781+
recipient_id: if(opts[:recipient], do: opts[:recipient].id),
758782
bounty_id: opts[:bounty_id],
759783
claim_id: nil,
760784
amount: amount,

test/algora/bounties_test.exs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,56 @@ defmodule Algora.BountiesTest do
229229
end
230230
end
231231

232+
describe "tips" do
233+
test "successfully creates checkout url for tips" do
234+
creator = insert!(:user)
235+
owner = insert!(:organization)
236+
recipient = insert!(:user)
237+
repo = insert!(:repository, %{user: owner})
238+
ticket = insert!(:ticket, %{repository: repo})
239+
amount = ~M[4000]usd
240+
241+
ticket_ref = %{
242+
owner: owner.handle,
243+
repo: repo.name,
244+
number: ticket.number
245+
}
246+
247+
assert {:ok, _checkout_url} =
248+
Bounties.create_tip(
249+
%{
250+
amount: amount,
251+
owner: owner,
252+
creator: creator,
253+
recipient: recipient
254+
},
255+
ticket_ref: ticket_ref
256+
)
257+
258+
tip = Repo.one!(Tip)
259+
260+
charge = Repo.one!(from t in Transaction, where: t.type == :charge)
261+
assert Money.equal?(charge.net_amount, amount)
262+
assert charge.status == :initialized
263+
assert charge.user_id == owner.id
264+
265+
debit = Repo.one!(from t in Transaction, where: t.type == :debit)
266+
assert Money.equal?(debit.net_amount, amount)
267+
assert debit.status == :initialized
268+
assert debit.user_id == owner.id
269+
assert debit.tip_id == tip.id
270+
271+
credit = Repo.one!(from t in Transaction, where: t.type == :credit)
272+
assert Money.equal?(credit.net_amount, amount)
273+
assert credit.status == :initialized
274+
assert credit.user_id == recipient.id
275+
assert credit.tip_id == tip.id
276+
277+
transfer = Repo.one(from t in Transaction, where: t.type == :transfer)
278+
assert is_nil(transfer)
279+
end
280+
end
281+
232282
describe "get_response_body/4" do
233283
test "generates correct response body with bounties and attempts" do
234284
repo_owner = insert!(:user, provider_login: "repo_owner")

0 commit comments

Comments
 (0)