mirror of
https://github.com/valitydev/hellgate.git
synced 2024-11-06 02:45:20 +00:00
TD-291: test refactoring/split suite (#82)
* TD-291: test refactoring/split suite * TD-291: fix format/dialyzer checks * TD-291: update style config * TD-291: fix typo --------- Co-authored-by: anatoliy.losev <losto@nix>
This commit is contained in:
parent
37f8ed7057
commit
db39bf920d
29
apps/hellgate/test/hg_ct_invoice.hrl
Normal file
29
apps/hellgate/test/hg_ct_invoice.hrl
Normal file
@ -0,0 +1,29 @@
|
||||
-include("invoice_events.hrl").
|
||||
-include("payment_events.hrl").
|
||||
-include("customer_events.hrl").
|
||||
|
||||
-define(invoice(ID), #domain_Invoice{id = ID}).
|
||||
-define(payment(ID), #domain_InvoicePayment{id = ID}).
|
||||
-define(payment(ID, Revision), #domain_InvoicePayment{id = ID, party_revision = Revision}).
|
||||
-define(adjustment(ID), #domain_InvoicePaymentAdjustment{id = ID}).
|
||||
-define(adjustment(ID, Status), #domain_InvoicePaymentAdjustment{id = ID, status = Status}).
|
||||
-define(adjustment_revision(Revision), #domain_InvoicePaymentAdjustment{party_revision = Revision}).
|
||||
-define(adjustment_reason(Reason), #domain_InvoicePaymentAdjustment{reason = Reason}).
|
||||
-define(invoice_state(Invoice), #payproc_Invoice{invoice = Invoice}).
|
||||
-define(invoice_state(Invoice, Payments), #payproc_Invoice{invoice = Invoice, payments = Payments}).
|
||||
-define(payment_state(Payment), #payproc_InvoicePayment{payment = Payment}).
|
||||
-define(payment_state(Payment, Refunds), #payproc_InvoicePayment{payment = Payment, refunds = Refunds}).
|
||||
-define(payment_route(Route), #payproc_InvoicePayment{route = Route}).
|
||||
-define(refund_state(Refund), #payproc_InvoicePaymentRefund{refund = Refund}).
|
||||
-define(payment_cashflow(CashFlow), #payproc_InvoicePayment{cash_flow = CashFlow}).
|
||||
-define(payment_last_trx(Trx), #payproc_InvoicePayment{last_transaction_info = Trx}).
|
||||
-define(invoice_w_status(Status), #domain_Invoice{status = Status}).
|
||||
-define(invoice_w_revision(Revision), #domain_Invoice{party_revision = Revision}).
|
||||
-define(payment_w_status(Status), #domain_InvoicePayment{status = Status}).
|
||||
-define(payment_w_status(ID, Status), #domain_InvoicePayment{id = ID, status = Status}).
|
||||
-define(invoice_payment_refund(Cash, Status), #domain_InvoicePaymentRefund{cash = Cash, status = Status}).
|
||||
-define(trx_info(ID), #domain_TransactionInfo{id = ID}).
|
||||
-define(trx_info(ID, Extra), #domain_TransactionInfo{id = ID, extra = Extra}).
|
||||
-define(refund_id(RefundID), #domain_InvoicePaymentRefund{id = RefundID}).
|
||||
-define(refund_id(RefundID, ExternalID), #domain_InvoicePaymentRefund{id = RefundID, external_id = ExternalID}).
|
||||
-define(contact_info(), ?contact_info(undefined)).
|
455
apps/hellgate/test/hg_invoice_helper.erl
Normal file
455
apps/hellgate/test/hg_invoice_helper.erl
Normal file
@ -0,0 +1,455 @@
|
||||
-module(hg_invoice_helper).
|
||||
|
||||
-include("hg_ct_invoice.hrl").
|
||||
-include("hg_ct_domain.hrl").
|
||||
|
||||
-define(DEFAULT_NEXT_CHANGE_TIMEOUT, 12000).
|
||||
|
||||
%%
|
||||
-export([
|
||||
start_kv_store/1,
|
||||
stop_kv_store/1,
|
||||
start_proxies/1
|
||||
]).
|
||||
|
||||
-export([
|
||||
make_due_date/1,
|
||||
start_invoice/4,
|
||||
start_invoice/5,
|
||||
start_invoice/6,
|
||||
next_changes/3,
|
||||
next_change/2,
|
||||
next_change/3,
|
||||
make_payment_params/1,
|
||||
make_payment_params/2,
|
||||
make_payment_params/3,
|
||||
register_payment/4,
|
||||
start_payment/3,
|
||||
start_payment_ev/2,
|
||||
start_payment_ev_no_risk_scoring/2,
|
||||
await_payment_session_started/4,
|
||||
await_payment_capture/3,
|
||||
await_payment_capture/4,
|
||||
await_payment_capture/5,
|
||||
await_payment_capture_finish/4,
|
||||
await_payment_capture_finish/5,
|
||||
await_payment_capture_finish/6,
|
||||
await_payment_cash_flow/3,
|
||||
await_payment_process_finish/3,
|
||||
construct_ta_context/3,
|
||||
convert_transaction_account/2,
|
||||
get_cashflow_volume/4,
|
||||
make_wallet_payment_params/1,
|
||||
execute_payment/3,
|
||||
process_payment/3,
|
||||
make_cash/1,
|
||||
make_cash/2,
|
||||
make_customer_w_rec_tool/4
|
||||
]).
|
||||
|
||||
cfg(Key, C) ->
|
||||
hg_ct_helper:cfg(Key, C).
|
||||
|
||||
%% init helpers
|
||||
-spec start_kv_store(_) -> _.
|
||||
start_kv_store(SupPid) ->
|
||||
ChildSpec = #{
|
||||
id => hg_kv_store,
|
||||
start => {hg_kv_store, start_link, [[]]},
|
||||
restart => permanent,
|
||||
shutdown => 2000,
|
||||
type => worker,
|
||||
modules => [hg_kv_store]
|
||||
},
|
||||
{ok, _} = supervisor:start_child(SupPid, ChildSpec),
|
||||
ok.
|
||||
|
||||
-spec stop_kv_store(_) -> _.
|
||||
stop_kv_store(SupPid) ->
|
||||
_ = supervisor:terminate_child(SupPid, hg_kv_store),
|
||||
ok.
|
||||
|
||||
-spec start_proxies(_) -> _.
|
||||
start_proxies(Proxies) ->
|
||||
setup_proxies(
|
||||
lists:map(
|
||||
fun
|
||||
Mapper({Module, ProxyID, Context}) ->
|
||||
Mapper({Module, ProxyID, #{}, Context});
|
||||
Mapper({Module, ProxyID, ProxyOpts, Context}) ->
|
||||
construct_proxy(ProxyID, start_service_handler(Module, Context, #{}), ProxyOpts)
|
||||
end,
|
||||
Proxies
|
||||
)
|
||||
).
|
||||
|
||||
start_service_handler(Module, C, HandlerOpts) ->
|
||||
start_service_handler(Module, Module, C, HandlerOpts).
|
||||
|
||||
start_service_handler(Name, Module, C, HandlerOpts) ->
|
||||
IP = "127.0.0.1",
|
||||
Port = get_random_port(),
|
||||
Opts = maps:merge(HandlerOpts, #{hellgate_root_url => hg_ct_helper:cfg(root_url, C)}),
|
||||
ChildSpec = hg_test_proxy:get_child_spec(Name, Module, IP, Port, Opts),
|
||||
{ok, _} = supervisor:start_child(hg_ct_helper:cfg(test_sup, C), ChildSpec),
|
||||
hg_test_proxy:get_url(Module, IP, Port).
|
||||
|
||||
setup_proxies(Proxies) ->
|
||||
_ = hg_domain:upsert(Proxies),
|
||||
ok.
|
||||
|
||||
construct_proxy(ID, Url, Options) ->
|
||||
{proxy, #domain_ProxyObject{
|
||||
ref = ?prx(ID),
|
||||
data = #domain_ProxyDefinition{
|
||||
name = Url,
|
||||
description = Url,
|
||||
url = Url,
|
||||
options = Options
|
||||
}
|
||||
}}.
|
||||
|
||||
get_random_port() ->
|
||||
rand:uniform(32768) + 32767.
|
||||
|
||||
%% Test helpers
|
||||
-spec make_due_date(pos_integer()) -> pos_integer().
|
||||
make_due_date(LifetimeSeconds) ->
|
||||
genlib_time:unow() + LifetimeSeconds.
|
||||
|
||||
-spec make_cash(_) -> _.
|
||||
make_cash(Amount) ->
|
||||
make_cash(Amount, <<"RUB">>).
|
||||
|
||||
-spec make_cash(_, _) -> _.
|
||||
make_cash(Amount, Currency) ->
|
||||
hg_ct_helper:make_cash(Amount, Currency).
|
||||
|
||||
make_invoice_params(PartyID, ShopID, Product, Due, Cost) ->
|
||||
hg_ct_helper:make_invoice_params(PartyID, ShopID, Product, Due, Cost).
|
||||
|
||||
-spec start_invoice(_, _, _, _) -> _.
|
||||
start_invoice(Product, Due, Amount, C) ->
|
||||
start_invoice(cfg(shop_id, C), Product, Due, Amount, C).
|
||||
|
||||
-spec start_invoice(_, _, _, _, _) -> _.
|
||||
start_invoice(ShopID, Product, Due, Amount, C) ->
|
||||
Client = cfg(client, C),
|
||||
PartyID = cfg(party_id, C),
|
||||
start_invoice(PartyID, ShopID, Product, Due, Amount, Client).
|
||||
|
||||
-spec start_invoice(_, _, _, _, _, _) -> _.
|
||||
start_invoice(PartyID, ShopID, Product, Due, Amount, Client) ->
|
||||
InvoiceParams = make_invoice_params(PartyID, ShopID, Product, Due, make_cash(Amount)),
|
||||
InvoiceID = create_invoice(InvoiceParams, Client),
|
||||
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),
|
||||
InvoiceID.
|
||||
|
||||
create_invoice(InvoiceParams, Client) ->
|
||||
?invoice_state(?invoice(InvoiceID)) = hg_client_invoicing:create(InvoiceParams, Client),
|
||||
InvoiceID.
|
||||
|
||||
-spec next_change(_, _) -> _.
|
||||
next_change(InvoiceID, Client) ->
|
||||
%% timeout should be at least as large as hold expiration in construct_domain_fixture/0
|
||||
next_change(InvoiceID, ?DEFAULT_NEXT_CHANGE_TIMEOUT, Client).
|
||||
|
||||
-spec next_change(_, _, _) -> _.
|
||||
next_change(InvoiceID, Timeout, Client) ->
|
||||
hg_client_invoicing:pull_change(InvoiceID, fun filter_change/1, Timeout, Client).
|
||||
|
||||
filter_change(?payment_ev(_, C)) ->
|
||||
filter_change(C);
|
||||
filter_change(?chargeback_ev(_, C)) ->
|
||||
filter_change(C);
|
||||
filter_change(?refund_ev(_, C)) ->
|
||||
filter_change(C);
|
||||
filter_change(?session_ev(_, ?proxy_st_changed(_))) ->
|
||||
false;
|
||||
filter_change(?session_ev(_, ?session_suspended(_, _))) ->
|
||||
false;
|
||||
filter_change(?session_ev(_, ?session_activated())) ->
|
||||
false;
|
||||
filter_change(_) ->
|
||||
true.
|
||||
|
||||
-spec next_changes(_, _, _) -> _.
|
||||
next_changes(InvoiceID, Amount, Client) ->
|
||||
next_changes(InvoiceID, Amount, ?DEFAULT_NEXT_CHANGE_TIMEOUT, Client).
|
||||
|
||||
next_changes(InvoiceID, Amount, Timeout, Client) ->
|
||||
TimeoutTime = erlang:monotonic_time(millisecond) + Timeout,
|
||||
next_changes_(InvoiceID, Amount, TimeoutTime, Client).
|
||||
|
||||
next_changes_(InvoiceID, Amount, Timeout, Client) ->
|
||||
Result = lists:foldl(
|
||||
fun(_N, Acc) ->
|
||||
case erlang:monotonic_time(millisecond) of
|
||||
Time when Time < Timeout ->
|
||||
[next_change(InvoiceID, Client) | Acc];
|
||||
_ ->
|
||||
[{error, timeout} | Acc]
|
||||
end
|
||||
end,
|
||||
[],
|
||||
lists:seq(1, Amount)
|
||||
),
|
||||
lists:reverse(Result).
|
||||
|
||||
-spec make_payment_params(_) -> _.
|
||||
make_payment_params(PmtSys) ->
|
||||
make_payment_params(PmtSys, instant).
|
||||
|
||||
-spec make_payment_params(_, _) -> _.
|
||||
make_payment_params(PmtSys, FlowType) ->
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, PmtSys),
|
||||
make_payment_params(PaymentTool, Session, FlowType).
|
||||
|
||||
-spec make_payment_params(_, _, _) -> _.
|
||||
make_payment_params(PaymentTool, Session, FlowType) ->
|
||||
Flow =
|
||||
case FlowType of
|
||||
instant ->
|
||||
{instant, #payproc_InvoicePaymentParamsFlowInstant{}};
|
||||
{hold, OnHoldExpiration} ->
|
||||
{hold, #payproc_InvoicePaymentParamsFlowHold{on_hold_expiration = OnHoldExpiration}}
|
||||
end,
|
||||
#payproc_InvoicePaymentParams{
|
||||
payer =
|
||||
{payment_resource, #payproc_PaymentResourcePayerParams{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = PaymentTool,
|
||||
payment_session_id = Session,
|
||||
client_info = #domain_ClientInfo{}
|
||||
},
|
||||
contact_info = ?contact_info()
|
||||
}},
|
||||
flow = Flow
|
||||
}.
|
||||
|
||||
-spec register_payment(_, _, _, _) -> _.
|
||||
register_payment(InvoiceID, RegisterPaymentParams, WithRiskScoring, Client) ->
|
||||
?payment_state(?payment(PaymentID)) =
|
||||
hg_client_invoicing:register_payment(InvoiceID, RegisterPaymentParams, Client),
|
||||
_ =
|
||||
case WithRiskScoring of
|
||||
true ->
|
||||
start_payment_ev(InvoiceID, Client);
|
||||
false ->
|
||||
start_payment_ev_no_risk_scoring(InvoiceID, Client)
|
||||
end,
|
||||
?payment_ev(PaymentID, ?cash_flow_changed(_)) =
|
||||
next_change(InvoiceID, Client),
|
||||
PaymentID.
|
||||
|
||||
-spec start_payment(_, _, _) -> _.
|
||||
start_payment(InvoiceID, PaymentParams, Client) ->
|
||||
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||
_ = start_payment_ev(InvoiceID, Client),
|
||||
?payment_ev(PaymentID, ?cash_flow_changed(_)) =
|
||||
next_change(InvoiceID, Client),
|
||||
PaymentID.
|
||||
|
||||
-spec start_payment_ev(_, _) -> _.
|
||||
start_payment_ev(InvoiceID, Client) ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||
?payment_ev(PaymentID, ?risk_score_changed(_RiskScore)),
|
||||
?payment_ev(PaymentID, ?route_changed(Route))
|
||||
] = next_changes(InvoiceID, 3, Client),
|
||||
Route.
|
||||
|
||||
-spec start_payment_ev_no_risk_scoring(_, _) -> _.
|
||||
start_payment_ev_no_risk_scoring(InvoiceID, Client) ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||
?payment_ev(PaymentID, ?route_changed(Route))
|
||||
] = next_changes(InvoiceID, 2, Client),
|
||||
Route.
|
||||
|
||||
-spec await_payment_session_started(_, _, _, _) -> _.
|
||||
await_payment_session_started(InvoiceID, PaymentID, Client, Target) ->
|
||||
?payment_ev(PaymentID, ?session_ev(Target, ?session_started())) =
|
||||
next_change(InvoiceID, Client),
|
||||
PaymentID.
|
||||
|
||||
-spec await_payment_capture(_, _, _) -> _.
|
||||
await_payment_capture(InvoiceID, PaymentID, Client) ->
|
||||
await_payment_capture(InvoiceID, PaymentID, ?timeout_reason(), Client).
|
||||
|
||||
-spec await_payment_capture(_, _, _, _) -> _.
|
||||
await_payment_capture(InvoiceID, PaymentID, Reason, Client) ->
|
||||
await_payment_capture(InvoiceID, PaymentID, Reason, undefined, Client).
|
||||
|
||||
-spec await_payment_capture(_, _, _, _, _) -> _.
|
||||
await_payment_capture(InvoiceID, PaymentID, Reason, TrxID, Client) ->
|
||||
Cost = get_payment_cost(InvoiceID, PaymentID, Client),
|
||||
[
|
||||
?payment_ev(PaymentID, ?payment_capture_started(Reason, Cost, _, _)),
|
||||
?payment_ev(PaymentID, ?session_ev(?captured(Reason, Cost), ?session_started()))
|
||||
] = next_changes(InvoiceID, 2, Client),
|
||||
TrxID =/= undefined andalso
|
||||
(?payment_ev(PaymentID, ?session_ev(?captured(Reason, Cost, _Cart, _), ?trx_bound(?trx_info(TrxID)))) =
|
||||
next_change(InvoiceID, Client)),
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Client).
|
||||
|
||||
get_payment_cost(InvoiceID, PaymentID, Client) ->
|
||||
#payproc_InvoicePayment{
|
||||
payment = #domain_InvoicePayment{cost = Cost}
|
||||
} = hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client),
|
||||
Cost.
|
||||
|
||||
-spec await_payment_capture_finish(_, _, _, _) -> _.
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Client) ->
|
||||
Cost = get_payment_cost(InvoiceID, PaymentID, Client),
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, Client).
|
||||
|
||||
-spec await_payment_capture_finish(_, _, _, _, _) -> _.
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, Client) ->
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, undefined, Client).
|
||||
|
||||
-spec await_payment_capture_finish(_, _, _, _, _, _) -> _.
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, Cart, Client) ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?session_ev(?captured(Reason, Cost, Cart, _), ?session_finished(?session_succeeded()))),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?captured(Reason, Cost, Cart, _))),
|
||||
?invoice_status_changed(?invoice_paid())
|
||||
] = next_changes(InvoiceID, 3, Client),
|
||||
PaymentID.
|
||||
|
||||
-spec await_payment_cash_flow(_, _, _) -> _.
|
||||
await_payment_cash_flow(InvoiceID, PaymentID, Client) ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?risk_score_changed(_)),
|
||||
?payment_ev(PaymentID, ?route_changed(Route)),
|
||||
?payment_ev(PaymentID, ?cash_flow_changed(CashFlow))
|
||||
] = next_changes(InvoiceID, 3, Client),
|
||||
{CashFlow, Route}.
|
||||
|
||||
-spec construct_ta_context(_, _, _) -> _.
|
||||
construct_ta_context(Party, Shop, Route) ->
|
||||
#{
|
||||
party => Party,
|
||||
shop => Shop,
|
||||
route => Route
|
||||
}.
|
||||
|
||||
-spec get_cashflow_volume(_, _, _, _) -> _.
|
||||
get_cashflow_volume(Source, Destination, CF, CFContext) ->
|
||||
TAS = convert_transaction_account(Source, CFContext),
|
||||
TAD = convert_transaction_account(Destination, CFContext),
|
||||
[Volume] = [
|
||||
V
|
||||
|| #domain_FinalCashFlowPosting{
|
||||
source = #domain_FinalCashFlowAccount{
|
||||
account_type = ST,
|
||||
transaction_account = SA
|
||||
},
|
||||
destination = #domain_FinalCashFlowAccount{
|
||||
account_type = DT,
|
||||
transaction_account = DA
|
||||
},
|
||||
volume = V
|
||||
} <- CF,
|
||||
ST == Source,
|
||||
DT == Destination,
|
||||
SA == TAS,
|
||||
DA == TAD
|
||||
],
|
||||
Volume.
|
||||
|
||||
-spec convert_transaction_account(_, _) -> _.
|
||||
convert_transaction_account({merchant, Type}, #{party := Party, shop := Shop}) ->
|
||||
{merchant, #domain_MerchantTransactionAccount{
|
||||
type = Type,
|
||||
owner = #domain_MerchantTransactionAccountOwner{
|
||||
party_id = Party,
|
||||
shop_id = Shop
|
||||
}
|
||||
}};
|
||||
convert_transaction_account({provider, Type}, #{route := Route}) ->
|
||||
#domain_PaymentRoute{
|
||||
provider = ProviderRef,
|
||||
terminal = TerminalRef
|
||||
} = Route,
|
||||
{provider, #domain_ProviderTransactionAccount{
|
||||
type = Type,
|
||||
owner = #domain_ProviderTransactionAccountOwner{
|
||||
provider_ref = ProviderRef,
|
||||
terminal_ref = TerminalRef
|
||||
}
|
||||
}};
|
||||
convert_transaction_account({system, Type}, _Context) ->
|
||||
{system, #domain_SystemTransactionAccount{
|
||||
type = Type
|
||||
}};
|
||||
convert_transaction_account({external, Type}, _Context) ->
|
||||
{external, #domain_ExternalTransactionAccount{
|
||||
type = Type
|
||||
}}.
|
||||
|
||||
-spec make_wallet_payment_params(_) -> _.
|
||||
make_wallet_payment_params(PmtSrv) ->
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(digital_wallet, PmtSrv),
|
||||
make_payment_params(PaymentTool, Session, instant).
|
||||
|
||||
-spec execute_payment(_, _, _) -> _.
|
||||
execute_payment(InvoiceID, Params, Client) ->
|
||||
PaymentID = process_payment(InvoiceID, Params, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
PaymentID.
|
||||
|
||||
-spec process_payment(_, _, _) -> _.
|
||||
process_payment(InvoiceID, PaymentParams, Client) ->
|
||||
PaymentID = start_payment(InvoiceID, PaymentParams, Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
PaymentID = await_payment_process_finish(InvoiceID, PaymentID, Client).
|
||||
|
||||
-spec await_payment_process_finish(_, _, _) -> _.
|
||||
await_payment_process_finish(InvoiceID, PaymentID, Client) ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?trx_bound(?trx_info(_)))),
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_finished(?session_succeeded()))),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?processed()))
|
||||
] = next_changes(InvoiceID, 3, Client),
|
||||
PaymentID.
|
||||
|
||||
-spec make_customer_w_rec_tool(_, _, _, _) -> _.
|
||||
make_customer_w_rec_tool(PartyID, ShopID, Client, PmtSys) ->
|
||||
CustomerParams = hg_ct_helper:make_customer_params(PartyID, ShopID, <<"InvoicingTests">>),
|
||||
#payproc_Customer{id = CustomerID} =
|
||||
hg_client_customer:create(CustomerParams, Client),
|
||||
#payproc_CustomerBinding{id = BindingID} =
|
||||
hg_client_customer:start_binding(
|
||||
CustomerID,
|
||||
hg_ct_helper:make_customer_binding_params(hg_dummy_provider:make_payment_tool(no_preauth, PmtSys)),
|
||||
Client
|
||||
),
|
||||
ok = wait_for_binding_success(CustomerID, BindingID, Client),
|
||||
CustomerID.
|
||||
|
||||
wait_for_binding_success(CustomerID, BindingID, Client) ->
|
||||
wait_for_binding_success(CustomerID, BindingID, 20000, Client).
|
||||
|
||||
wait_for_binding_success(CustomerID, BindingID, TimeLeft, Client) when TimeLeft > 0 ->
|
||||
Target = ?customer_binding_changed(BindingID, ?customer_binding_status_changed(?customer_binding_succeeded())),
|
||||
Started = genlib_time:ticks(),
|
||||
Event = hg_client_customer:pull_event(CustomerID, Client),
|
||||
R =
|
||||
case Event of
|
||||
{ok, ?customer_event(Changes)} ->
|
||||
lists:member(Target, Changes);
|
||||
_ ->
|
||||
false
|
||||
end,
|
||||
case R of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
timer:sleep(200),
|
||||
Now = genlib_time:ticks(),
|
||||
TimeLeftNext = TimeLeft - (Now - Started) div 1000,
|
||||
wait_for_binding_success(CustomerID, BindingID, TimeLeftNext, Client)
|
||||
end;
|
||||
wait_for_binding_success(_, _, _, _) ->
|
||||
timeout.
|
817
apps/hellgate/test/hg_invoice_lite_tests_SUITE.erl
Normal file
817
apps/hellgate/test/hg_invoice_lite_tests_SUITE.erl
Normal file
@ -0,0 +1,817 @@
|
||||
-module(hg_invoice_lite_tests_SUITE).
|
||||
|
||||
-include("hg_ct_invoice.hrl").
|
||||
-include("hg_ct_domain.hrl").
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
|
||||
-export([all/0]).
|
||||
-export([groups/0]).
|
||||
-export([init_per_suite/1]).
|
||||
-export([end_per_suite/1]).
|
||||
-export([init_per_testcase/2]).
|
||||
-export([end_per_testcase/2]).
|
||||
|
||||
-export([payment_start_idempotency/1]).
|
||||
-export([payment_success/1]).
|
||||
-export([register_payment_success/1]).
|
||||
-export([register_payment_customer_payer_success/1]).
|
||||
-export([payment_success_additional_info/1]).
|
||||
-export([payment_w_mobile_commerce/1]).
|
||||
-export([payment_suspend_timeout_failure/1]).
|
||||
-export([payment_w_crypto_currency_success/1]).
|
||||
-export([payment_w_wallet_success/1]).
|
||||
-export([payment_success_empty_cvv/1]).
|
||||
-export([payment_has_optional_fields/1]).
|
||||
-export([payment_last_trx_correct/1]).
|
||||
|
||||
-type config() :: hg_ct_helper:config().
|
||||
-type test_case_name() :: hg_ct_helper:test_case_name().
|
||||
-type group_name() :: hg_ct_helper:group_name().
|
||||
-type test_return() :: _ | no_return().
|
||||
|
||||
%% Supervisor
|
||||
-behaviour(supervisor).
|
||||
|
||||
-export([init/1]).
|
||||
|
||||
-spec init([]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
|
||||
init([]) ->
|
||||
{ok, {#{strategy => one_for_all, intensity => 1, period => 1}, []}}.
|
||||
|
||||
%% Tests
|
||||
-spec all() -> [test_case_name() | {group, group_name()}].
|
||||
all() ->
|
||||
[
|
||||
{group, payments}
|
||||
].
|
||||
|
||||
-spec groups() -> [{group_name(), list(), [test_case_name()]}].
|
||||
groups() ->
|
||||
[
|
||||
{payments, [parallel], [
|
||||
payment_start_idempotency,
|
||||
payment_success,
|
||||
register_payment_success,
|
||||
register_payment_customer_payer_success,
|
||||
payment_success_additional_info,
|
||||
payment_w_mobile_commerce,
|
||||
payment_suspend_timeout_failure,
|
||||
payment_w_crypto_currency_success,
|
||||
payment_w_wallet_success,
|
||||
payment_success_empty_cvv,
|
||||
payment_has_optional_fields,
|
||||
payment_last_trx_correct
|
||||
]}
|
||||
].
|
||||
|
||||
-spec init_per_suite(config()) -> config().
|
||||
init_per_suite(C) ->
|
||||
CowboySpec = hg_dummy_provider:get_http_cowboy_spec(),
|
||||
{Apps, Ret} = hg_ct_helper:start_apps([
|
||||
woody,
|
||||
scoper,
|
||||
dmt_client,
|
||||
bender_client,
|
||||
party_client,
|
||||
hg_proto,
|
||||
hellgate,
|
||||
{cowboy, CowboySpec},
|
||||
snowflake
|
||||
]),
|
||||
RootUrl = maps:get(hellgate_root_url, Ret),
|
||||
_ = hg_limiter_helper:init_per_suite(C),
|
||||
_ = hg_domain:insert(construct_domain_fixture()),
|
||||
PartyID = hg_utils:unique_id(),
|
||||
PartyClient = {party_client:create_client(), party_client:create_context()},
|
||||
CustomerClient = hg_client_customer:start(hg_ct_helper:create_client(RootUrl)),
|
||||
ShopID = hg_ct_helper:create_party_and_shop(PartyID, ?cat(1), <<"RUB">>, ?tmpl(1), ?pinst(1), PartyClient),
|
||||
{ok, SupPid} = supervisor:start_link(?MODULE, []),
|
||||
_ = unlink(SupPid),
|
||||
ok = hg_invoice_helper:start_kv_store(SupPid),
|
||||
NewC = [
|
||||
{party_id, PartyID},
|
||||
{shop_id, ShopID},
|
||||
{customer_client, CustomerClient},
|
||||
{root_url, RootUrl},
|
||||
{test_sup, SupPid},
|
||||
{apps, Apps}
|
||||
| C
|
||||
],
|
||||
ok = hg_invoice_helper:start_proxies([{hg_dummy_provider, 1, NewC}, {hg_dummy_inspector, 2, NewC}]),
|
||||
NewC.
|
||||
|
||||
-spec end_per_suite(config()) -> _.
|
||||
end_per_suite(C) ->
|
||||
_ = hg_domain:cleanup(),
|
||||
_ = [application:stop(App) || App <- cfg(apps, C)],
|
||||
hg_invoice_helper:stop_kv_store(cfg(test_sup, C)),
|
||||
exit(cfg(test_sup, C), shutdown).
|
||||
|
||||
-spec init_per_testcase(test_case_name(), config()) -> config().
|
||||
init_per_testcase(_, C) ->
|
||||
ApiClient = hg_ct_helper:create_client(hg_ct_helper:cfg(root_url, C)),
|
||||
Client = hg_client_invoicing:start_link(ApiClient),
|
||||
ok = hg_context:save(hg_context:create()),
|
||||
[
|
||||
{client, Client}
|
||||
| C
|
||||
].
|
||||
|
||||
-spec end_per_testcase(test_case_name(), config()) -> config().
|
||||
end_per_testcase(_, C) ->
|
||||
C.
|
||||
|
||||
%% TESTS
|
||||
-spec payment_start_idempotency(config()) -> test_return().
|
||||
payment_start_idempotency(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
PaymentParams0 = make_payment_params(?pmt_sys(<<"visa-ref">>)),
|
||||
PaymentID1 = <<"1">>,
|
||||
ExternalID = <<"42">>,
|
||||
PaymentParams1 = PaymentParams0#payproc_InvoicePaymentParams{
|
||||
id = PaymentID1,
|
||||
external_id = ExternalID
|
||||
},
|
||||
?payment_state(#domain_InvoicePayment{
|
||||
id = PaymentID1,
|
||||
external_id = ExternalID
|
||||
}) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams1, Client),
|
||||
?payment_state(#domain_InvoicePayment{
|
||||
id = PaymentID1,
|
||||
external_id = ExternalID
|
||||
}) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams1, Client),
|
||||
PaymentParams2 = PaymentParams0#payproc_InvoicePaymentParams{id = <<"2">>},
|
||||
{exception, #payproc_InvoicePaymentPending{id = PaymentID1}} =
|
||||
hg_client_invoicing:start_payment(InvoiceID, PaymentParams2, Client),
|
||||
PaymentID1 = execute_payment(InvoiceID, PaymentParams1, Client),
|
||||
?payment_state(#domain_InvoicePayment{
|
||||
id = PaymentID1,
|
||||
external_id = ExternalID
|
||||
}) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams1, Client).
|
||||
|
||||
-spec payment_success(config()) -> test_return().
|
||||
payment_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
Context = #base_Content{
|
||||
type = <<"application/x-erlang-binary">>,
|
||||
data = erlang:term_to_binary({you, 643, "not", [<<"welcome">>, here]})
|
||||
},
|
||||
PayerSessionInfo = #domain_PayerSessionInfo{
|
||||
redirect_url = RedirectURL = <<"https://redirectly.io/merchant">>
|
||||
},
|
||||
PaymentParams = (make_payment_params(?pmt_sys(<<"visa-ref">>)))#payproc_InvoicePaymentParams{
|
||||
payer_session_info = PayerSessionInfo,
|
||||
context = Context
|
||||
},
|
||||
PaymentID = process_payment(InvoiceID, PaymentParams, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
?invoice_state(
|
||||
?invoice_w_status(?invoice_paid()),
|
||||
[PaymentSt = ?payment_state(Payment)]
|
||||
) = hg_client_invoicing:get(InvoiceID, Client),
|
||||
?payment_w_status(PaymentID, ?captured()) = Payment,
|
||||
?payment_last_trx(Trx) = PaymentSt,
|
||||
?assertMatch(
|
||||
#domain_InvoicePayment{
|
||||
payer_session_info = PayerSessionInfo,
|
||||
context = Context
|
||||
},
|
||||
Payment
|
||||
),
|
||||
?assertMatch(
|
||||
#domain_TransactionInfo{
|
||||
extra = #{
|
||||
<<"payment.payer_session_info.redirect_url">> := RedirectURL
|
||||
}
|
||||
},
|
||||
Trx
|
||||
).
|
||||
|
||||
-spec register_payment_success(config()) -> test_return().
|
||||
register_payment_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
Context = #base_Content{
|
||||
type = <<"application/x-erlang-binary">>,
|
||||
data = erlang:term_to_binary({you, 643, "not", [<<"welcome">>, here]})
|
||||
},
|
||||
PayerSessionInfo = #domain_PayerSessionInfo{},
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, ?pmt_sys(<<"visa-ref">>)),
|
||||
Route = ?route(?prv(1), ?trm(1)),
|
||||
Cost = ?cash(41999, <<"RUB">>),
|
||||
ID = hg_utils:unique_id(),
|
||||
ExternalID = hg_utils:unique_id(),
|
||||
TransactionInfo = ?trx_info(<<"1">>, #{}),
|
||||
OccurredAt = hg_datetime:format_now(),
|
||||
PaymentParams = #payproc_RegisterInvoicePaymentParams{
|
||||
payer_params =
|
||||
{payment_resource, #payproc_PaymentResourcePayerParams{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = PaymentTool,
|
||||
payment_session_id = Session,
|
||||
client_info = #domain_ClientInfo{}
|
||||
},
|
||||
contact_info = ?contact_info()
|
||||
}},
|
||||
route = Route,
|
||||
payer_session_info = PayerSessionInfo,
|
||||
context = Context,
|
||||
cost = Cost,
|
||||
id = ID,
|
||||
external_id = ExternalID,
|
||||
transaction_info = TransactionInfo,
|
||||
risk_score = high,
|
||||
occurred_at = OccurredAt
|
||||
},
|
||||
PaymentID = register_payment(InvoiceID, PaymentParams, true, Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
PaymentID = await_payment_process_finish(InvoiceID, PaymentID, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
?invoice_state(?invoice_w_status(?invoice_paid())) =
|
||||
hg_client_invoicing:get(InvoiceID, Client),
|
||||
PaymentSt = hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client),
|
||||
|
||||
?payment_route(Route) = PaymentSt,
|
||||
?payment_last_trx(TransactionInfo) = PaymentSt,
|
||||
?payment_state(Payment) = PaymentSt,
|
||||
?payment_w_status(PaymentID, ?captured()) = Payment,
|
||||
?assertMatch(
|
||||
#domain_InvoicePayment{
|
||||
id = ID,
|
||||
payer_session_info = PayerSessionInfo,
|
||||
context = Context,
|
||||
flow = ?invoice_payment_flow_instant(),
|
||||
cost = Cost,
|
||||
external_id = ExternalID
|
||||
},
|
||||
Payment
|
||||
).
|
||||
|
||||
-spec register_payment_customer_payer_success(config()) -> test_return().
|
||||
register_payment_customer_payer_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
Route = ?route(?prv(1), ?trm(1)),
|
||||
CustomerID = make_customer_w_rec_tool(
|
||||
cfg(party_id, C), cfg(shop_id, C), cfg(customer_client, C), ?pmt_sys(<<"visa-ref">>)
|
||||
),
|
||||
PaymentParams = #payproc_RegisterInvoicePaymentParams{
|
||||
payer_params =
|
||||
{customer, #payproc_CustomerPayerParams{
|
||||
customer_id = CustomerID
|
||||
}},
|
||||
route = Route,
|
||||
transaction_info = ?trx_info(<<"1">>, #{})
|
||||
},
|
||||
PaymentID = register_payment(InvoiceID, PaymentParams, false, Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
PaymentID = await_payment_process_finish(InvoiceID, PaymentID, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
?invoice_state(?invoice_w_status(?invoice_paid())) =
|
||||
hg_client_invoicing:get(InvoiceID, Client).
|
||||
|
||||
-spec payment_success_additional_info(config()) -> test_return().
|
||||
payment_success_additional_info(C) ->
|
||||
Client = hg_ct_helper:cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(empty_cvv, ?pmt_sys(<<"visa-ref">>)),
|
||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||
PaymentID = start_payment(InvoiceID, PaymentParams, Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
|
||||
[
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?trx_bound(Trx))),
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_finished(?session_succeeded())))
|
||||
] = next_changes(InvoiceID, 2, Client),
|
||||
%% Check additional info
|
||||
AdditionalInfo = hg_ct_fixture:construct_dummy_additional_info(),
|
||||
#domain_TransactionInfo{additional_info = AdditionalInfo} = Trx,
|
||||
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?processed())) =
|
||||
next_change(InvoiceID, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
?invoice_state(
|
||||
?invoice_w_status(?invoice_paid()),
|
||||
[?payment_state(?payment_w_status(PaymentID, ?captured()))]
|
||||
) = hg_client_invoicing:get(InvoiceID, Client).
|
||||
|
||||
-spec payment_w_mobile_commerce(config()) -> _ | no_return().
|
||||
payment_w_mobile_commerce(C) ->
|
||||
payment_w_mobile_commerce(C, success).
|
||||
|
||||
-spec payment_suspend_timeout_failure(config()) -> _ | no_return().
|
||||
payment_suspend_timeout_failure(C) ->
|
||||
payment_w_mobile_commerce(C, failure).
|
||||
|
||||
payment_w_mobile_commerce(C, Expectation) ->
|
||||
Client = cfg(client, C),
|
||||
PayCash = 1001,
|
||||
InvoiceID = start_invoice(<<"oatmeal">>, make_due_date(10), PayCash, C),
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool({mobile_commerce, Expectation}, ?mob(<<"mts-ref">>)),
|
||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
||||
next_change(InvoiceID, Client),
|
||||
_ = await_payment_cash_flow(InvoiceID, PaymentID, Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
case Expectation of
|
||||
success ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_finished(?session_succeeded()))),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?processed()))
|
||||
] =
|
||||
next_changes(InvoiceID, 2, Client);
|
||||
failure ->
|
||||
[
|
||||
?payment_ev(
|
||||
PaymentID,
|
||||
?session_ev(?processed(), ?session_finished(?session_failed({failure, Failure})))
|
||||
),
|
||||
?payment_ev(PaymentID, ?payment_rollback_started({failure, Failure})),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?failed({failure, Failure})))
|
||||
] =
|
||||
next_changes(InvoiceID, 3, Client)
|
||||
end.
|
||||
|
||||
-spec payment_w_crypto_currency_success(config()) -> _ | no_return().
|
||||
payment_w_crypto_currency_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
PayCash = 2000,
|
||||
InvoiceID = start_invoice(<<"cryptoduck">>, make_due_date(10), PayCash, C),
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(crypto_currency, ?crypta(<<"bitcoin-ref">>)),
|
||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||
?payment_state(#domain_InvoicePayment{
|
||||
id = PaymentID,
|
||||
owner_id = PartyID,
|
||||
shop_id = ShopID
|
||||
}) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
||||
next_change(InvoiceID, Client),
|
||||
{CF, Route} = await_payment_cash_flow(InvoiceID, PaymentID, Client),
|
||||
CFContext = construct_ta_context(PartyID, ShopID, Route),
|
||||
?cash(PayCash, <<"RUB">>) = get_cashflow_volume({provider, settlement}, {merchant, settlement}, CF, CFContext),
|
||||
?cash(36, <<"RUB">>) = get_cashflow_volume({system, settlement}, {provider, settlement}, CF, CFContext),
|
||||
?cash(90, <<"RUB">>) = get_cashflow_volume({merchant, settlement}, {system, settlement}, CF, CFContext).
|
||||
|
||||
-spec payment_w_wallet_success(config()) -> _ | no_return().
|
||||
payment_w_wallet_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"bubbleblob">>, make_due_date(10), 42000, C),
|
||||
PaymentParams = make_wallet_payment_params(?pmt_srv(<<"qiwi-ref">>)),
|
||||
PaymentID = execute_payment(InvoiceID, PaymentParams, Client),
|
||||
?invoice_state(
|
||||
?invoice_w_status(?invoice_paid()),
|
||||
[?payment_state(?payment_w_status(PaymentID, ?captured()))]
|
||||
) = hg_client_invoicing:get(InvoiceID, Client).
|
||||
|
||||
-spec payment_success_empty_cvv(config()) -> test_return().
|
||||
payment_success_empty_cvv(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(empty_cvv, ?pmt_sys(<<"visa-ref">>)),
|
||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||
PaymentID = execute_payment(InvoiceID, PaymentParams, Client),
|
||||
?invoice_state(
|
||||
?invoice_w_status(?invoice_paid()),
|
||||
[?payment_state(?payment_w_status(PaymentID, ?captured()))]
|
||||
) = hg_client_invoicing:get(InvoiceID, Client).
|
||||
|
||||
-spec payment_has_optional_fields(config()) -> test_return().
|
||||
payment_has_optional_fields(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
PaymentParams = make_payment_params(?pmt_sys(<<"visa-ref">>)),
|
||||
PaymentID = execute_payment(InvoiceID, PaymentParams, Client),
|
||||
InvoicePayment = hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client),
|
||||
?payment_state(Payment) = InvoicePayment,
|
||||
?payment_route(Route) = InvoicePayment,
|
||||
?payment_cashflow(CashFlow) = InvoicePayment,
|
||||
?payment_last_trx(TrxInfo) = InvoicePayment,
|
||||
PartyID = cfg(party_id, C),
|
||||
ShopID = cfg(shop_id, C),
|
||||
#domain_InvoicePayment{owner_id = PartyID, shop_id = ShopID} = Payment,
|
||||
false = Route =:= undefined,
|
||||
false = CashFlow =:= undefined,
|
||||
false = TrxInfo =:= undefined.
|
||||
|
||||
-spec payment_last_trx_correct(config()) -> _ | no_return().
|
||||
payment_last_trx_correct(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
PaymentID = start_payment(InvoiceID, make_payment_params(?pmt_sys(<<"visa-ref">>)), Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
[
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?trx_bound(TrxInfo0))),
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_finished(?session_succeeded()))),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?processed()))
|
||||
] = next_changes(InvoiceID, 3, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
?payment_last_trx(TrxInfo0) = hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Internals
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
cfg(Key, Config) ->
|
||||
hg_ct_helper:cfg(Key, Config).
|
||||
|
||||
make_due_date(LifetimeSeconds) ->
|
||||
hg_invoice_helper:make_due_date(LifetimeSeconds).
|
||||
|
||||
start_invoice(Product, Due, Amount, Client) ->
|
||||
hg_invoice_helper:start_invoice(Product, Due, Amount, Client).
|
||||
|
||||
make_payment_params(PmtSys) ->
|
||||
hg_invoice_helper:make_payment_params(PmtSys).
|
||||
|
||||
make_payment_params(PaymentTool, Session, FlowType) ->
|
||||
hg_invoice_helper:make_payment_params(PaymentTool, Session, FlowType).
|
||||
|
||||
register_payment(InvoiceID, RegisterPaymentParams, WithRiskScoring, Client) ->
|
||||
hg_invoice_helper:register_payment(InvoiceID, RegisterPaymentParams, WithRiskScoring, Client).
|
||||
|
||||
start_payment(InvoiceID, PaymentParams, Client) ->
|
||||
hg_invoice_helper:start_payment(InvoiceID, PaymentParams, Client).
|
||||
|
||||
process_payment(InvoiceID, PaymentParams, Client) ->
|
||||
hg_invoice_helper:process_payment(InvoiceID, PaymentParams, Client).
|
||||
|
||||
await_payment_session_started(InvoiceID, PaymentID, Client, Target) ->
|
||||
hg_invoice_helper:await_payment_session_started(InvoiceID, PaymentID, Client, Target).
|
||||
|
||||
await_payment_process_finish(InvoiceID, PaymentID, Client) ->
|
||||
hg_invoice_helper:await_payment_process_finish(InvoiceID, PaymentID, Client).
|
||||
|
||||
next_changes(InvoiceID, Amount, Client) ->
|
||||
hg_invoice_helper:next_changes(InvoiceID, Amount, Client).
|
||||
|
||||
next_change(InvoiceID, Client) ->
|
||||
hg_invoice_helper:next_change(InvoiceID, Client).
|
||||
|
||||
await_payment_capture(InvoiceID, PaymentID, Client) ->
|
||||
hg_invoice_helper:await_payment_capture(InvoiceID, PaymentID, Client).
|
||||
|
||||
await_payment_cash_flow(InvoiceID, PaymentID, Client) ->
|
||||
hg_invoice_helper:await_payment_cash_flow(InvoiceID, PaymentID, Client).
|
||||
|
||||
construct_ta_context(PartyID, ShopID, Route) ->
|
||||
hg_invoice_helper:construct_ta_context(PartyID, ShopID, Route).
|
||||
|
||||
get_cashflow_volume(Source, Destination, CF, CFContext) ->
|
||||
hg_invoice_helper:get_cashflow_volume(Source, Destination, CF, CFContext).
|
||||
|
||||
make_wallet_payment_params(PmtSrv) ->
|
||||
hg_invoice_helper:make_wallet_payment_params(PmtSrv).
|
||||
|
||||
execute_payment(InvoiceID, PaymentParams, Client) ->
|
||||
hg_invoice_helper:execute_payment(InvoiceID, PaymentParams, Client).
|
||||
|
||||
make_customer_w_rec_tool(PartyID, ShopID, Client, PmtSys) ->
|
||||
hg_invoice_helper:make_customer_w_rec_tool(PartyID, ShopID, Client, PmtSys).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% CONFIG
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
-define(merchant_to_system_share_1, ?share(45, 1000, operation_amount)).
|
||||
|
||||
-spec construct_domain_fixture() -> _.
|
||||
construct_domain_fixture() ->
|
||||
TestTermSet = #domain_TermSet{
|
||||
payments = #domain_PaymentsServiceTerms{
|
||||
currencies =
|
||||
{value,
|
||||
?ordset([
|
||||
?cur(<<"RUB">>)
|
||||
])},
|
||||
categories =
|
||||
{value,
|
||||
?ordset([
|
||||
?cat(1),
|
||||
?cat(2)
|
||||
])},
|
||||
payment_methods =
|
||||
{decisions, [
|
||||
#domain_PaymentMethodDecision{
|
||||
if_ = {constant, true},
|
||||
then_ =
|
||||
{value,
|
||||
?ordset([
|
||||
?pmt(mobile, ?mob(<<"mts-ref">>)),
|
||||
?pmt(digital_wallet, ?pmt_srv(<<"qiwi-ref">>)),
|
||||
?pmt(crypto_currency, ?crypta(<<"bitcoin-ref">>)),
|
||||
?pmt(bank_card, ?bank_card_no_cvv(<<"visa-ref">>)),
|
||||
?pmt(bank_card, ?bank_card(<<"visa-ref">>))
|
||||
])}
|
||||
}
|
||||
]},
|
||||
cash_limit =
|
||||
{decisions, [
|
||||
#domain_CashLimitDecision{
|
||||
if_ = {condition, {currency_is, ?cur(<<"RUB">>)}},
|
||||
then_ =
|
||||
{value,
|
||||
?cashrng(
|
||||
{inclusive, ?cash(10, <<"RUB">>)},
|
||||
{exclusive, ?cash(420000000, <<"RUB">>)}
|
||||
)}
|
||||
}
|
||||
]},
|
||||
fees =
|
||||
{decisions, [
|
||||
#domain_CashFlowDecision{
|
||||
if_ = {condition, {currency_is, ?cur(<<"RUB">>)}},
|
||||
then_ =
|
||||
{value, [
|
||||
?cfpost(
|
||||
{merchant, settlement},
|
||||
{system, settlement},
|
||||
?merchant_to_system_share_1
|
||||
)
|
||||
]}
|
||||
}
|
||||
]},
|
||||
holds = #domain_PaymentHoldsServiceTerms{
|
||||
payment_methods =
|
||||
{value,
|
||||
?ordset([
|
||||
?pmt(bank_card, ?bank_card(<<"visa-ref">>))
|
||||
])},
|
||||
lifetime =
|
||||
{decisions, [
|
||||
#domain_HoldLifetimeDecision{
|
||||
if_ = {condition, {currency_is, ?cur(<<"RUB">>)}},
|
||||
then_ = {value, #domain_HoldLifetime{seconds = 10}}
|
||||
}
|
||||
]}
|
||||
},
|
||||
refunds = #domain_PaymentRefundsServiceTerms{
|
||||
payment_methods =
|
||||
{value,
|
||||
?ordset([
|
||||
?pmt(bank_card, ?bank_card(<<"visa-ref">>))
|
||||
])},
|
||||
fees =
|
||||
{value, [
|
||||
?cfpost(
|
||||
{merchant, settlement},
|
||||
{system, settlement},
|
||||
?fixed(100, <<"RUB">>)
|
||||
)
|
||||
]},
|
||||
eligibility_time = {value, #base_TimeSpan{minutes = 1}},
|
||||
partial_refunds = #domain_PartialRefundsServiceTerms{
|
||||
cash_limit =
|
||||
{decisions, [
|
||||
#domain_CashLimitDecision{
|
||||
if_ = {condition, {currency_is, ?cur(<<"RUB">>)}},
|
||||
then_ =
|
||||
{value,
|
||||
?cashrng(
|
||||
{inclusive, ?cash(1000, <<"RUB">>)},
|
||||
{exclusive, ?cash(1000000000, <<"RUB">>)}
|
||||
)}
|
||||
}
|
||||
]}
|
||||
}
|
||||
},
|
||||
allocations = #domain_PaymentAllocationServiceTerms{
|
||||
allow = {constant, true}
|
||||
},
|
||||
attempt_limit = {value, #domain_AttemptLimit{attempts = 2}}
|
||||
},
|
||||
recurrent_paytools = #domain_RecurrentPaytoolsServiceTerms{
|
||||
payment_methods =
|
||||
{value,
|
||||
ordsets:from_list([
|
||||
?pmt(bank_card, ?bank_card(<<"visa-ref">>))
|
||||
])}
|
||||
}
|
||||
},
|
||||
[
|
||||
hg_ct_fixture:construct_bank_card_category(
|
||||
?bc_cat(1),
|
||||
<<"Bank card category">>,
|
||||
<<"Corporative">>,
|
||||
[<<"*CORPORAT*">>]
|
||||
),
|
||||
|
||||
hg_ct_fixture:construct_currency(?cur(<<"RUB">>)),
|
||||
|
||||
hg_ct_fixture:construct_category(?cat(1), <<"Test category">>, test),
|
||||
hg_ct_fixture:construct_category(?cat(2), <<"Generic Store">>, live),
|
||||
|
||||
hg_ct_fixture:construct_payment_method(?pmt(mobile, ?mob(<<"mts-ref">>))),
|
||||
hg_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"visa-ref">>))),
|
||||
hg_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card_no_cvv(<<"visa-ref">>))),
|
||||
hg_ct_fixture:construct_payment_method(?pmt(crypto_currency, ?crypta(<<"bitcoin-ref">>))),
|
||||
hg_ct_fixture:construct_payment_method(?pmt(digital_wallet, ?pmt_srv(<<"qiwi-ref">>))),
|
||||
|
||||
hg_ct_fixture:construct_proxy(?prx(1), <<"Dummy proxy">>),
|
||||
hg_ct_fixture:construct_proxy(?prx(2), <<"Inspector proxy">>),
|
||||
|
||||
hg_ct_fixture:construct_inspector(?insp(1), <<"Rejector">>, ?prx(2), #{<<"risk_score">> => <<"low">>}),
|
||||
|
||||
hg_ct_fixture:construct_contract_template(?tmpl(1), ?trms(1)),
|
||||
|
||||
hg_ct_fixture:construct_system_account_set(?sas(1)),
|
||||
hg_ct_fixture:construct_external_account_set(?eas(1)),
|
||||
|
||||
hg_ct_fixture:construct_payment_routing_ruleset(
|
||||
?ruleset(1),
|
||||
<<"Policies">>,
|
||||
{candidates, [
|
||||
?candidate({constant, true}, ?trm(1))
|
||||
]}
|
||||
),
|
||||
hg_ct_fixture:construct_payment_routing_ruleset(
|
||||
?ruleset(3),
|
||||
<<"Prohibitions">>,
|
||||
{candidates, []}
|
||||
),
|
||||
|
||||
{payment_institution, #domain_PaymentInstitutionObject{
|
||||
ref = ?pinst(1),
|
||||
data = #domain_PaymentInstitution{
|
||||
name = <<"Test Inc.">>,
|
||||
system_account_set = {value, ?sas(1)},
|
||||
default_contract_template = {value, ?tmpl(1)},
|
||||
providers =
|
||||
{value,
|
||||
?ordset([
|
||||
?prv(1)
|
||||
])},
|
||||
payment_routing_rules = #domain_RoutingRules{
|
||||
policies = ?ruleset(1),
|
||||
prohibitions = ?ruleset(3)
|
||||
},
|
||||
inspector =
|
||||
{decisions, [
|
||||
#domain_InspectorDecision{
|
||||
if_ = {condition, {category_is, ?cat(1)}},
|
||||
then_ = {value, ?insp(1)}
|
||||
},
|
||||
#domain_InspectorDecision{
|
||||
if_ = {condition, {category_is, ?cat(2)}},
|
||||
then_ = {value, ?insp(1)}
|
||||
}
|
||||
]},
|
||||
residences = [],
|
||||
realm = test
|
||||
}
|
||||
}},
|
||||
|
||||
{globals, #domain_GlobalsObject{
|
||||
ref = #domain_GlobalsRef{},
|
||||
data = #domain_Globals{
|
||||
external_account_set =
|
||||
{decisions, [
|
||||
#domain_ExternalAccountSetDecision{
|
||||
if_ = {constant, true},
|
||||
then_ = {value, ?eas(1)}
|
||||
}
|
||||
]},
|
||||
payment_institutions = ?ordset([?pinst(1)])
|
||||
}
|
||||
}},
|
||||
|
||||
{term_set_hierarchy, #domain_TermSetHierarchyObject{
|
||||
ref = ?trms(1),
|
||||
data = #domain_TermSetHierarchy{
|
||||
term_sets = [
|
||||
#domain_TimedTermSet{
|
||||
action_time = #base_TimestampInterval{},
|
||||
terms = TestTermSet
|
||||
}
|
||||
]
|
||||
}
|
||||
}},
|
||||
|
||||
{provider, #domain_ProviderObject{
|
||||
ref = ?prv(1),
|
||||
data = #domain_Provider{
|
||||
name = <<"Brovider">>,
|
||||
description = <<"A provider but bro">>,
|
||||
proxy = #domain_Proxy{
|
||||
ref = ?prx(1),
|
||||
additional = #{
|
||||
<<"override">> => <<"brovider">>
|
||||
}
|
||||
},
|
||||
abs_account = <<"1234567890">>,
|
||||
accounts = hg_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]),
|
||||
terms = #domain_ProvisionTermSet{
|
||||
payments = #domain_PaymentsProvisionTerms{
|
||||
currencies =
|
||||
{value,
|
||||
?ordset([
|
||||
?cur(<<"RUB">>)
|
||||
])},
|
||||
categories =
|
||||
{value,
|
||||
?ordset([
|
||||
?cat(1),
|
||||
?cat(2)
|
||||
])},
|
||||
payment_methods =
|
||||
{value,
|
||||
?ordset([
|
||||
?pmt(mobile, ?mob(<<"mts-ref">>)),
|
||||
?pmt(digital_wallet, ?pmt_srv(<<"qiwi-ref">>)),
|
||||
?pmt(bank_card, ?bank_card_no_cvv(<<"visa-ref">>)),
|
||||
?pmt(bank_card, ?bank_card(<<"visa-ref">>)),
|
||||
?pmt(crypto_currency, ?crypta(<<"bitcoin-ref">>))
|
||||
])},
|
||||
cash_limit =
|
||||
{value,
|
||||
?cashrng(
|
||||
{inclusive, ?cash(1000, <<"RUB">>)},
|
||||
{exclusive, ?cash(1000000000, <<"RUB">>)}
|
||||
)},
|
||||
cash_flow =
|
||||
{value, [
|
||||
?cfpost(
|
||||
{provider, settlement},
|
||||
{merchant, settlement},
|
||||
?share(1, 1, operation_amount)
|
||||
),
|
||||
?cfpost(
|
||||
{system, settlement},
|
||||
{provider, settlement},
|
||||
?share(18, 1000, operation_amount)
|
||||
)
|
||||
]},
|
||||
holds = #domain_PaymentHoldsProvisionTerms{
|
||||
lifetime =
|
||||
{decisions, [
|
||||
#domain_HoldLifetimeDecision{
|
||||
if_ =
|
||||
{condition,
|
||||
{payment_tool,
|
||||
{bank_card, #domain_BankCardCondition{
|
||||
definition =
|
||||
{payment_system, #domain_PaymentSystemCondition{
|
||||
payment_system_is = ?pmt_sys(<<"visa-ref">>)
|
||||
}}
|
||||
}}}},
|
||||
then_ = {value, ?hold_lifetime(12)}
|
||||
}
|
||||
]}
|
||||
},
|
||||
refunds = #domain_PaymentRefundsProvisionTerms{
|
||||
cash_flow =
|
||||
{value, [
|
||||
?cfpost(
|
||||
{merchant, settlement},
|
||||
{provider, settlement},
|
||||
?share(1, 1, operation_amount)
|
||||
)
|
||||
]},
|
||||
partial_refunds = #domain_PartialRefundsProvisionTerms{
|
||||
cash_limit =
|
||||
{value,
|
||||
?cashrng(
|
||||
{inclusive, ?cash(10, <<"RUB">>)},
|
||||
{exclusive, ?cash(1000000000, <<"RUB">>)}
|
||||
)}
|
||||
}
|
||||
},
|
||||
chargebacks = #domain_PaymentChargebackProvisionTerms{
|
||||
cash_flow =
|
||||
{value, [
|
||||
?cfpost(
|
||||
{merchant, settlement},
|
||||
{provider, settlement},
|
||||
?share(1, 1, operation_amount)
|
||||
)
|
||||
]}
|
||||
}
|
||||
},
|
||||
recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{
|
||||
categories = {value, ?ordset([?cat(1), ?cat(2)])},
|
||||
payment_methods =
|
||||
{value,
|
||||
?ordset([
|
||||
?pmt(bank_card, ?bank_card(<<"visa-ref">>))
|
||||
])},
|
||||
cash_value = {value, ?cash(1000, <<"RUB">>)}
|
||||
}
|
||||
}
|
||||
}
|
||||
}},
|
||||
{terminal, #domain_TerminalObject{
|
||||
ref = ?trm(1),
|
||||
data = #domain_Terminal{
|
||||
name = <<"Brominal 1">>,
|
||||
description = <<"Brominal 1">>,
|
||||
provider_ref = ?prv(1)
|
||||
}
|
||||
}},
|
||||
|
||||
hg_ct_fixture:construct_mobile_operator(?mob(<<"mts-ref">>), <<"mts mobile operator">>),
|
||||
hg_ct_fixture:construct_payment_service(?pmt_srv(<<"qiwi-ref">>), <<"qiwi payment service">>),
|
||||
hg_ct_fixture:construct_payment_system(?pmt_sys(<<"visa-ref">>), <<"visa payment system">>),
|
||||
hg_ct_fixture:construct_crypto_currency(?crypta(<<"bitcoin-ref">>), <<"bitcoin currency">>)
|
||||
].
|
@ -5,6 +5,7 @@
|
||||
-module(hg_invoice_tests_SUITE).
|
||||
|
||||
-include("hg_ct_domain.hrl").
|
||||
-include("hg_ct_invoice.hrl").
|
||||
-include_lib("damsel/include/dmsl_repair_thrift.hrl").
|
||||
-include_lib("hellgate/include/allocation.hrl").
|
||||
|
||||
@ -34,11 +35,6 @@
|
||||
-export([invoice_cancellation_after_payment_timeout/1]).
|
||||
-export([invalid_payment_amount/1]).
|
||||
|
||||
-export([payment_start_idempotency/1]).
|
||||
-export([payment_success/1]).
|
||||
-export([register_payment_success/1]).
|
||||
-export([register_payment_customer_payer_success/1]).
|
||||
|
||||
-export([payment_limit_success/1]).
|
||||
-export([payment_routes_limit_values/1]).
|
||||
-export([register_payment_limit_success/1]).
|
||||
@ -54,18 +50,12 @@
|
||||
-export([limit_hold_two_routes_failure/1]).
|
||||
|
||||
-export([processing_deadline_reached_test/1]).
|
||||
-export([payment_success_empty_cvv/1]).
|
||||
-export([payment_success_additional_info/1]).
|
||||
-export([payment_w_terminal_w_payment_service_success/1]).
|
||||
-export([payment_w_crypto_currency_success/1]).
|
||||
-export([payment_bank_card_category_condition/1]).
|
||||
-export([payment_w_wallet_success/1]).
|
||||
-export([payment_w_customer_success/1]).
|
||||
-export([payment_w_another_shop_customer/1]).
|
||||
-export([payment_w_another_party_customer/1]).
|
||||
-export([payment_w_deleted_customer/1]).
|
||||
-export([payment_w_mobile_commerce/1]).
|
||||
-export([payment_suspend_timeout_failure/1]).
|
||||
-export([payments_w_bank_card_issuer_conditions/1]).
|
||||
-export([payments_w_bank_conditions/1]).
|
||||
-export([payment_success_on_second_try/1]).
|
||||
@ -158,8 +148,6 @@
|
||||
-export([payment_with_offsite_preauth_failed/1]).
|
||||
-export([payment_with_tokenized_bank_card/1]).
|
||||
-export([terms_retrieval/1]).
|
||||
-export([payment_has_optional_fields/1]).
|
||||
-export([payment_last_trx_correct/1]).
|
||||
-export([payment_w_misconfigured_routing_failed/1]).
|
||||
-export([payment_capture_failed/1]).
|
||||
-export([payment_capture_retries_exceeded/1]).
|
||||
@ -310,30 +298,18 @@ groups() ->
|
||||
invoice_cancellation_after_payment_timeout,
|
||||
invalid_payment_amount,
|
||||
|
||||
payment_start_idempotency,
|
||||
payment_success,
|
||||
register_payment_success,
|
||||
register_payment_customer_payer_success,
|
||||
payment_success_ruleset,
|
||||
processing_deadline_reached_test,
|
||||
payment_success_empty_cvv,
|
||||
payment_success_additional_info,
|
||||
payment_bank_card_category_condition,
|
||||
payment_w_terminal_w_payment_service_success,
|
||||
payment_w_crypto_currency_success,
|
||||
payment_w_wallet_success,
|
||||
payment_w_customer_success,
|
||||
payment_w_another_shop_customer,
|
||||
payment_w_another_party_customer,
|
||||
payment_w_deleted_customer,
|
||||
payment_w_mobile_commerce,
|
||||
payment_suspend_timeout_failure,
|
||||
payment_success_on_second_try,
|
||||
payment_fail_after_silent_callback,
|
||||
payment_temporary_unavailability_retry_success,
|
||||
payment_temporary_unavailability_too_many_retries,
|
||||
payment_has_optional_fields,
|
||||
payment_last_trx_correct,
|
||||
invoice_success_on_third_payment,
|
||||
payment_w_misconfigured_routing_failed,
|
||||
payment_capture_failed,
|
||||
@ -560,40 +536,11 @@ init_per_suite(C) ->
|
||||
end_per_suite(C) ->
|
||||
_ = hg_domain:cleanup(),
|
||||
_ = [application:stop(App) || App <- cfg(apps, C)],
|
||||
_ = hg_invoice_helper:stop_kv_store(cfg(test_sup, C)),
|
||||
exit(cfg(test_sup, C), shutdown).
|
||||
|
||||
%% tests
|
||||
|
||||
-include("invoice_events.hrl").
|
||||
-include("payment_events.hrl").
|
||||
-include("customer_events.hrl").
|
||||
|
||||
-define(invoice(ID), #domain_Invoice{id = ID}).
|
||||
-define(payment(ID), #domain_InvoicePayment{id = ID}).
|
||||
-define(payment(ID, Revision), #domain_InvoicePayment{id = ID, party_revision = Revision}).
|
||||
-define(adjustment(ID), #domain_InvoicePaymentAdjustment{id = ID}).
|
||||
-define(adjustment(ID, Status), #domain_InvoicePaymentAdjustment{id = ID, status = Status}).
|
||||
-define(adjustment_revision(Revision), #domain_InvoicePaymentAdjustment{party_revision = Revision}).
|
||||
-define(adjustment_reason(Reason), #domain_InvoicePaymentAdjustment{reason = Reason}).
|
||||
-define(invoice_state(Invoice), #payproc_Invoice{invoice = Invoice}).
|
||||
-define(invoice_state(Invoice, Payments), #payproc_Invoice{invoice = Invoice, payments = Payments}).
|
||||
-define(payment_state(Payment), #payproc_InvoicePayment{payment = Payment}).
|
||||
-define(payment_state(Payment, Refunds), #payproc_InvoicePayment{payment = Payment, refunds = Refunds}).
|
||||
-define(payment_route(Route), #payproc_InvoicePayment{route = Route}).
|
||||
-define(refund_state(Refund), #payproc_InvoicePaymentRefund{refund = Refund}).
|
||||
-define(payment_cashflow(CashFlow), #payproc_InvoicePayment{cash_flow = CashFlow}).
|
||||
-define(payment_last_trx(Trx), #payproc_InvoicePayment{last_transaction_info = Trx}).
|
||||
-define(invoice_w_status(Status), #domain_Invoice{status = Status}).
|
||||
-define(invoice_w_revision(Revision), #domain_Invoice{party_revision = Revision}).
|
||||
-define(payment_w_status(Status), #domain_InvoicePayment{status = Status}).
|
||||
-define(payment_w_status(ID, Status), #domain_InvoicePayment{id = ID, status = Status}).
|
||||
-define(invoice_payment_refund(Cash, Status), #domain_InvoicePaymentRefund{cash = Cash, status = Status}).
|
||||
-define(trx_info(ID), #domain_TransactionInfo{id = ID}).
|
||||
-define(trx_info(ID, Extra), #domain_TransactionInfo{id = ID, extra = Extra}).
|
||||
-define(refund_id(RefundID), #domain_InvoicePaymentRefund{id = RefundID}).
|
||||
-define(refund_id(RefundID, ExternalID), #domain_InvoicePaymentRefund{id = RefundID, external_id = ExternalID}).
|
||||
-define(contact_info(), ?contact_info(undefined)).
|
||||
|
||||
-define(invalid_invoice_status(Status),
|
||||
{exception, #payproc_InvalidInvoiceStatus{status = Status}}
|
||||
).
|
||||
@ -1089,156 +1036,6 @@ invalid_payment_amount(C) ->
|
||||
errors = [<<"Invalid amount, more", _/binary>>]
|
||||
}} = hg_client_invoicing:start_payment(InvoiceID2, PaymentParams, Client).
|
||||
|
||||
-spec payment_start_idempotency(config()) -> test_return().
|
||||
payment_start_idempotency(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
PaymentParams0 = make_payment_params(?pmt_sys(<<"visa-ref">>)),
|
||||
PaymentID1 = <<"1">>,
|
||||
ExternalID = <<"42">>,
|
||||
PaymentParams1 = PaymentParams0#payproc_InvoicePaymentParams{
|
||||
id = PaymentID1,
|
||||
external_id = ExternalID
|
||||
},
|
||||
?payment_state(#domain_InvoicePayment{
|
||||
id = PaymentID1,
|
||||
external_id = ExternalID
|
||||
}) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams1, Client),
|
||||
?payment_state(#domain_InvoicePayment{
|
||||
id = PaymentID1,
|
||||
external_id = ExternalID
|
||||
}) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams1, Client),
|
||||
PaymentParams2 = PaymentParams0#payproc_InvoicePaymentParams{id = <<"2">>},
|
||||
{exception, #payproc_InvoicePaymentPending{id = PaymentID1}} =
|
||||
hg_client_invoicing:start_payment(InvoiceID, PaymentParams2, Client),
|
||||
PaymentID1 = execute_payment(InvoiceID, PaymentParams1, Client),
|
||||
?payment_state(#domain_InvoicePayment{
|
||||
id = PaymentID1,
|
||||
external_id = ExternalID
|
||||
}) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams1, Client).
|
||||
|
||||
-spec payment_success(config()) -> test_return().
|
||||
payment_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
Context = #base_Content{
|
||||
type = <<"application/x-erlang-binary">>,
|
||||
data = erlang:term_to_binary({you, 643, "not", [<<"welcome">>, here]})
|
||||
},
|
||||
PayerSessionInfo = #domain_PayerSessionInfo{
|
||||
redirect_url = RedirectURL = <<"https://redirectly.io/merchant">>
|
||||
},
|
||||
PaymentParams = (make_payment_params(?pmt_sys(<<"visa-ref">>)))#payproc_InvoicePaymentParams{
|
||||
payer_session_info = PayerSessionInfo,
|
||||
context = Context
|
||||
},
|
||||
PaymentID = process_payment(InvoiceID, PaymentParams, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
?invoice_state(
|
||||
?invoice_w_status(?invoice_paid()),
|
||||
[PaymentSt = ?payment_state(Payment)]
|
||||
) = hg_client_invoicing:get(InvoiceID, Client),
|
||||
?payment_w_status(PaymentID, ?captured()) = Payment,
|
||||
?payment_last_trx(Trx) = PaymentSt,
|
||||
?assertMatch(
|
||||
#domain_InvoicePayment{
|
||||
payer_session_info = PayerSessionInfo,
|
||||
context = Context
|
||||
},
|
||||
Payment
|
||||
),
|
||||
?assertMatch(
|
||||
#domain_TransactionInfo{
|
||||
extra = #{
|
||||
<<"payment.payer_session_info.redirect_url">> := RedirectURL
|
||||
}
|
||||
},
|
||||
Trx
|
||||
).
|
||||
|
||||
-spec register_payment_success(config()) -> test_return().
|
||||
register_payment_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
Context = #base_Content{
|
||||
type = <<"application/x-erlang-binary">>,
|
||||
data = erlang:term_to_binary({you, 643, "not", [<<"welcome">>, here]})
|
||||
},
|
||||
PayerSessionInfo = #domain_PayerSessionInfo{},
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, ?pmt_sys(<<"visa-ref">>)),
|
||||
Route = ?route(?prv(1), ?trm(1)),
|
||||
Cost = ?cash(41999, <<"RUB">>),
|
||||
ID = hg_utils:unique_id(),
|
||||
ExternalID = hg_utils:unique_id(),
|
||||
TransactionInfo = ?trx_info(<<"1">>, #{}),
|
||||
OccurredAt = hg_datetime:format_now(),
|
||||
PaymentParams = #payproc_RegisterInvoicePaymentParams{
|
||||
payer_params =
|
||||
{payment_resource, #payproc_PaymentResourcePayerParams{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = PaymentTool,
|
||||
payment_session_id = Session,
|
||||
client_info = #domain_ClientInfo{}
|
||||
},
|
||||
contact_info = ?contact_info()
|
||||
}},
|
||||
route = Route,
|
||||
payer_session_info = PayerSessionInfo,
|
||||
context = Context,
|
||||
cost = Cost,
|
||||
id = ID,
|
||||
external_id = ExternalID,
|
||||
transaction_info = TransactionInfo,
|
||||
risk_score = high,
|
||||
occurred_at = OccurredAt
|
||||
},
|
||||
PaymentID = register_payment(InvoiceID, PaymentParams, true, Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
PaymentID = await_payment_process_finish(InvoiceID, PaymentID, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
?invoice_state(?invoice_w_status(?invoice_paid())) =
|
||||
hg_client_invoicing:get(InvoiceID, Client),
|
||||
PaymentSt = hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client),
|
||||
|
||||
?payment_route(Route) = PaymentSt,
|
||||
?payment_last_trx(TransactionInfo) = PaymentSt,
|
||||
?payment_state(Payment) = PaymentSt,
|
||||
?payment_w_status(PaymentID, ?captured()) = Payment,
|
||||
?assertMatch(
|
||||
#domain_InvoicePayment{
|
||||
id = ID,
|
||||
payer_session_info = PayerSessionInfo,
|
||||
context = Context,
|
||||
flow = ?invoice_payment_flow_instant(),
|
||||
cost = Cost,
|
||||
external_id = ExternalID
|
||||
},
|
||||
Payment
|
||||
).
|
||||
|
||||
-spec register_payment_customer_payer_success(config()) -> test_return().
|
||||
register_payment_customer_payer_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
Route = ?route(?prv(1), ?trm(1)),
|
||||
CustomerID = make_customer_w_rec_tool(
|
||||
cfg(party_id, C), cfg(shop_id, C), cfg(customer_client, C), ?pmt_sys(<<"visa-ref">>)
|
||||
),
|
||||
PaymentParams = #payproc_RegisterInvoicePaymentParams{
|
||||
payer_params =
|
||||
{customer, #payproc_CustomerPayerParams{
|
||||
customer_id = CustomerID
|
||||
}},
|
||||
route = Route,
|
||||
transaction_info = ?trx_info(<<"1">>, #{})
|
||||
},
|
||||
PaymentID = register_payment(InvoiceID, PaymentParams, false, Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
PaymentID = await_payment_process_finish(InvoiceID, PaymentID, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
?invoice_state(?invoice_w_status(?invoice_paid())) =
|
||||
hg_client_invoicing:get(InvoiceID, Client).
|
||||
|
||||
%%=============================================================================
|
||||
%% register_* cases helpers
|
||||
|
||||
@ -1599,74 +1396,6 @@ processing_deadline_reached_test(C) ->
|
||||
fun({authorization_failed, {processing_deadline_reached, _}}) -> ok end
|
||||
).
|
||||
|
||||
-spec payment_success_empty_cvv(config()) -> test_return().
|
||||
payment_success_empty_cvv(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(empty_cvv, ?pmt_sys(<<"visa-ref">>)),
|
||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||
PaymentID = execute_payment(InvoiceID, PaymentParams, Client),
|
||||
?invoice_state(
|
||||
?invoice_w_status(?invoice_paid()),
|
||||
[?payment_state(?payment_w_status(PaymentID, ?captured()))]
|
||||
) = hg_client_invoicing:get(InvoiceID, Client).
|
||||
|
||||
-spec payment_success_additional_info(config()) -> test_return().
|
||||
payment_success_additional_info(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(empty_cvv, ?pmt_sys(<<"visa-ref">>)),
|
||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||
PaymentID = start_payment(InvoiceID, PaymentParams, Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
|
||||
[
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?trx_bound(Trx))),
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_finished(?session_succeeded())))
|
||||
] = next_changes(InvoiceID, 2, Client),
|
||||
#domain_TransactionInfo{additional_info = AdditionalInfo} = Trx,
|
||||
AdditionalInfo = hg_ct_fixture:construct_dummy_additional_info(),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?processed())) =
|
||||
next_change(InvoiceID, Client),
|
||||
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
?invoice_state(
|
||||
?invoice_w_status(?invoice_paid()),
|
||||
[?payment_state(?payment_w_status(PaymentID, ?captured()))]
|
||||
) = hg_client_invoicing:get(InvoiceID, Client).
|
||||
|
||||
-spec payment_has_optional_fields(config()) -> test_return().
|
||||
payment_has_optional_fields(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
PaymentParams = make_payment_params(?pmt_sys(<<"visa-ref">>)),
|
||||
PaymentID = execute_payment(InvoiceID, PaymentParams, Client),
|
||||
InvoicePayment = hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client),
|
||||
?payment_state(Payment) = InvoicePayment,
|
||||
?payment_route(Route) = InvoicePayment,
|
||||
?payment_cashflow(CashFlow) = InvoicePayment,
|
||||
?payment_last_trx(TrxInfo) = InvoicePayment,
|
||||
PartyID = cfg(party_id, C),
|
||||
ShopID = cfg(shop_id, C),
|
||||
#domain_InvoicePayment{owner_id = PartyID, shop_id = ShopID} = Payment,
|
||||
false = Route =:= undefined,
|
||||
false = CashFlow =:= undefined,
|
||||
false = TrxInfo =:= undefined.
|
||||
|
||||
-spec payment_last_trx_correct(config()) -> _ | no_return().
|
||||
payment_last_trx_correct(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C),
|
||||
PaymentID = start_payment(InvoiceID, make_payment_params(?pmt_sys(<<"visa-ref">>)), Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
[
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?trx_bound(TrxInfo0))),
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_finished(?session_succeeded()))),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?processed()))
|
||||
] = next_changes(InvoiceID, 3, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
?payment_last_trx(TrxInfo0) = hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client).
|
||||
|
||||
-spec payment_w_misconfigured_routing_failed(config()) -> test_return().
|
||||
payment_w_misconfigured_routing_failed(C) ->
|
||||
Client = cfg(client, C),
|
||||
@ -2297,26 +2026,6 @@ payment_w_terminal_w_payment_service_success(C) ->
|
||||
PaymentSt
|
||||
).
|
||||
|
||||
-spec payment_w_crypto_currency_success(config()) -> _ | no_return().
|
||||
payment_w_crypto_currency_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
PayCash = 2000,
|
||||
InvoiceID = start_invoice(<<"cryptoduck">>, make_due_date(10), PayCash, C),
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(crypto_currency, ?crypta(<<"bitcoin-ref">>)),
|
||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||
?payment_state(#domain_InvoicePayment{
|
||||
id = PaymentID,
|
||||
owner_id = PartyID,
|
||||
shop_id = ShopID
|
||||
}) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
||||
next_change(InvoiceID, Client),
|
||||
{CF, Route} = await_payment_cash_flow(InvoiceID, PaymentID, Client),
|
||||
CFContext = construct_ta_context(PartyID, ShopID, Route),
|
||||
?cash(PayCash, <<"RUB">>) = get_cashflow_volume({provider, settlement}, {merchant, settlement}, CF, CFContext),
|
||||
?cash(40, <<"RUB">>) = get_cashflow_volume({system, settlement}, {provider, settlement}, CF, CFContext),
|
||||
?cash(90, <<"RUB">>) = get_cashflow_volume({merchant, settlement}, {system, settlement}, CF, CFContext).
|
||||
|
||||
-spec payment_bank_card_category_condition(config()) -> _ | no_return().
|
||||
payment_bank_card_category_condition(C) ->
|
||||
Client = cfg(client, C),
|
||||
@ -2335,55 +2044,6 @@ payment_bank_card_category_condition(C) ->
|
||||
CFContext = construct_ta_context(cfg(party_id, C), cfg(shop_id, C), Route),
|
||||
?cash(200, <<"RUB">>) = get_cashflow_volume({merchant, settlement}, {system, settlement}, CF, CFContext).
|
||||
|
||||
-spec payment_w_mobile_commerce(config()) -> _ | no_return().
|
||||
payment_w_mobile_commerce(C) ->
|
||||
payment_w_mobile_commerce(C, success).
|
||||
|
||||
-spec payment_suspend_timeout_failure(config()) -> _ | no_return().
|
||||
payment_suspend_timeout_failure(C) ->
|
||||
payment_w_mobile_commerce(C, failure).
|
||||
|
||||
payment_w_mobile_commerce(C, Expectation) ->
|
||||
Client = cfg(client, C),
|
||||
PayCash = 1001,
|
||||
InvoiceID = start_invoice(<<"oatmeal">>, make_due_date(10), PayCash, C),
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool({mobile_commerce, Expectation}, ?mob(<<"mts-ref">>)),
|
||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
||||
next_change(InvoiceID, Client),
|
||||
_ = await_payment_cash_flow(InvoiceID, PaymentID, Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
case Expectation of
|
||||
success ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_finished(?session_succeeded()))),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?processed()))
|
||||
] =
|
||||
next_changes(InvoiceID, 2, Client);
|
||||
failure ->
|
||||
[
|
||||
?payment_ev(
|
||||
PaymentID,
|
||||
?session_ev(?processed(), ?session_finished(?session_failed({failure, Failure})))
|
||||
),
|
||||
?payment_ev(PaymentID, ?payment_rollback_started({failure, Failure})),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?failed({failure, Failure})))
|
||||
] =
|
||||
next_changes(InvoiceID, 3, Client)
|
||||
end.
|
||||
|
||||
-spec payment_w_wallet_success(config()) -> _ | no_return().
|
||||
payment_w_wallet_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
InvoiceID = start_invoice(<<"bubbleblob">>, make_due_date(10), 42000, C),
|
||||
PaymentParams = make_wallet_payment_params(?pmt_srv(<<"qiwi-ref">>)),
|
||||
PaymentID = execute_payment(InvoiceID, PaymentParams, Client),
|
||||
?invoice_state(
|
||||
?invoice_w_status(?invoice_paid()),
|
||||
[?payment_state(?payment_w_status(PaymentID, ?captured()))]
|
||||
) = hg_client_invoicing:get(InvoiceID, Client).
|
||||
|
||||
-spec payment_w_customer_success(config()) -> test_return().
|
||||
payment_w_customer_success(C) ->
|
||||
Client = cfg(client, C),
|
||||
@ -3174,11 +2834,7 @@ update_payment_terms_cashflow(ProviderRef, CashFlow) ->
|
||||
ok.
|
||||
|
||||
construct_ta_context(Party, Shop, Route) ->
|
||||
#{
|
||||
party => Party,
|
||||
shop => Shop,
|
||||
route => Route
|
||||
}.
|
||||
hg_invoice_helper:construct_ta_context(Party, Shop, Route).
|
||||
|
||||
get_deprecated_cashflow_account(Type, CF, CFContext) ->
|
||||
ID = get_deprecated_cashflow_account_id(Type, CF, CFContext),
|
||||
@ -5209,56 +4865,10 @@ rounding_cashflow_volume(C) ->
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client).
|
||||
|
||||
get_cashflow_volume(Source, Destination, CF, CFContext) ->
|
||||
TAS = convert_transaction_account(Source, CFContext),
|
||||
TAD = convert_transaction_account(Destination, CFContext),
|
||||
[Volume] = [
|
||||
V
|
||||
|| #domain_FinalCashFlowPosting{
|
||||
source = #domain_FinalCashFlowAccount{
|
||||
account_type = ST,
|
||||
transaction_account = SA
|
||||
},
|
||||
destination = #domain_FinalCashFlowAccount{
|
||||
account_type = DT,
|
||||
transaction_account = DA
|
||||
},
|
||||
volume = V
|
||||
} <- CF,
|
||||
ST == Source,
|
||||
DT == Destination,
|
||||
SA == TAS,
|
||||
DA == TAD
|
||||
],
|
||||
Volume.
|
||||
hg_invoice_helper:get_cashflow_volume(Source, Destination, CF, CFContext).
|
||||
|
||||
convert_transaction_account({merchant, Type}, #{party := Party, shop := Shop}) ->
|
||||
{merchant, #domain_MerchantTransactionAccount{
|
||||
type = Type,
|
||||
owner = #domain_MerchantTransactionAccountOwner{
|
||||
party_id = Party,
|
||||
shop_id = Shop
|
||||
}
|
||||
}};
|
||||
convert_transaction_account({provider, Type}, #{route := Route}) ->
|
||||
#domain_PaymentRoute{
|
||||
provider = ProviderRef,
|
||||
terminal = TerminalRef
|
||||
} = Route,
|
||||
{provider, #domain_ProviderTransactionAccount{
|
||||
type = Type,
|
||||
owner = #domain_ProviderTransactionAccountOwner{
|
||||
provider_ref = ProviderRef,
|
||||
terminal_ref = TerminalRef
|
||||
}
|
||||
}};
|
||||
convert_transaction_account({system, Type}, _Context) ->
|
||||
{system, #domain_SystemTransactionAccount{
|
||||
type = Type
|
||||
}};
|
||||
convert_transaction_account({external, Type}, _Context) ->
|
||||
{external, #domain_ExternalTransactionAccount{
|
||||
type = Type
|
||||
}}.
|
||||
convert_transaction_account(Entity, Context) ->
|
||||
hg_invoice_helper:convert_transaction_account(Entity, Context).
|
||||
|
||||
%%
|
||||
|
||||
@ -6583,104 +6193,21 @@ await_cascade_triggering(InvoiceID, PaymentID, Client) ->
|
||||
{Route, CashFlow, TrxID, Failure}.
|
||||
|
||||
next_changes(InvoiceID, Amount, Client) ->
|
||||
next_changes(InvoiceID, Amount, ?DEFAULT_NEXT_CHANGE_TIMEOUT, Client).
|
||||
|
||||
next_changes(InvoiceID, Amount, Timeout, Client) ->
|
||||
TimeoutTime = erlang:monotonic_time(millisecond) + Timeout,
|
||||
next_changes_(InvoiceID, Amount, TimeoutTime, Client).
|
||||
|
||||
next_changes_(InvoiceID, Amount, Timeout, Client) ->
|
||||
Result = lists:foldl(
|
||||
fun(_N, Acc) ->
|
||||
case erlang:monotonic_time(millisecond) of
|
||||
Time when Time < Timeout ->
|
||||
[next_change(InvoiceID, Client) | Acc];
|
||||
_ ->
|
||||
[{error, timeout} | Acc]
|
||||
end
|
||||
end,
|
||||
[],
|
||||
lists:seq(1, Amount)
|
||||
),
|
||||
lists:reverse(Result).
|
||||
hg_invoice_helper:next_changes(InvoiceID, Amount, Client).
|
||||
|
||||
next_change(InvoiceID, Client) ->
|
||||
%% timeout should be at least as large as hold expiration in construct_domain_fixture/0
|
||||
next_change(InvoiceID, ?DEFAULT_NEXT_CHANGE_TIMEOUT, Client).
|
||||
hg_invoice_helper:next_change(InvoiceID, Client).
|
||||
|
||||
next_change(InvoiceID, Timeout, Client) ->
|
||||
hg_client_invoicing:pull_change(InvoiceID, fun filter_change/1, Timeout, Client).
|
||||
|
||||
filter_change(?payment_ev(_, C)) ->
|
||||
filter_change(C);
|
||||
filter_change(?chargeback_ev(_, C)) ->
|
||||
filter_change(C);
|
||||
filter_change(?refund_ev(_, C)) ->
|
||||
filter_change(C);
|
||||
filter_change(?session_ev(_, ?proxy_st_changed(_))) ->
|
||||
false;
|
||||
filter_change(?session_ev(_, ?session_suspended(_, _))) ->
|
||||
false;
|
||||
filter_change(?session_ev(_, ?session_activated())) ->
|
||||
false;
|
||||
filter_change(_) ->
|
||||
true.
|
||||
hg_invoice_helper:next_change(InvoiceID, Timeout, Client).
|
||||
|
||||
%%
|
||||
|
||||
start_service_handler(Module, C, HandlerOpts) ->
|
||||
start_service_handler(Module, Module, C, HandlerOpts).
|
||||
|
||||
start_service_handler(Name, Module, C, HandlerOpts) ->
|
||||
IP = "127.0.0.1",
|
||||
Port = get_random_port(),
|
||||
Opts = maps:merge(HandlerOpts, #{hellgate_root_url => cfg(root_url, C)}),
|
||||
ChildSpec = hg_test_proxy:get_child_spec(Name, Module, IP, Port, Opts),
|
||||
{ok, _} = supervisor:start_child(cfg(test_sup, C), ChildSpec),
|
||||
hg_test_proxy:get_url(Module, IP, Port).
|
||||
|
||||
start_proxies(Proxies) ->
|
||||
setup_proxies(
|
||||
lists:map(
|
||||
fun
|
||||
Mapper({Module, ProxyID, Context}) ->
|
||||
Mapper({Module, ProxyID, #{}, Context});
|
||||
Mapper({Module, ProxyID, ProxyOpts, Context}) ->
|
||||
construct_proxy(ProxyID, start_service_handler(Module, Context, #{}), ProxyOpts)
|
||||
end,
|
||||
Proxies
|
||||
)
|
||||
).
|
||||
|
||||
setup_proxies(Proxies) ->
|
||||
_ = hg_domain:upsert(Proxies),
|
||||
ok.
|
||||
hg_invoice_helper:start_proxies(Proxies).
|
||||
|
||||
start_kv_store(SupPid) ->
|
||||
ChildSpec = #{
|
||||
id => hg_kv_store,
|
||||
start => {hg_kv_store, start_link, [[]]},
|
||||
restart => permanent,
|
||||
shutdown => 2000,
|
||||
type => worker,
|
||||
modules => [hg_kv_store]
|
||||
},
|
||||
{ok, _} = supervisor:start_child(SupPid, ChildSpec),
|
||||
ok.
|
||||
|
||||
get_random_port() ->
|
||||
rand:uniform(32768) + 32767.
|
||||
|
||||
construct_proxy(ID, Url, Options) ->
|
||||
{proxy, #domain_ProxyObject{
|
||||
ref = ?prx(ID),
|
||||
data = #domain_ProxyDefinition{
|
||||
name = Url,
|
||||
description = Url,
|
||||
url = Url,
|
||||
options = Options
|
||||
}
|
||||
}}.
|
||||
hg_invoice_helper:start_kv_store(SupPid).
|
||||
|
||||
%%
|
||||
make_invoice_params(PartyID, ShopID, Product, Cost) ->
|
||||
@ -6694,7 +6221,7 @@ make_invoice_params(PartyID, ShopID, Product, Due, Cost, AllocationPrototype) ->
|
||||
hg_ct_helper:make_invoice_params(InvoiceID, PartyID, ShopID, Product, Due, Cost, AllocationPrototype).
|
||||
|
||||
make_cash(Amount) ->
|
||||
make_cash(Amount, <<"RUB">>).
|
||||
hg_invoice_helper:make_cash(Amount).
|
||||
|
||||
make_cash(Amount, Currency) ->
|
||||
hg_ct_helper:make_cash(Amount, Currency).
|
||||
@ -6732,8 +6259,7 @@ delete_invoice_tpl(TplID, Config) ->
|
||||
hg_client_invoice_templating:delete(TplID, cfg(client_tpl, Config)).
|
||||
|
||||
make_wallet_payment_params(PmtSrv) ->
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(digital_wallet, PmtSrv),
|
||||
make_payment_params(PaymentTool, Session, instant).
|
||||
hg_invoice_helper:make_wallet_payment_params(PmtSrv).
|
||||
|
||||
make_tds_payment_params(FlowType, PmtSys) ->
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(preauth_3ds, PmtSys),
|
||||
@ -6757,32 +6283,13 @@ make_scenario_payment_params(Scenario, FlowType, PmtSys) ->
|
||||
make_payment_params(PaymentTool, Session, FlowType).
|
||||
|
||||
make_payment_params(PmtSys) ->
|
||||
make_payment_params(PmtSys, instant).
|
||||
hg_invoice_helper:make_payment_params(PmtSys).
|
||||
|
||||
make_payment_params(PmtSys, FlowType) ->
|
||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, PmtSys),
|
||||
make_payment_params(PaymentTool, Session, FlowType).
|
||||
hg_invoice_helper:make_payment_params(PmtSys, FlowType).
|
||||
|
||||
make_payment_params(PaymentTool, Session, FlowType) ->
|
||||
Flow =
|
||||
case FlowType of
|
||||
instant ->
|
||||
{instant, #payproc_InvoicePaymentParamsFlowInstant{}};
|
||||
{hold, OnHoldExpiration} ->
|
||||
{hold, #payproc_InvoicePaymentParamsFlowHold{on_hold_expiration = OnHoldExpiration}}
|
||||
end,
|
||||
#payproc_InvoicePaymentParams{
|
||||
payer =
|
||||
{payment_resource, #payproc_PaymentResourcePayerParams{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = PaymentTool,
|
||||
payment_session_id = Session,
|
||||
client_info = #domain_ClientInfo{}
|
||||
},
|
||||
contact_info = ?contact_info()
|
||||
}},
|
||||
flow = Flow
|
||||
}.
|
||||
hg_invoice_helper:make_payment_params(PaymentTool, Session, FlowType).
|
||||
|
||||
make_chargeback_cancel_params() ->
|
||||
#payproc_InvoicePaymentChargebackCancelParams{}.
|
||||
@ -6904,7 +6411,7 @@ make_status_adjustment_params(Status, Reason) ->
|
||||
}.
|
||||
|
||||
make_due_date(LifetimeSeconds) ->
|
||||
genlib_time:unow() + LifetimeSeconds.
|
||||
hg_invoice_helper:make_due_date(LifetimeSeconds).
|
||||
|
||||
create_invoice(InvoiceParams, Client) ->
|
||||
?invoice_state(?invoice(InvoiceID)) = hg_client_invoicing:create(InvoiceParams, Client),
|
||||
@ -6934,59 +6441,28 @@ repair_invoice_with_scenario(InvoiceID, Scenario, Client) ->
|
||||
hg_client_invoicing:repair_scenario(InvoiceID, create_repair_scenario(Scenario), Client).
|
||||
|
||||
start_invoice(Product, Due, Amount, C) ->
|
||||
start_invoice(cfg(shop_id, C), Product, Due, Amount, C).
|
||||
hg_invoice_helper:start_invoice(Product, Due, Amount, C).
|
||||
|
||||
start_invoice(ShopID, Product, Due, Amount, C) ->
|
||||
Client = cfg(client, C),
|
||||
PartyID = cfg(party_id, C),
|
||||
start_invoice(PartyID, ShopID, Product, Due, Amount, Client).
|
||||
hg_invoice_helper:start_invoice(ShopID, Product, Due, Amount, C).
|
||||
|
||||
start_invoice(PartyID, ShopID, Product, Due, Amount, Client) ->
|
||||
InvoiceParams = make_invoice_params(PartyID, ShopID, Product, Due, make_cash(Amount)),
|
||||
InvoiceID = create_invoice(InvoiceParams, Client),
|
||||
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),
|
||||
InvoiceID.
|
||||
hg_invoice_helper:start_invoice(PartyID, ShopID, Product, Due, Amount, Client).
|
||||
|
||||
start_payment(InvoiceID, PaymentParams, Client) ->
|
||||
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||
_ = start_payment_ev(InvoiceID, Client),
|
||||
?payment_ev(PaymentID, ?cash_flow_changed(_)) =
|
||||
next_change(InvoiceID, Client),
|
||||
PaymentID.
|
||||
hg_invoice_helper:start_payment(InvoiceID, PaymentParams, Client).
|
||||
|
||||
register_payment(InvoiceID, RegisterPaymentParams, WithRiskScoring, Client) ->
|
||||
?payment_state(?payment(PaymentID)) =
|
||||
hg_client_invoicing:register_payment(InvoiceID, RegisterPaymentParams, Client),
|
||||
_ =
|
||||
case WithRiskScoring of
|
||||
true ->
|
||||
start_payment_ev(InvoiceID, Client);
|
||||
false ->
|
||||
start_payment_ev_no_risk_scoring(InvoiceID, Client)
|
||||
end,
|
||||
?payment_ev(PaymentID, ?cash_flow_changed(_)) =
|
||||
next_change(InvoiceID, Client),
|
||||
PaymentID.
|
||||
hg_invoice_helper:register_payment(InvoiceID, RegisterPaymentParams, WithRiskScoring, Client).
|
||||
|
||||
start_payment_ev(InvoiceID, Client) ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||
?payment_ev(PaymentID, ?risk_score_changed(_RiskScore)),
|
||||
?payment_ev(PaymentID, ?route_changed(Route))
|
||||
] = next_changes(InvoiceID, 3, Client),
|
||||
Route.
|
||||
hg_invoice_helper:start_payment_ev(InvoiceID, Client).
|
||||
|
||||
start_payment_ev_no_risk_scoring(InvoiceID, Client) ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||
?payment_ev(PaymentID, ?route_changed(Route))
|
||||
] = next_changes(InvoiceID, 2, Client),
|
||||
Route.
|
||||
hg_invoice_helper:start_payment_ev_no_risk_scoring(InvoiceID, Client).
|
||||
|
||||
process_payment(InvoiceID, PaymentParams, Client) ->
|
||||
PaymentID = start_payment(InvoiceID, PaymentParams, Client),
|
||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||
PaymentID = await_payment_process_finish(InvoiceID, PaymentID, Client).
|
||||
hg_invoice_helper:process_payment(InvoiceID, PaymentParams, Client).
|
||||
|
||||
await_payment_started(InvoiceID, PaymentID, Client) ->
|
||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
||||
@ -6994,12 +6470,7 @@ await_payment_started(InvoiceID, PaymentID, Client) ->
|
||||
PaymentID.
|
||||
|
||||
await_payment_cash_flow(InvoiceID, PaymentID, Client) ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?risk_score_changed(_)),
|
||||
?payment_ev(PaymentID, ?route_changed(Route)),
|
||||
?payment_ev(PaymentID, ?cash_flow_changed(CashFlow))
|
||||
] = next_changes(InvoiceID, 3, Client),
|
||||
{CashFlow, Route}.
|
||||
hg_invoice_helper:await_payment_cash_flow(InvoiceID, PaymentID, Client).
|
||||
|
||||
await_payment_cash_flow(RS, Route, InvoiceID, PaymentID, Client) ->
|
||||
[
|
||||
@ -7018,9 +6489,7 @@ await_payment_rollback(InvoiceID, PaymentID, Client) ->
|
||||
Failure.
|
||||
|
||||
await_payment_session_started(InvoiceID, PaymentID, Client, Target) ->
|
||||
?payment_ev(PaymentID, ?session_ev(Target, ?session_started())) =
|
||||
next_change(InvoiceID, Client),
|
||||
PaymentID.
|
||||
hg_invoice_helper:await_payment_session_started(InvoiceID, PaymentID, Client, Target).
|
||||
|
||||
await_payment_process_interaction(InvoiceID, PaymentID, Client) ->
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_started())) =
|
||||
@ -7033,12 +6502,7 @@ await_payment_process_interaction(InvoiceID, PaymentID, Client) ->
|
||||
UserInteraction.
|
||||
|
||||
await_payment_process_finish(InvoiceID, PaymentID, Client) ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?trx_bound(?trx_info(_)))),
|
||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_finished(?session_succeeded()))),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?processed()))
|
||||
] = next_changes(InvoiceID, 3, Client),
|
||||
PaymentID.
|
||||
hg_invoice_helper:await_payment_process_finish(InvoiceID, PaymentID, Client).
|
||||
|
||||
await_payment_process_interaction_completion(InvoiceID, PaymentID, UserInteraction, Client) ->
|
||||
?payment_ev(
|
||||
@ -7051,21 +6515,13 @@ await_payment_process_interaction_completion(InvoiceID, PaymentID, UserInteracti
|
||||
ok.
|
||||
|
||||
await_payment_capture(InvoiceID, PaymentID, Client) ->
|
||||
await_payment_capture(InvoiceID, PaymentID, ?timeout_reason(), Client).
|
||||
hg_invoice_helper:await_payment_capture(InvoiceID, PaymentID, Client).
|
||||
|
||||
await_payment_capture(InvoiceID, PaymentID, Reason, Client) ->
|
||||
await_payment_capture(InvoiceID, PaymentID, Reason, undefined, Client).
|
||||
hg_invoice_helper:await_payment_capture(InvoiceID, PaymentID, Reason, Client).
|
||||
|
||||
await_payment_capture(InvoiceID, PaymentID, Reason, TrxID, Client) ->
|
||||
Cost = get_payment_cost(InvoiceID, PaymentID, Client),
|
||||
[
|
||||
?payment_ev(PaymentID, ?payment_capture_started(Reason, Cost, _, _)),
|
||||
?payment_ev(PaymentID, ?session_ev(?captured(Reason, Cost), ?session_started()))
|
||||
] = next_changes(InvoiceID, 2, Client),
|
||||
TrxID =/= undefined andalso
|
||||
(?payment_ev(PaymentID, ?session_ev(?captured(Reason, Cost, _Cart, _), ?trx_bound(?trx_info(TrxID)))) =
|
||||
next_change(InvoiceID, Client)),
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Client).
|
||||
hg_invoice_helper:await_payment_capture(InvoiceID, PaymentID, Reason, TrxID, Client).
|
||||
|
||||
await_payment_partial_capture(InvoiceID, PaymentID, Reason, Cash, Client) ->
|
||||
[
|
||||
@ -7076,19 +6532,13 @@ await_payment_partial_capture(InvoiceID, PaymentID, Reason, Cash, Client) ->
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cash, Client).
|
||||
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Client) ->
|
||||
Cost = get_payment_cost(InvoiceID, PaymentID, Client),
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, Client).
|
||||
hg_invoice_helper:await_payment_capture_finish(InvoiceID, PaymentID, Reason, Client).
|
||||
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, Client) ->
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, undefined, Client).
|
||||
hg_invoice_helper:await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, Client).
|
||||
|
||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, Cart, Client) ->
|
||||
[
|
||||
?payment_ev(PaymentID, ?session_ev(?captured(Reason, Cost, Cart, _), ?session_finished(?session_succeeded()))),
|
||||
?payment_ev(PaymentID, ?payment_status_changed(?captured(Reason, Cost, Cart, _))),
|
||||
?invoice_status_changed(?invoice_paid())
|
||||
] = next_changes(InvoiceID, 3, Client),
|
||||
PaymentID.
|
||||
hg_invoice_helper:await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, Cart, Client).
|
||||
|
||||
await_payment_cancel(InvoiceID, PaymentID, Reason, Client) ->
|
||||
[
|
||||
@ -7221,43 +6671,7 @@ get_post_request(?payterm_receipt(SPID)) ->
|
||||
{URL, #{<<"tag">> => SPID}}.
|
||||
|
||||
make_customer_w_rec_tool(PartyID, ShopID, Client, PmtSys) ->
|
||||
CustomerParams = hg_ct_helper:make_customer_params(PartyID, ShopID, <<"InvoicingTests">>),
|
||||
#payproc_Customer{id = CustomerID} =
|
||||
hg_client_customer:create(CustomerParams, Client),
|
||||
#payproc_CustomerBinding{id = BindingID} =
|
||||
hg_client_customer:start_binding(
|
||||
CustomerID,
|
||||
hg_ct_helper:make_customer_binding_params(hg_dummy_provider:make_payment_tool(no_preauth, PmtSys)),
|
||||
Client
|
||||
),
|
||||
ok = wait_for_binding_success(CustomerID, BindingID, Client),
|
||||
CustomerID.
|
||||
|
||||
wait_for_binding_success(CustomerID, BindingID, Client) ->
|
||||
wait_for_binding_success(CustomerID, BindingID, 20000, Client).
|
||||
|
||||
wait_for_binding_success(CustomerID, BindingID, TimeLeft, Client) when TimeLeft > 0 ->
|
||||
Target = ?customer_binding_changed(BindingID, ?customer_binding_status_changed(?customer_binding_succeeded())),
|
||||
Started = genlib_time:ticks(),
|
||||
Event = hg_client_customer:pull_event(CustomerID, Client),
|
||||
R =
|
||||
case Event of
|
||||
{ok, ?customer_event(Changes)} ->
|
||||
lists:member(Target, Changes);
|
||||
_ ->
|
||||
false
|
||||
end,
|
||||
case R of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
timer:sleep(200),
|
||||
Now = genlib_time:ticks(),
|
||||
TimeLeftNext = TimeLeft - (Now - Started) div 1000,
|
||||
wait_for_binding_success(CustomerID, BindingID, TimeLeftNext, Client)
|
||||
end;
|
||||
wait_for_binding_success(_, _, _, _) ->
|
||||
timeout.
|
||||
hg_invoice_helper:make_customer_w_rec_tool(PartyID, ShopID, Client, PmtSys).
|
||||
|
||||
invoice_create_and_get_revision(PartyID, Client, ShopID) ->
|
||||
InvoiceParams = make_invoice_params(PartyID, ShopID, <<"somePlace">>, make_due_date(10), make_cash(5000)),
|
||||
@ -7267,9 +6681,7 @@ invoice_create_and_get_revision(PartyID, Client, ShopID) ->
|
||||
{InvoiceRev, InvoiceID}.
|
||||
|
||||
execute_payment(InvoiceID, Params, Client) ->
|
||||
PaymentID = process_payment(InvoiceID, Params, Client),
|
||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
||||
PaymentID.
|
||||
hg_invoice_helper:execute_payment(InvoiceID, Params, Client).
|
||||
|
||||
execute_payment_w_cascade(InvoiceID, Params, Client, CascadeCount) when CascadeCount > 0 ->
|
||||
#payproc_InvoicePayment{payment = _Payment} = hg_client_invoicing:start_payment(InvoiceID, Params, Client),
|
||||
@ -7431,12 +6843,6 @@ payment_customer_risk_score_check(C) ->
|
||||
|
||||
%
|
||||
|
||||
get_payment_cost(InvoiceID, PaymentID, Client) ->
|
||||
#payproc_InvoicePayment{
|
||||
payment = #domain_InvoicePayment{cost = Cost}
|
||||
} = hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client),
|
||||
Cost.
|
||||
|
||||
get_payment_cashflow_mapped(InvoiceID, PaymentID, Client) ->
|
||||
#payproc_InvoicePayment{
|
||||
cash_flow = CashFlow
|
||||
|
@ -20,7 +20,8 @@
|
||||
hg_ct_helper,
|
||||
hg_customer_tests_SUITE,
|
||||
hg_recurrent_paytools_tests_SUITE,
|
||||
hg_invoice_tests_SUITE
|
||||
hg_invoice_tests_SUITE,
|
||||
hg_invoice_helper
|
||||
]
|
||||
}},
|
||||
{elvis_style, no_if_expression},
|
||||
@ -37,7 +38,8 @@
|
||||
hg_routing,
|
||||
hg_route_rules_tests_SUITE,
|
||||
hg_invoice_tests_SUITE,
|
||||
hg_allocation_tests
|
||||
hg_allocation_tests,
|
||||
hg_invoice_helper
|
||||
]
|
||||
}},
|
||||
{elvis_style, no_debug_call, #{}}
|
||||
|
Loading…
Reference in New Issue
Block a user