Skip to content

Commit

Permalink
Automatic confirm/capture
Browse files Browse the repository at this point in the history
  • Loading branch information
nkezhaya committed Oct 18, 2019
1 parent cab6a51 commit af9026d
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 16 deletions.
24 changes: 19 additions & 5 deletions lib/stripe_mock/api/operations/payment_intent.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@ defmodule StripeMock.API.Operations.PaymentIntent do
%PaymentIntent{}
|> PaymentIntent.changeset(attrs)
|> Repo.insert()
|> case do
{:ok, payment_intent} = result ->
if payment_intent.confirmation_method == "automatic" do
{:ok, payment_intent} = confirm_payment_intent(payment_intent)

if payment_intent.capture_method == "automatic" do
{:ok, _payment_intent} = capture_payment_intent(payment_intent)
end

get_payment_intent(payment_intent.id)
else
result
end

error ->
error
end
|> do_preloads()
end

Expand All @@ -37,10 +54,7 @@ defmodule StripeMock.API.Operations.PaymentIntent do
def confirm_payment_intent(%PaymentIntent{} = payment_intent) do
Multi.new()
|> Multi.insert(:charge, Charge.capture_changeset(%Charge{}, payment_intent))
|> Multi.update(
:payment_intent,
PaymentIntent.status_changeset(payment_intent, "requires_action")
)
|> Multi.update(:payment_intent, PaymentIntent.confirm_changeset(payment_intent))
|> Repo.transaction()
|> case do
{:ok, %{payment_intent: payment_intent}} -> {:ok, payment_intent}
Expand All @@ -54,7 +68,7 @@ defmodule StripeMock.API.Operations.PaymentIntent do

Multi.new()
|> Multi.update_all(:charge, query, set: [captured: true])
|> Multi.update(:payment_intent, PaymentIntent.status_changeset(payment_intent, "succeeded"))
|> Multi.update(:payment_intent, PaymentIntent.capture_changeset(payment_intent))
|> Repo.transaction()
|> case do
{:ok, %{payment_intent: payment_intent}} -> {:ok, payment_intent}
Expand Down
26 changes: 22 additions & 4 deletions lib/stripe_mock/api/payment_intent.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule StripeMock.API.PaymentIntent do
field :currency, :string
field :payment_method_types, {:array, :string}, default: ["card"]
field :statement_descriptor, :string
field :status, :string
field :status, :string, default: "requires_confirmation"
field :transfer_data, :map
field :transfer_group, :string

Expand Down Expand Up @@ -37,20 +37,38 @@ defmodule StripeMock.API.PaymentIntent do
:transfer_data,
:transfer_group
])
|> validate_inclusion(:capture_method, ~w(automatic manual))
|> validate_inclusion(:confirmation_method, ~w(automatic manual))
|> validate_inclusion(:capture_method, ~w(automatic manual))
|> set_payment_method()
|> validate_required([:payment_method_id])
|> put_common_fields()
end

@doc false
def status_changeset(payment_intent, status) do
def confirm_changeset(payment_intent) do
payment_intent
|> change()
|> ensure_status("requires_confirmation")
|> put_change(:status, "requires_capture")
|> put_common_fields()
end

@doc false
def capture_changeset(payment_intent) do
payment_intent
|> change(%{status: status})
|> change()
|> ensure_status("requires_capture")
|> put_change(:status, "succeeded")
|> put_common_fields()
end

defp ensure_status(changeset, status) do
case get_field(changeset, :status) do
^status -> changeset
s -> add_error(changeset, :status, "should be '#{status}', is '#{s}'")
end
end

defp set_payment_method(changeset) do
case get_change(changeset, :payment_method_id) do
nil ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,19 @@ defmodule StripeMockWeb.PaymentIntentControllerTest do

assert json_response(conn, 422)["errors"] != %{}
end
end

describe "manual update" do
setup [:create_manual_payment_intent]

test "confirms payment intent", %{conn: conn, payment_intent: payment_intent} do
conn = post(conn, Routes.payment_intent_path(conn, :confirm, payment_intent), %{})

assert %{"status" => "requires_action"} = json_response(conn, 200)
assert %{"status" => "requires_capture"} = json_response(conn, 200)
end

test "captures payment intent", %{conn: conn, payment_intent: payment_intent} do
conn
|> post(Routes.payment_intent_path(conn, :confirm, payment_intent), %{})
|> json_response(:ok)
conn = post(conn, Routes.payment_intent_path(conn, :confirm, payment_intent), %{})
assert %{"status" => "requires_capture"} = json_response(conn, 200)

conn = post(conn, Routes.payment_intent_path(conn, :capture, payment_intent), %{})

Expand Down
10 changes: 8 additions & 2 deletions test/test_helper.exs
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,26 @@ defmodule StripeMock.TestHelper do
[payment_intent: create_payment_intent(customer)]
end

def create_payment_intent(%API.Customer{} = customer) do
def create_payment_intent(%API.Customer{} = customer, manual? \\ false) do
[token: token] = create_token()

{:ok, charge} =
API.create_payment_intent(%{
amount: 5000,
currency: "some currency",
customer_id: customer.id,
payment_method_id: token.id
payment_method_id: token.id,
confirmation_method: if(manual?, do: "manual", else: "automatic"),
capture_method: if(manual?, do: "manual", else: "automatic")
})

charge
end

def create_manual_payment_intent(%{customer: customer}) do
[payment_intent: create_payment_intent(customer, true)]
end

def create_refund(%{charge: charge}) do
params = %{
amount: 5000,
Expand Down

0 comments on commit af9026d

Please sign in to comment.