From cd4014719090e3d3094851cdb9528d664ddf4040 Mon Sep 17 00:00:00 2001 From: radewoosh Date: Sat, 31 Mar 2018 23:25:10 +0530 Subject: [PATCH] [SecurionPay] Implemented `purchase/3` SecurionPay =========== `purchasee/3` --------------- * Implemented two `purchase` clauses: - `CreditCard` struct (a `card_id` is NOT generated) - `card_id` (`customer_id` must be provided in `opts`) * Does not support optional arguments like shipping, billing etc. * In both cases, the Gateway API is hit only ONCE. Docs ---- * Added docs for `purchase/3`. Tests ----- * Added integration tests for `purchase/3`, uing ExVCR. --- lib/gringotts/gateways/securion_pay.ex | 36 ++++++++++++++++++ .../gateways/securion_pay_test.exs | 37 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/lib/gringotts/gateways/securion_pay.ex b/lib/gringotts/gateways/securion_pay.ex index 04e6d38f..ae625bac 100644 --- a/lib/gringotts/gateways/securion_pay.ex +++ b/lib/gringotts/gateways/securion_pay.ex @@ -116,6 +116,42 @@ defmodule Gringotts.Gateways.SecurionPay do commit([], "charges/#{payment_id}/capture", opts) end + @doc """ + Transfers `amount` from the customer to the merchant. + + SecurionPay attempts to process a purchase on behalf of the customer, by debiting + `amount` from the customer's account by charging the customer's `card`. + + The second argument can be a `CreditCard` or a `card_id`. The `customer_id` of the customer who owns the card must be + given in optional field if `card_id` is used. + + ## Example + ### With a `CreditCard` struct + iex> amount = Money.new(20, :USD) + iex> card = %Gringotts.CreditCard{first_name: "Harry", last_name: "Potter", number: "4200000000000000", year: 2099, month: 12, verification_code: "123", brand: "VISA"} + iex> result = Gringotts.Gateways.SecurionPay.purchase(amount, card, []) + + ## Example + ### With a `card_token` and `customer_token` + iex> amount = Money.new(20, :USD) + iex> opts = [customer_id: "cust_9999999999999999999999999"] + iex> card = "card_999999999999999" + iex> result = Gringotts.Gateways.SecurionPay.purchase(amount, card, opts) + + """ + + @spec purchase(Money.t(), CreditCard.t() | String.t(), keyword) :: {:ok | :error, Response.t()} + + def purchase(amount, %CreditCard{} = card, opts) do + params = common_params(amount, true) ++ card_params(card) + commit(params, "charges", opts) + end + + def purchase(amount, card_id, opts) when is_binary(card_id) do + params = common_params(amount, true) ++ card_params(card_id, opts) + commit(params, "charges", opts) + end + ########################################################################## # PRIVATE METHODS # ########################################################################## diff --git a/test/integration/gateways/securion_pay_test.exs b/test/integration/gateways/securion_pay_test.exs index aa8cd808..ea96f90b 100644 --- a/test/integration/gateways/securion_pay_test.exs +++ b/test/integration/gateways/securion_pay_test.exs @@ -99,4 +99,41 @@ defmodule Gringotts.Integration.Gateways.SecurionPayTest do end end end + + describe "[purchase]" do + test "with CreditCard" do + use_cassette "securion_pay/purchase_with_credit_card" do + assert {:ok, response} = Gateway.purchase(@amount, @good_card, @opts) + assert response.success == true + assert response.status_code == 200 + end + end + + test "with card_id and customer_id" do + use_cassette "securion_pay/purchase_with_card_id" do + assert {:ok, response} = Gateway.purchase(@amount, @card_id, @opts) + assert response.success == true + assert response.status_code == 200 + end + end + + test "with expired CreditCard" do + use_cassette "securion_pay/purchase_with_expired_card" do + assert {:error, response} = Gateway.purchase(@amount, @bad_card, @opts) + assert response.success == false + refute response.status_code == 200 + assert response.message == "card_error" + assert response.reason == "The card has expired." + end + end + + test "with card_id but no customer_id" do + use_cassette "securion_pay/purchase_without_customer_id" do + assert {:error, response} = Gateway.purchase(@amount, @card_id, @bad_opts) + assert response.success == false + refute response.status_code == 200 + assert response.message == "invalid_request" + end + end + end end