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).
|
-module(hg_invoice_tests_SUITE).
|
||||||
|
|
||||||
-include("hg_ct_domain.hrl").
|
-include("hg_ct_domain.hrl").
|
||||||
|
-include("hg_ct_invoice.hrl").
|
||||||
-include_lib("damsel/include/dmsl_repair_thrift.hrl").
|
-include_lib("damsel/include/dmsl_repair_thrift.hrl").
|
||||||
-include_lib("hellgate/include/allocation.hrl").
|
-include_lib("hellgate/include/allocation.hrl").
|
||||||
|
|
||||||
@ -34,11 +35,6 @@
|
|||||||
-export([invoice_cancellation_after_payment_timeout/1]).
|
-export([invoice_cancellation_after_payment_timeout/1]).
|
||||||
-export([invalid_payment_amount/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_limit_success/1]).
|
||||||
-export([payment_routes_limit_values/1]).
|
-export([payment_routes_limit_values/1]).
|
||||||
-export([register_payment_limit_success/1]).
|
-export([register_payment_limit_success/1]).
|
||||||
@ -54,18 +50,12 @@
|
|||||||
-export([limit_hold_two_routes_failure/1]).
|
-export([limit_hold_two_routes_failure/1]).
|
||||||
|
|
||||||
-export([processing_deadline_reached_test/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_terminal_w_payment_service_success/1]).
|
||||||
-export([payment_w_crypto_currency_success/1]).
|
|
||||||
-export([payment_bank_card_category_condition/1]).
|
-export([payment_bank_card_category_condition/1]).
|
||||||
-export([payment_w_wallet_success/1]).
|
|
||||||
-export([payment_w_customer_success/1]).
|
-export([payment_w_customer_success/1]).
|
||||||
-export([payment_w_another_shop_customer/1]).
|
-export([payment_w_another_shop_customer/1]).
|
||||||
-export([payment_w_another_party_customer/1]).
|
-export([payment_w_another_party_customer/1]).
|
||||||
-export([payment_w_deleted_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_card_issuer_conditions/1]).
|
||||||
-export([payments_w_bank_conditions/1]).
|
-export([payments_w_bank_conditions/1]).
|
||||||
-export([payment_success_on_second_try/1]).
|
-export([payment_success_on_second_try/1]).
|
||||||
@ -158,8 +148,6 @@
|
|||||||
-export([payment_with_offsite_preauth_failed/1]).
|
-export([payment_with_offsite_preauth_failed/1]).
|
||||||
-export([payment_with_tokenized_bank_card/1]).
|
-export([payment_with_tokenized_bank_card/1]).
|
||||||
-export([terms_retrieval/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_w_misconfigured_routing_failed/1]).
|
||||||
-export([payment_capture_failed/1]).
|
-export([payment_capture_failed/1]).
|
||||||
-export([payment_capture_retries_exceeded/1]).
|
-export([payment_capture_retries_exceeded/1]).
|
||||||
@ -310,30 +298,18 @@ groups() ->
|
|||||||
invoice_cancellation_after_payment_timeout,
|
invoice_cancellation_after_payment_timeout,
|
||||||
invalid_payment_amount,
|
invalid_payment_amount,
|
||||||
|
|
||||||
payment_start_idempotency,
|
|
||||||
payment_success,
|
|
||||||
register_payment_success,
|
|
||||||
register_payment_customer_payer_success,
|
|
||||||
payment_success_ruleset,
|
payment_success_ruleset,
|
||||||
processing_deadline_reached_test,
|
processing_deadline_reached_test,
|
||||||
payment_success_empty_cvv,
|
|
||||||
payment_success_additional_info,
|
|
||||||
payment_bank_card_category_condition,
|
payment_bank_card_category_condition,
|
||||||
payment_w_terminal_w_payment_service_success,
|
payment_w_terminal_w_payment_service_success,
|
||||||
payment_w_crypto_currency_success,
|
|
||||||
payment_w_wallet_success,
|
|
||||||
payment_w_customer_success,
|
payment_w_customer_success,
|
||||||
payment_w_another_shop_customer,
|
payment_w_another_shop_customer,
|
||||||
payment_w_another_party_customer,
|
payment_w_another_party_customer,
|
||||||
payment_w_deleted_customer,
|
payment_w_deleted_customer,
|
||||||
payment_w_mobile_commerce,
|
|
||||||
payment_suspend_timeout_failure,
|
|
||||||
payment_success_on_second_try,
|
payment_success_on_second_try,
|
||||||
payment_fail_after_silent_callback,
|
payment_fail_after_silent_callback,
|
||||||
payment_temporary_unavailability_retry_success,
|
payment_temporary_unavailability_retry_success,
|
||||||
payment_temporary_unavailability_too_many_retries,
|
payment_temporary_unavailability_too_many_retries,
|
||||||
payment_has_optional_fields,
|
|
||||||
payment_last_trx_correct,
|
|
||||||
invoice_success_on_third_payment,
|
invoice_success_on_third_payment,
|
||||||
payment_w_misconfigured_routing_failed,
|
payment_w_misconfigured_routing_failed,
|
||||||
payment_capture_failed,
|
payment_capture_failed,
|
||||||
@ -560,40 +536,11 @@ init_per_suite(C) ->
|
|||||||
end_per_suite(C) ->
|
end_per_suite(C) ->
|
||||||
_ = hg_domain:cleanup(),
|
_ = hg_domain:cleanup(),
|
||||||
_ = [application:stop(App) || App <- cfg(apps, C)],
|
_ = [application:stop(App) || App <- cfg(apps, C)],
|
||||||
|
_ = hg_invoice_helper:stop_kv_store(cfg(test_sup, C)),
|
||||||
exit(cfg(test_sup, C), shutdown).
|
exit(cfg(test_sup, C), shutdown).
|
||||||
|
|
||||||
%% tests
|
%% 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),
|
-define(invalid_invoice_status(Status),
|
||||||
{exception, #payproc_InvalidInvoiceStatus{status = Status}}
|
{exception, #payproc_InvalidInvoiceStatus{status = Status}}
|
||||||
).
|
).
|
||||||
@ -1089,156 +1036,6 @@ invalid_payment_amount(C) ->
|
|||||||
errors = [<<"Invalid amount, more", _/binary>>]
|
errors = [<<"Invalid amount, more", _/binary>>]
|
||||||
}} = hg_client_invoicing:start_payment(InvoiceID2, PaymentParams, Client).
|
}} = 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
|
%% register_* cases helpers
|
||||||
|
|
||||||
@ -1599,74 +1396,6 @@ processing_deadline_reached_test(C) ->
|
|||||||
fun({authorization_failed, {processing_deadline_reached, _}}) -> ok end
|
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().
|
-spec payment_w_misconfigured_routing_failed(config()) -> test_return().
|
||||||
payment_w_misconfigured_routing_failed(C) ->
|
payment_w_misconfigured_routing_failed(C) ->
|
||||||
Client = cfg(client, C),
|
Client = cfg(client, C),
|
||||||
@ -2297,26 +2026,6 @@ payment_w_terminal_w_payment_service_success(C) ->
|
|||||||
PaymentSt
|
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().
|
-spec payment_bank_card_category_condition(config()) -> _ | no_return().
|
||||||
payment_bank_card_category_condition(C) ->
|
payment_bank_card_category_condition(C) ->
|
||||||
Client = cfg(client, 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),
|
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).
|
?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().
|
-spec payment_w_customer_success(config()) -> test_return().
|
||||||
payment_w_customer_success(C) ->
|
payment_w_customer_success(C) ->
|
||||||
Client = cfg(client, C),
|
Client = cfg(client, C),
|
||||||
@ -3174,11 +2834,7 @@ update_payment_terms_cashflow(ProviderRef, CashFlow) ->
|
|||||||
ok.
|
ok.
|
||||||
|
|
||||||
construct_ta_context(Party, Shop, Route) ->
|
construct_ta_context(Party, Shop, Route) ->
|
||||||
#{
|
hg_invoice_helper:construct_ta_context(Party, Shop, Route).
|
||||||
party => Party,
|
|
||||||
shop => Shop,
|
|
||||||
route => Route
|
|
||||||
}.
|
|
||||||
|
|
||||||
get_deprecated_cashflow_account(Type, CF, CFContext) ->
|
get_deprecated_cashflow_account(Type, CF, CFContext) ->
|
||||||
ID = get_deprecated_cashflow_account_id(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).
|
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client).
|
||||||
|
|
||||||
get_cashflow_volume(Source, Destination, CF, CFContext) ->
|
get_cashflow_volume(Source, Destination, CF, CFContext) ->
|
||||||
TAS = convert_transaction_account(Source, CFContext),
|
hg_invoice_helper:get_cashflow_volume(Source, Destination, CF, 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.
|
|
||||||
|
|
||||||
convert_transaction_account({merchant, Type}, #{party := Party, shop := Shop}) ->
|
convert_transaction_account(Entity, Context) ->
|
||||||
{merchant, #domain_MerchantTransactionAccount{
|
hg_invoice_helper:convert_transaction_account(Entity, Context).
|
||||||
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
|
|
||||||
}}.
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@ -6583,104 +6193,21 @@ await_cascade_triggering(InvoiceID, PaymentID, Client) ->
|
|||||||
{Route, CashFlow, TrxID, Failure}.
|
{Route, CashFlow, TrxID, Failure}.
|
||||||
|
|
||||||
next_changes(InvoiceID, Amount, Client) ->
|
next_changes(InvoiceID, Amount, Client) ->
|
||||||
next_changes(InvoiceID, Amount, ?DEFAULT_NEXT_CHANGE_TIMEOUT, Client).
|
hg_invoice_helper:next_changes(InvoiceID, Amount, 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).
|
|
||||||
|
|
||||||
next_change(InvoiceID, Client) ->
|
next_change(InvoiceID, Client) ->
|
||||||
%% timeout should be at least as large as hold expiration in construct_domain_fixture/0
|
hg_invoice_helper:next_change(InvoiceID, Client).
|
||||||
next_change(InvoiceID, ?DEFAULT_NEXT_CHANGE_TIMEOUT, Client).
|
|
||||||
|
|
||||||
next_change(InvoiceID, Timeout, Client) ->
|
next_change(InvoiceID, Timeout, Client) ->
|
||||||
hg_client_invoicing:pull_change(InvoiceID, fun filter_change/1, Timeout, Client).
|
hg_invoice_helper:next_change(InvoiceID, 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.
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
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) ->
|
start_proxies(Proxies) ->
|
||||||
setup_proxies(
|
hg_invoice_helper:start_proxies(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.
|
|
||||||
|
|
||||||
start_kv_store(SupPid) ->
|
start_kv_store(SupPid) ->
|
||||||
ChildSpec = #{
|
hg_invoice_helper:start_kv_store(SupPid).
|
||||||
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
|
|
||||||
}
|
|
||||||
}}.
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
make_invoice_params(PartyID, ShopID, Product, Cost) ->
|
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).
|
hg_ct_helper:make_invoice_params(InvoiceID, PartyID, ShopID, Product, Due, Cost, AllocationPrototype).
|
||||||
|
|
||||||
make_cash(Amount) ->
|
make_cash(Amount) ->
|
||||||
make_cash(Amount, <<"RUB">>).
|
hg_invoice_helper:make_cash(Amount).
|
||||||
|
|
||||||
make_cash(Amount, Currency) ->
|
make_cash(Amount, Currency) ->
|
||||||
hg_ct_helper: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)).
|
hg_client_invoice_templating:delete(TplID, cfg(client_tpl, Config)).
|
||||||
|
|
||||||
make_wallet_payment_params(PmtSrv) ->
|
make_wallet_payment_params(PmtSrv) ->
|
||||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(digital_wallet, PmtSrv),
|
hg_invoice_helper:make_wallet_payment_params(PmtSrv).
|
||||||
make_payment_params(PaymentTool, Session, instant).
|
|
||||||
|
|
||||||
make_tds_payment_params(FlowType, PmtSys) ->
|
make_tds_payment_params(FlowType, PmtSys) ->
|
||||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(preauth_3ds, 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(PaymentTool, Session, FlowType).
|
||||||
|
|
||||||
make_payment_params(PmtSys) ->
|
make_payment_params(PmtSys) ->
|
||||||
make_payment_params(PmtSys, instant).
|
hg_invoice_helper:make_payment_params(PmtSys).
|
||||||
|
|
||||||
make_payment_params(PmtSys, FlowType) ->
|
make_payment_params(PmtSys, FlowType) ->
|
||||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, PmtSys),
|
hg_invoice_helper:make_payment_params(PmtSys, FlowType).
|
||||||
make_payment_params(PaymentTool, Session, FlowType).
|
|
||||||
|
|
||||||
make_payment_params(PaymentTool, Session, FlowType) ->
|
make_payment_params(PaymentTool, Session, FlowType) ->
|
||||||
Flow =
|
hg_invoice_helper:make_payment_params(PaymentTool, Session, FlowType).
|
||||||
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
|
|
||||||
}.
|
|
||||||
|
|
||||||
make_chargeback_cancel_params() ->
|
make_chargeback_cancel_params() ->
|
||||||
#payproc_InvoicePaymentChargebackCancelParams{}.
|
#payproc_InvoicePaymentChargebackCancelParams{}.
|
||||||
@ -6904,7 +6411,7 @@ make_status_adjustment_params(Status, Reason) ->
|
|||||||
}.
|
}.
|
||||||
|
|
||||||
make_due_date(LifetimeSeconds) ->
|
make_due_date(LifetimeSeconds) ->
|
||||||
genlib_time:unow() + LifetimeSeconds.
|
hg_invoice_helper:make_due_date(LifetimeSeconds).
|
||||||
|
|
||||||
create_invoice(InvoiceParams, Client) ->
|
create_invoice(InvoiceParams, Client) ->
|
||||||
?invoice_state(?invoice(InvoiceID)) = hg_client_invoicing:create(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).
|
hg_client_invoicing:repair_scenario(InvoiceID, create_repair_scenario(Scenario), Client).
|
||||||
|
|
||||||
start_invoice(Product, Due, Amount, C) ->
|
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) ->
|
start_invoice(ShopID, Product, Due, Amount, C) ->
|
||||||
Client = cfg(client, C),
|
hg_invoice_helper:start_invoice(ShopID, Product, Due, Amount, C).
|
||||||
PartyID = cfg(party_id, C),
|
|
||||||
start_invoice(PartyID, ShopID, Product, Due, Amount, Client).
|
|
||||||
|
|
||||||
start_invoice(PartyID, ShopID, Product, Due, Amount, Client) ->
|
start_invoice(PartyID, ShopID, Product, Due, Amount, Client) ->
|
||||||
InvoiceParams = make_invoice_params(PartyID, ShopID, Product, Due, make_cash(Amount)),
|
hg_invoice_helper:start_invoice(PartyID, ShopID, Product, Due, Amount, Client).
|
||||||
InvoiceID = create_invoice(InvoiceParams, Client),
|
|
||||||
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),
|
|
||||||
InvoiceID.
|
|
||||||
|
|
||||||
start_payment(InvoiceID, PaymentParams, Client) ->
|
start_payment(InvoiceID, PaymentParams, Client) ->
|
||||||
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
hg_invoice_helper:start_payment(InvoiceID, PaymentParams, Client).
|
||||||
_ = start_payment_ev(InvoiceID, Client),
|
|
||||||
?payment_ev(PaymentID, ?cash_flow_changed(_)) =
|
|
||||||
next_change(InvoiceID, Client),
|
|
||||||
PaymentID.
|
|
||||||
|
|
||||||
register_payment(InvoiceID, RegisterPaymentParams, WithRiskScoring, Client) ->
|
register_payment(InvoiceID, RegisterPaymentParams, WithRiskScoring, Client) ->
|
||||||
?payment_state(?payment(PaymentID)) =
|
hg_invoice_helper:register_payment(InvoiceID, RegisterPaymentParams, WithRiskScoring, Client).
|
||||||
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.
|
|
||||||
|
|
||||||
start_payment_ev(InvoiceID, Client) ->
|
start_payment_ev(InvoiceID, Client) ->
|
||||||
[
|
hg_invoice_helper: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.
|
|
||||||
|
|
||||||
start_payment_ev_no_risk_scoring(InvoiceID, Client) ->
|
start_payment_ev_no_risk_scoring(InvoiceID, Client) ->
|
||||||
[
|
hg_invoice_helper: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.
|
|
||||||
|
|
||||||
process_payment(InvoiceID, PaymentParams, Client) ->
|
process_payment(InvoiceID, PaymentParams, Client) ->
|
||||||
PaymentID = start_payment(InvoiceID, PaymentParams, Client),
|
hg_invoice_helper:process_payment(InvoiceID, PaymentParams, Client).
|
||||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
|
||||||
PaymentID = await_payment_process_finish(InvoiceID, PaymentID, Client).
|
|
||||||
|
|
||||||
await_payment_started(InvoiceID, PaymentID, Client) ->
|
await_payment_started(InvoiceID, PaymentID, Client) ->
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
||||||
@ -6994,12 +6470,7 @@ await_payment_started(InvoiceID, PaymentID, Client) ->
|
|||||||
PaymentID.
|
PaymentID.
|
||||||
|
|
||||||
await_payment_cash_flow(InvoiceID, PaymentID, Client) ->
|
await_payment_cash_flow(InvoiceID, PaymentID, Client) ->
|
||||||
[
|
hg_invoice_helper: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}.
|
|
||||||
|
|
||||||
await_payment_cash_flow(RS, Route, InvoiceID, PaymentID, Client) ->
|
await_payment_cash_flow(RS, Route, InvoiceID, PaymentID, Client) ->
|
||||||
[
|
[
|
||||||
@ -7018,9 +6489,7 @@ await_payment_rollback(InvoiceID, PaymentID, Client) ->
|
|||||||
Failure.
|
Failure.
|
||||||
|
|
||||||
await_payment_session_started(InvoiceID, PaymentID, Client, Target) ->
|
await_payment_session_started(InvoiceID, PaymentID, Client, Target) ->
|
||||||
?payment_ev(PaymentID, ?session_ev(Target, ?session_started())) =
|
hg_invoice_helper:await_payment_session_started(InvoiceID, PaymentID, Client, Target).
|
||||||
next_change(InvoiceID, Client),
|
|
||||||
PaymentID.
|
|
||||||
|
|
||||||
await_payment_process_interaction(InvoiceID, PaymentID, Client) ->
|
await_payment_process_interaction(InvoiceID, PaymentID, Client) ->
|
||||||
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_started())) =
|
?payment_ev(PaymentID, ?session_ev(?processed(), ?session_started())) =
|
||||||
@ -7033,12 +6502,7 @@ await_payment_process_interaction(InvoiceID, PaymentID, Client) ->
|
|||||||
UserInteraction.
|
UserInteraction.
|
||||||
|
|
||||||
await_payment_process_finish(InvoiceID, PaymentID, Client) ->
|
await_payment_process_finish(InvoiceID, PaymentID, Client) ->
|
||||||
[
|
hg_invoice_helper: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.
|
|
||||||
|
|
||||||
await_payment_process_interaction_completion(InvoiceID, PaymentID, UserInteraction, Client) ->
|
await_payment_process_interaction_completion(InvoiceID, PaymentID, UserInteraction, Client) ->
|
||||||
?payment_ev(
|
?payment_ev(
|
||||||
@ -7051,21 +6515,13 @@ await_payment_process_interaction_completion(InvoiceID, PaymentID, UserInteracti
|
|||||||
ok.
|
ok.
|
||||||
|
|
||||||
await_payment_capture(InvoiceID, PaymentID, Client) ->
|
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, 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) ->
|
await_payment_capture(InvoiceID, PaymentID, Reason, TrxID, Client) ->
|
||||||
Cost = get_payment_cost(InvoiceID, PaymentID, Client),
|
hg_invoice_helper:await_payment_capture(InvoiceID, PaymentID, Reason, TrxID, 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).
|
|
||||||
|
|
||||||
await_payment_partial_capture(InvoiceID, PaymentID, Reason, Cash, 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, Cash, Client).
|
||||||
|
|
||||||
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Client) ->
|
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Client) ->
|
||||||
Cost = get_payment_cost(InvoiceID, PaymentID, 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, 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) ->
|
await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, Cart, Client) ->
|
||||||
[
|
hg_invoice_helper: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.
|
|
||||||
|
|
||||||
await_payment_cancel(InvoiceID, PaymentID, Reason, Client) ->
|
await_payment_cancel(InvoiceID, PaymentID, Reason, Client) ->
|
||||||
[
|
[
|
||||||
@ -7221,43 +6671,7 @@ get_post_request(?payterm_receipt(SPID)) ->
|
|||||||
{URL, #{<<"tag">> => SPID}}.
|
{URL, #{<<"tag">> => SPID}}.
|
||||||
|
|
||||||
make_customer_w_rec_tool(PartyID, ShopID, Client, PmtSys) ->
|
make_customer_w_rec_tool(PartyID, ShopID, Client, PmtSys) ->
|
||||||
CustomerParams = hg_ct_helper:make_customer_params(PartyID, ShopID, <<"InvoicingTests">>),
|
hg_invoice_helper:make_customer_w_rec_tool(PartyID, ShopID, Client, PmtSys).
|
||||||
#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.
|
|
||||||
|
|
||||||
invoice_create_and_get_revision(PartyID, Client, ShopID) ->
|
invoice_create_and_get_revision(PartyID, Client, ShopID) ->
|
||||||
InvoiceParams = make_invoice_params(PartyID, ShopID, <<"somePlace">>, make_due_date(10), make_cash(5000)),
|
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}.
|
{InvoiceRev, InvoiceID}.
|
||||||
|
|
||||||
execute_payment(InvoiceID, Params, Client) ->
|
execute_payment(InvoiceID, Params, Client) ->
|
||||||
PaymentID = process_payment(InvoiceID, Params, Client),
|
hg_invoice_helper:execute_payment(InvoiceID, Params, Client).
|
||||||
PaymentID = await_payment_capture(InvoiceID, PaymentID, Client),
|
|
||||||
PaymentID.
|
|
||||||
|
|
||||||
execute_payment_w_cascade(InvoiceID, Params, Client, CascadeCount) when CascadeCount > 0 ->
|
execute_payment_w_cascade(InvoiceID, Params, Client, CascadeCount) when CascadeCount > 0 ->
|
||||||
#payproc_InvoicePayment{payment = _Payment} = hg_client_invoicing:start_payment(InvoiceID, Params, Client),
|
#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) ->
|
get_payment_cashflow_mapped(InvoiceID, PaymentID, Client) ->
|
||||||
#payproc_InvoicePayment{
|
#payproc_InvoicePayment{
|
||||||
cash_flow = CashFlow
|
cash_flow = CashFlow
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
hg_ct_helper,
|
hg_ct_helper,
|
||||||
hg_customer_tests_SUITE,
|
hg_customer_tests_SUITE,
|
||||||
hg_recurrent_paytools_tests_SUITE,
|
hg_recurrent_paytools_tests_SUITE,
|
||||||
hg_invoice_tests_SUITE
|
hg_invoice_tests_SUITE,
|
||||||
|
hg_invoice_helper
|
||||||
]
|
]
|
||||||
}},
|
}},
|
||||||
{elvis_style, no_if_expression},
|
{elvis_style, no_if_expression},
|
||||||
@ -37,7 +38,8 @@
|
|||||||
hg_routing,
|
hg_routing,
|
||||||
hg_route_rules_tests_SUITE,
|
hg_route_rules_tests_SUITE,
|
||||||
hg_invoice_tests_SUITE,
|
hg_invoice_tests_SUITE,
|
||||||
hg_allocation_tests
|
hg_allocation_tests,
|
||||||
|
hg_invoice_helper
|
||||||
]
|
]
|
||||||
}},
|
}},
|
||||||
{elvis_style, no_debug_call, #{}}
|
{elvis_style, no_debug_call, #{}}
|
||||||
|
Loading…
Reference in New Issue
Block a user