mirror of
https://github.com/valitydev/hellgate.git
synced 2024-11-06 02:45:20 +00:00
OPS-442: Add shop limits (#121)
* OPS-442: Add shop limits * Fix tests and specs * Add tests * Format * Add regression test * Fix * Update PM image
This commit is contained in:
parent
55899c876c
commit
50480643a5
@ -29,7 +29,8 @@
|
|||||||
timings :: undefined | hg_timings:t(),
|
timings :: undefined | hg_timings:t(),
|
||||||
allocation :: undefined | hg_allocation:allocation(),
|
allocation :: undefined | hg_allocation:allocation(),
|
||||||
route_limits = #{} :: hg_routing:limits(),
|
route_limits = #{} :: hg_routing:limits(),
|
||||||
route_scores = #{} :: hg_routing:scores()
|
route_scores = #{} :: hg_routing:scores(),
|
||||||
|
shop_limit_status = undefined :: undefined | initialized | finalized
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-record(refund_st, {
|
-record(refund_st, {
|
||||||
|
@ -51,6 +51,20 @@
|
|||||||
}}
|
}}
|
||||||
).
|
).
|
||||||
|
|
||||||
|
-define(shop_limit_initiated(),
|
||||||
|
{
|
||||||
|
invoice_payment_shop_limit_initiated,
|
||||||
|
#payproc_InvoicePaymentShopLimitInitiated{}
|
||||||
|
}
|
||||||
|
).
|
||||||
|
|
||||||
|
-define(shop_limit_applied(),
|
||||||
|
{
|
||||||
|
invoice_payment_shop_limit_applied,
|
||||||
|
#payproc_InvoicePaymentShopLimitApplied{}
|
||||||
|
}
|
||||||
|
).
|
||||||
|
|
||||||
-define(cash_flow_changed(CashFlow),
|
-define(cash_flow_changed(CashFlow),
|
||||||
{invoice_payment_cash_flow_changed, #payproc_InvoicePaymentCashFlowChanged{
|
{invoice_payment_cash_flow_changed, #payproc_InvoicePaymentCashFlowChanged{
|
||||||
cash_flow = CashFlow
|
cash_flow = CashFlow
|
||||||
|
@ -148,6 +148,9 @@
|
|||||||
|
|
||||||
-type payment_step() ::
|
-type payment_step() ::
|
||||||
new
|
new
|
||||||
|
| shop_limit_initializing
|
||||||
|
| shop_limit_failure
|
||||||
|
| shop_limit_finalizing
|
||||||
| risk_scoring
|
| risk_scoring
|
||||||
| routing
|
| routing
|
||||||
| routing_failure
|
| routing_failure
|
||||||
@ -1813,6 +1816,12 @@ process_timeout(St) ->
|
|||||||
repair_process_timeout(get_activity(St), Action, St).
|
repair_process_timeout(get_activity(St), Action, St).
|
||||||
|
|
||||||
-spec process_timeout(activity(), action(), st()) -> machine_result().
|
-spec process_timeout(activity(), action(), st()) -> machine_result().
|
||||||
|
process_timeout({payment, shop_limit_initializing}, Action, St) ->
|
||||||
|
process_shop_limit_initialization(Action, St);
|
||||||
|
process_timeout({payment, shop_limit_failure}, Action, St) ->
|
||||||
|
process_shop_limit_failure(Action, St);
|
||||||
|
process_timeout({payment, shop_limit_finalizing}, Action, St) ->
|
||||||
|
process_shop_limit_finalization(Action, St);
|
||||||
process_timeout({payment, risk_scoring}, Action, St) ->
|
process_timeout({payment, risk_scoring}, Action, St) ->
|
||||||
process_risk_score(Action, St);
|
process_risk_score(Action, St);
|
||||||
process_timeout({payment, routing}, Action, St) ->
|
process_timeout({payment, routing}, Action, St) ->
|
||||||
@ -1924,6 +1933,39 @@ process_callback(_Tag, _Payload, undefined, _St) ->
|
|||||||
throw(invalid_callback).
|
throw(invalid_callback).
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
-spec process_shop_limit_initialization(action(), st()) -> machine_result().
|
||||||
|
process_shop_limit_initialization(Action, St) ->
|
||||||
|
Opts = get_opts(St),
|
||||||
|
_ = hold_shop_limits(Opts, St),
|
||||||
|
case check_shop_limits(Opts, St) of
|
||||||
|
ok ->
|
||||||
|
{next, {[?shop_limit_initiated()], hg_machine_action:set_timeout(0, Action)}};
|
||||||
|
{error, {limit_overflow = Error, IDs}} ->
|
||||||
|
Failure = construct_shop_limit_failure(Error, IDs),
|
||||||
|
Events = [
|
||||||
|
?shop_limit_initiated(),
|
||||||
|
?payment_rollback_started(Failure)
|
||||||
|
],
|
||||||
|
{next, {Events, hg_machine_action:set_timeout(0, Action)}}
|
||||||
|
end.
|
||||||
|
|
||||||
|
construct_shop_limit_failure(limit_overflow, IDs) ->
|
||||||
|
Error = mk_static_error([authorization_failed, shop_limit_exceeded, unknown]),
|
||||||
|
Reason = genlib:format("Limits with following IDs overflowed: ~p", [IDs]),
|
||||||
|
{failure, payproc_errors:construct('PaymentFailure', Error, Reason)}.
|
||||||
|
|
||||||
|
process_shop_limit_failure(Action, St = #st{failure = Failure}) ->
|
||||||
|
Opts = get_opts(St),
|
||||||
|
_ = rollback_shop_limits(Opts, St, [ignore_business_error, ignore_not_found]),
|
||||||
|
{done, {[?payment_status_changed(?failed(Failure))], hg_machine_action:set_timeout(0, Action)}}.
|
||||||
|
|
||||||
|
-spec process_shop_limit_finalization(action(), st()) -> machine_result().
|
||||||
|
process_shop_limit_finalization(Action, St) ->
|
||||||
|
Opts = get_opts(St),
|
||||||
|
_ = commit_shop_limits(Opts, St),
|
||||||
|
{next, {[?shop_limit_applied()], hg_machine_action:set_timeout(0, Action)}}.
|
||||||
|
|
||||||
-spec process_risk_score(action(), st()) -> machine_result().
|
-spec process_risk_score(action(), st()) -> machine_result().
|
||||||
process_risk_score(Action, St) ->
|
process_risk_score(Action, St) ->
|
||||||
Opts = get_opts(St),
|
Opts = get_opts(St),
|
||||||
@ -2551,6 +2593,52 @@ get_limit_overflow_routes(Routes, VS, St) ->
|
|||||||
Routes
|
Routes
|
||||||
).
|
).
|
||||||
|
|
||||||
|
%% Shop limits
|
||||||
|
|
||||||
|
hold_shop_limits(Opts, St) ->
|
||||||
|
Payment = get_payment(St),
|
||||||
|
Invoice = get_invoice(Opts),
|
||||||
|
Party = get_party(Opts),
|
||||||
|
Shop = get_shop(Opts),
|
||||||
|
TurnoverLimits = get_shop_turnover_limits(Shop),
|
||||||
|
ok = hg_limiter:hold_shop_limits(TurnoverLimits, Party, Shop, Invoice, Payment).
|
||||||
|
|
||||||
|
commit_shop_limits(Opts, St) ->
|
||||||
|
Payment = get_payment(St),
|
||||||
|
Invoice = get_invoice(Opts),
|
||||||
|
Party = get_party(Opts),
|
||||||
|
Shop = get_shop(Opts),
|
||||||
|
TurnoverLimits = get_shop_turnover_limits(Shop),
|
||||||
|
ok = hg_limiter:commit_shop_limits(TurnoverLimits, Party, Shop, Invoice, Payment).
|
||||||
|
|
||||||
|
check_shop_limits(Opts, St) ->
|
||||||
|
Payment = get_payment(St),
|
||||||
|
Invoice = get_invoice(Opts),
|
||||||
|
TurnoverLimits = get_shop_turnover_limits(get_shop(Opts)),
|
||||||
|
hg_limiter:check_shop_limits(TurnoverLimits, Invoice, Payment).
|
||||||
|
|
||||||
|
rollback_shop_limits(Opts, St, Flags) ->
|
||||||
|
Payment = get_payment(St),
|
||||||
|
Invoice = get_invoice(Opts),
|
||||||
|
Party = get_party(Opts),
|
||||||
|
Shop = get_shop(Opts),
|
||||||
|
TurnoverLimits = get_shop_turnover_limits(Shop),
|
||||||
|
ok = hg_limiter:rollback_shop_limits(
|
||||||
|
TurnoverLimits,
|
||||||
|
Party,
|
||||||
|
Shop,
|
||||||
|
Invoice,
|
||||||
|
Payment,
|
||||||
|
Flags
|
||||||
|
).
|
||||||
|
|
||||||
|
get_shop_turnover_limits(#domain_Shop{turnover_limits = undefined}) ->
|
||||||
|
[];
|
||||||
|
get_shop_turnover_limits(#domain_Shop{turnover_limits = T}) ->
|
||||||
|
ordsets:to_list(T).
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
-spec hold_limit_routes([hg_route:t()], hg_varset:varset(), pos_integer(), st()) ->
|
-spec hold_limit_routes([hg_route:t()], hg_varset:varset(), pos_integer(), st()) ->
|
||||||
{[hg_route:t()], [hg_route:rejected_route()]}.
|
{[hg_route:t()], [hg_route:rejected_route()]}.
|
||||||
hold_limit_routes(Routes0, VS, Iter, St) ->
|
hold_limit_routes(Routes0, VS, Iter, St) ->
|
||||||
@ -2979,11 +3067,35 @@ merge_change(Change = ?payment_started(Payment), #st{} = St, Opts) ->
|
|||||||
St#st{
|
St#st{
|
||||||
target = ?processed(),
|
target = ?processed(),
|
||||||
payment = Payment,
|
payment = Payment,
|
||||||
activity = {payment, risk_scoring},
|
activity = {payment, shop_limit_initializing},
|
||||||
timings = hg_timings:mark(started, define_event_timestamp(Opts))
|
timings = hg_timings:mark(started, define_event_timestamp(Opts))
|
||||||
};
|
};
|
||||||
|
merge_change(Change = ?shop_limit_initiated(), #st{} = St, Opts) ->
|
||||||
|
_ = validate_transition({payment, shop_limit_initializing}, Change, St, Opts),
|
||||||
|
St#st{
|
||||||
|
shop_limit_status = initialized,
|
||||||
|
activity = {payment, shop_limit_finalizing}
|
||||||
|
};
|
||||||
|
merge_change(Change = ?shop_limit_applied(), #st{} = St, Opts) ->
|
||||||
|
_ = validate_transition({payment, shop_limit_finalizing}, Change, St, Opts),
|
||||||
|
St#st{
|
||||||
|
shop_limit_status = finalized,
|
||||||
|
activity = {payment, risk_scoring}
|
||||||
|
};
|
||||||
merge_change(Change = ?risk_score_changed(RiskScore), #st{} = St, Opts) ->
|
merge_change(Change = ?risk_score_changed(RiskScore), #st{} = St, Opts) ->
|
||||||
_ = validate_transition({payment, risk_scoring}, Change, St, Opts),
|
_ = validate_transition(
|
||||||
|
[
|
||||||
|
{payment, S}
|
||||||
|
|| S <- [
|
||||||
|
risk_scoring,
|
||||||
|
%% Added for backward compatibility
|
||||||
|
shop_limit_initializing
|
||||||
|
]
|
||||||
|
],
|
||||||
|
Change,
|
||||||
|
St,
|
||||||
|
Opts
|
||||||
|
),
|
||||||
St#st{
|
St#st{
|
||||||
risk_score = RiskScore,
|
risk_score = RiskScore,
|
||||||
activity = {payment, routing}
|
activity = {payment, routing}
|
||||||
@ -3061,14 +3173,20 @@ merge_change(Change = ?cash_changed(_OldCash, NewCash), #st{} = St, Opts) ->
|
|||||||
St#st{new_cash = NewCash, new_cash_provided = true, payment = Payment1};
|
St#st{new_cash = NewCash, new_cash_provided = true, payment = Payment1};
|
||||||
merge_change(Change = ?payment_rollback_started(Failure), St, Opts) ->
|
merge_change(Change = ?payment_rollback_started(Failure), St, Opts) ->
|
||||||
_ = validate_transition(
|
_ = validate_transition(
|
||||||
[{payment, cash_flow_building}, {payment, processing_session}],
|
[
|
||||||
|
{payment, shop_limit_finalizing},
|
||||||
|
{payment, cash_flow_building},
|
||||||
|
{payment, processing_session}
|
||||||
|
],
|
||||||
Change,
|
Change,
|
||||||
St,
|
St,
|
||||||
Opts
|
Opts
|
||||||
),
|
),
|
||||||
Activity =
|
Activity =
|
||||||
case St#st.cash_flow of
|
case St of
|
||||||
undefined ->
|
#st{shop_limit_status = initialized} ->
|
||||||
|
{payment, shop_limit_failure};
|
||||||
|
#st{cash_flow = undefined} ->
|
||||||
{payment, routing_failure};
|
{payment, routing_failure};
|
||||||
_ ->
|
_ ->
|
||||||
{payment, processing_failure}
|
{payment, processing_failure}
|
||||||
@ -3086,6 +3204,7 @@ merge_change(Change = ?payment_status_changed({failed, _} = Status), #st{payment
|
|||||||
risk_scoring,
|
risk_scoring,
|
||||||
routing,
|
routing,
|
||||||
cash_flow_building,
|
cash_flow_building,
|
||||||
|
shop_limit_failure,
|
||||||
routing_failure,
|
routing_failure,
|
||||||
processing_failure
|
processing_failure
|
||||||
]
|
]
|
||||||
@ -3834,6 +3953,7 @@ get_route_cascade_behaviour(Route, Revision) ->
|
|||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("hellgate/test/hg_ct_domain.hrl").
|
||||||
|
|
||||||
-spec test() -> _.
|
-spec test() -> _.
|
||||||
|
|
||||||
@ -3925,4 +4045,50 @@ filter_attempted_routes_test_() ->
|
|||||||
)
|
)
|
||||||
].
|
].
|
||||||
|
|
||||||
|
-spec shop_limits_regression_test() -> _.
|
||||||
|
shop_limits_regression_test() ->
|
||||||
|
DisposableResource = #domain_DisposablePaymentResource{
|
||||||
|
payment_tool =
|
||||||
|
{generic, #domain_GenericPaymentTool{
|
||||||
|
payment_service = ?pmt_srv(<<"id">>)
|
||||||
|
}}
|
||||||
|
},
|
||||||
|
ContactInfo = #domain_ContactInfo{},
|
||||||
|
Payment = #domain_InvoicePayment{
|
||||||
|
id = <<"PaymentID">>,
|
||||||
|
created_at = <<"Timestamp">>,
|
||||||
|
status = ?pending(),
|
||||||
|
cost = ?cash(1000, <<"USD">>),
|
||||||
|
domain_revision = 1,
|
||||||
|
flow = ?invoice_payment_flow_instant(),
|
||||||
|
payer = ?payment_resource_payer(DisposableResource, ContactInfo)
|
||||||
|
},
|
||||||
|
RiskScore = low,
|
||||||
|
Route = #domain_PaymentRoute{
|
||||||
|
provider = ?prv(1),
|
||||||
|
terminal = ?trm(1)
|
||||||
|
},
|
||||||
|
FinalCashflow = [],
|
||||||
|
TransactionInfo = #domain_TransactionInfo{
|
||||||
|
id = <<"TransactionID">>,
|
||||||
|
extra = #{}
|
||||||
|
},
|
||||||
|
Events = [
|
||||||
|
?payment_started(Payment),
|
||||||
|
?risk_score_changed(RiskScore),
|
||||||
|
?route_changed(Route),
|
||||||
|
?cash_flow_changed(FinalCashflow),
|
||||||
|
hg_session:wrap_event(?processed(), hg_session:create()),
|
||||||
|
hg_session:wrap_event(?processed(), ?trx_bound(TransactionInfo)),
|
||||||
|
hg_session:wrap_event(?processed(), ?session_finished(?session_succeeded())),
|
||||||
|
?payment_status_changed(?processed())
|
||||||
|
],
|
||||||
|
ChangeOpts = #{
|
||||||
|
invoice_id => <<"InvoiceID">>
|
||||||
|
},
|
||||||
|
?assertMatch(
|
||||||
|
#st{},
|
||||||
|
collapse_changes(Events, undefined, ChangeOpts)
|
||||||
|
).
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
@ -85,7 +85,9 @@ init_(PaymentID, Params, Opts = #{timestamp := CreatedAt0}) ->
|
|||||||
|
|
||||||
Events =
|
Events =
|
||||||
[
|
[
|
||||||
?payment_started(Payment)
|
?payment_started(Payment),
|
||||||
|
?shop_limit_initiated(),
|
||||||
|
?shop_limit_applied()
|
||||||
] ++
|
] ++
|
||||||
RiskScoreEventList ++
|
RiskScoreEventList ++
|
||||||
[
|
[
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
-type cash() :: dmsl_domain_thrift:'Cash'().
|
-type cash() :: dmsl_domain_thrift:'Cash'().
|
||||||
-type handling_flag() :: ignore_business_error | ignore_not_found.
|
-type handling_flag() :: ignore_business_error | ignore_not_found.
|
||||||
-type turnover_limit_value() :: dmsl_payproc_thrift:'TurnoverLimitValue'().
|
-type turnover_limit_value() :: dmsl_payproc_thrift:'TurnoverLimitValue'().
|
||||||
|
-type party() :: hg_party:party().
|
||||||
|
-type shop() :: dmsl_domain_thrift:'Shop'().
|
||||||
|
|
||||||
-type change_queue() :: [hg_limiter_client:limit_change()].
|
-type change_queue() :: [hg_limiter_client:limit_change()].
|
||||||
|
|
||||||
@ -23,11 +25,15 @@
|
|||||||
|
|
||||||
-export([get_turnover_limits/1]).
|
-export([get_turnover_limits/1]).
|
||||||
-export([check_limits/4]).
|
-export([check_limits/4]).
|
||||||
|
-export([check_shop_limits/3]).
|
||||||
-export([hold_payment_limits/5]).
|
-export([hold_payment_limits/5]).
|
||||||
|
-export([hold_shop_limits/5]).
|
||||||
-export([hold_refund_limits/5]).
|
-export([hold_refund_limits/5]).
|
||||||
-export([commit_payment_limits/6]).
|
-export([commit_payment_limits/6]).
|
||||||
|
-export([commit_shop_limits/5]).
|
||||||
-export([commit_refund_limits/5]).
|
-export([commit_refund_limits/5]).
|
||||||
-export([rollback_payment_limits/6]).
|
-export([rollback_payment_limits/6]).
|
||||||
|
-export([rollback_shop_limits/6]).
|
||||||
-export([rollback_refund_limits/5]).
|
-export([rollback_refund_limits/5]).
|
||||||
-export([get_limit_values/4]).
|
-export([get_limit_values/4]).
|
||||||
|
|
||||||
@ -36,6 +42,14 @@
|
|||||||
terminal = TerminalRef
|
terminal = TerminalRef
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
-define(party(PartyID), #domain_Party{
|
||||||
|
id = PartyID
|
||||||
|
}).
|
||||||
|
|
||||||
|
-define(shop(ShopID), #domain_Shop{
|
||||||
|
id = ShopID
|
||||||
|
}).
|
||||||
|
|
||||||
-spec get_turnover_limits(turnover_selector() | undefined) -> [turnover_limit()].
|
-spec get_turnover_limits(turnover_selector() | undefined) -> [turnover_limit()].
|
||||||
get_turnover_limits(undefined) ->
|
get_turnover_limits(undefined) ->
|
||||||
[];
|
[];
|
||||||
@ -76,6 +90,21 @@ check_limits(TurnoverLimits, Invoice, Payment, Route) ->
|
|||||||
{error, {limit_overflow, IDs, Limits}}
|
{error, {limit_overflow, IDs, Limits}}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec check_shop_limits([turnover_limit()], invoice(), payment()) ->
|
||||||
|
ok
|
||||||
|
| {error, {limit_overflow, [binary()]}}.
|
||||||
|
check_shop_limits(TurnoverLimits, Invoice, Payment) ->
|
||||||
|
Context = gen_limit_shop_context(Invoice, Payment),
|
||||||
|
{ok, Limits} = gather_limits(TurnoverLimits, Context, []),
|
||||||
|
try
|
||||||
|
ok = check_limits_(Limits, Context),
|
||||||
|
ok
|
||||||
|
catch
|
||||||
|
throw:limit_overflow ->
|
||||||
|
IDs = [T#domain_TurnoverLimit.id || T <- TurnoverLimits],
|
||||||
|
{error, {limit_overflow, IDs}}
|
||||||
|
end.
|
||||||
|
|
||||||
check_limits_([], _) ->
|
check_limits_([], _) ->
|
||||||
ok;
|
ok;
|
||||||
check_limits_([TurnoverLimitValue | TLVs], Context) ->
|
check_limits_([TurnoverLimitValue | TLVs], Context) ->
|
||||||
@ -114,6 +143,13 @@ hold_payment_limits(TurnoverLimits, Route, Iter, Invoice, Payment) ->
|
|||||||
Context = gen_limit_context(Invoice, Payment, Route),
|
Context = gen_limit_context(Invoice, Payment, Route),
|
||||||
hold(LimitChanges, get_latest_clock(), Context).
|
hold(LimitChanges, get_latest_clock(), Context).
|
||||||
|
|
||||||
|
-spec hold_shop_limits([turnover_limit()], party(), shop(), invoice(), payment()) -> ok.
|
||||||
|
hold_shop_limits(TurnoverLimits, Party, Shop, Invoice, Payment) ->
|
||||||
|
ChangeIDs = [construct_shop_change_id(Party, Shop, Invoice, Payment)],
|
||||||
|
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs),
|
||||||
|
Context = gen_limit_shop_context(Invoice, Payment),
|
||||||
|
hold(LimitChanges, get_latest_clock(), Context).
|
||||||
|
|
||||||
-spec hold_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok.
|
-spec hold_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok.
|
||||||
hold_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
|
hold_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
|
||||||
ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)],
|
ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)],
|
||||||
@ -133,6 +169,16 @@ commit_payment_limits(TurnoverLimits, Route, Iter, Invoice, Payment, CapturedCas
|
|||||||
ok = commit(LimitChanges, Clock, Context),
|
ok = commit(LimitChanges, Clock, Context),
|
||||||
ok = log_limit_changes(TurnoverLimits, Clock, Context).
|
ok = log_limit_changes(TurnoverLimits, Clock, Context).
|
||||||
|
|
||||||
|
-spec commit_shop_limits([turnover_limit()], party(), shop(), invoice(), payment()) -> ok.
|
||||||
|
commit_shop_limits(TurnoverLimits, Party, Shop, Invoice, Payment) ->
|
||||||
|
ChangeIDs = [construct_shop_change_id(Party, Shop, Invoice, Payment)],
|
||||||
|
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs),
|
||||||
|
Context = gen_limit_shop_context(Invoice, Payment),
|
||||||
|
Clock = get_latest_clock(),
|
||||||
|
ok = commit(LimitChanges, Clock, Context),
|
||||||
|
ok = log_limit_changes(TurnoverLimits, Clock, Context),
|
||||||
|
ok.
|
||||||
|
|
||||||
-spec commit_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok.
|
-spec commit_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok.
|
||||||
commit_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
|
commit_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
|
||||||
ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)],
|
ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)],
|
||||||
@ -161,6 +207,14 @@ rollback_payment_limits(TurnoverLimits, Route, Iter, Invoice, Payment, Flags) ->
|
|||||||
Context = gen_limit_context(Invoice, Payment, Route),
|
Context = gen_limit_context(Invoice, Payment, Route),
|
||||||
rollback(LimitChanges, get_latest_clock(), Context, Flags).
|
rollback(LimitChanges, get_latest_clock(), Context, Flags).
|
||||||
|
|
||||||
|
-spec rollback_shop_limits([turnover_limit()], party(), shop(), invoice(), payment(), [handling_flag()]) ->
|
||||||
|
ok.
|
||||||
|
rollback_shop_limits(TurnoverLimits, Party, Shop, Invoice, Payment, Flags) ->
|
||||||
|
ChangeIDs = [construct_shop_change_id(Party, Shop, Invoice, Payment)],
|
||||||
|
LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs),
|
||||||
|
Context = gen_limit_shop_context(Invoice, Payment),
|
||||||
|
rollback(LimitChanges, get_latest_clock(), Context, Flags).
|
||||||
|
|
||||||
-spec rollback_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok.
|
-spec rollback_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok.
|
||||||
rollback_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
|
rollback_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
|
||||||
ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)],
|
ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)],
|
||||||
@ -238,6 +292,19 @@ gen_limit_context(Invoice, Payment, Route, CapturedCash) ->
|
|||||||
}
|
}
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
gen_limit_shop_context(Invoice, Payment) ->
|
||||||
|
#limiter_LimitContext{
|
||||||
|
payment_processing = #context_payproc_Context{
|
||||||
|
op = {invoice_payment, #context_payproc_OperationInvoicePayment{}},
|
||||||
|
invoice = #context_payproc_Invoice{
|
||||||
|
invoice = Invoice,
|
||||||
|
payment = #context_payproc_InvoicePayment{
|
||||||
|
payment = Payment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.
|
||||||
|
|
||||||
gen_limit_refund_context(Invoice, Payment, Refund, Route) ->
|
gen_limit_refund_context(Invoice, Payment, Refund, Route) ->
|
||||||
PaymentCtx = #context_payproc_InvoicePayment{
|
PaymentCtx = #context_payproc_InvoicePayment{
|
||||||
payment = Payment,
|
payment = Payment,
|
||||||
@ -290,6 +357,14 @@ construct_payment_change_id(?route(ProviderRef, TerminalRef), Iter, Invoice, Pay
|
|||||||
integer_to_binary(Iter)
|
integer_to_binary(Iter)
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
construct_shop_change_id(?party(PartyID), ?shop(ShopID), Invoice, Payment) ->
|
||||||
|
hg_utils:construct_complex_id([
|
||||||
|
PartyID,
|
||||||
|
ShopID,
|
||||||
|
get_invoice_id(Invoice),
|
||||||
|
get_payment_id(Payment)
|
||||||
|
]).
|
||||||
|
|
||||||
construct_refund_change_id(Invoice, Payment, Refund) ->
|
construct_refund_change_id(Invoice, Payment, Refund) ->
|
||||||
hg_utils:construct_complex_id([
|
hg_utils:construct_complex_id([
|
||||||
get_invoice_id(Invoice),
|
get_invoice_id(Invoice),
|
||||||
@ -341,7 +416,7 @@ mk_limit_log_attributes(#limiter_LimitContext{
|
|||||||
payment = #context_payproc_InvoicePayment{
|
payment = #context_payproc_InvoicePayment{
|
||||||
payment = Payment,
|
payment = Payment,
|
||||||
refund = Refund,
|
refund = Refund,
|
||||||
route = #base_Route{provider = Provider, terminal = Terminal}
|
route = Route
|
||||||
}
|
}
|
||||||
} = CtxInvoice,
|
} = CtxInvoice,
|
||||||
#domain_Cash{amount = Amount, currency = Currency} =
|
#domain_Cash{amount = Amount, currency = Currency} =
|
||||||
@ -357,10 +432,7 @@ mk_limit_log_attributes(#limiter_LimitContext{
|
|||||||
boundary => undefined,
|
boundary => undefined,
|
||||||
%% Current amount with accounted change
|
%% Current amount with accounted change
|
||||||
amount => undefined,
|
amount => undefined,
|
||||||
route => #{
|
route => maybe_route_context(Route),
|
||||||
provider_id => Provider#domain_ProviderRef.id,
|
|
||||||
terminal_id => Terminal#domain_TerminalRef.id
|
|
||||||
},
|
|
||||||
party_id => PartyID,
|
party_id => PartyID,
|
||||||
shop_id => ShopID,
|
shop_id => ShopID,
|
||||||
change => #{
|
change => #{
|
||||||
@ -368,3 +440,11 @@ mk_limit_log_attributes(#limiter_LimitContext{
|
|||||||
currency => Currency#domain_CurrencyRef.symbolic_code
|
currency => Currency#domain_CurrencyRef.symbolic_code
|
||||||
}
|
}
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
maybe_route_context(undefined) ->
|
||||||
|
undefined;
|
||||||
|
maybe_route_context(#base_Route{provider = Provider, terminal = Terminal}) ->
|
||||||
|
#{
|
||||||
|
provider_id => Provider#domain_ProviderRef.id,
|
||||||
|
terminal_id => Terminal#domain_TerminalRef.id
|
||||||
|
}.
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
-export([create_party_and_shop/6]).
|
-export([create_party_and_shop/6]).
|
||||||
-export([create_party/2]).
|
-export([create_party/2]).
|
||||||
-export([create_shop/6]).
|
-export([create_shop/6]).
|
||||||
|
-export([create_shop/7]).
|
||||||
-export([create_battle_ready_shop/6]).
|
-export([create_battle_ready_shop/6]).
|
||||||
-export([adjust_contract/4]).
|
-export([adjust_contract/4]).
|
||||||
|
|
||||||
@ -350,6 +351,8 @@ create_client_w_context(RootUrl, WoodyCtx) ->
|
|||||||
-type party() :: dmsl_domain_thrift:'Party'().
|
-type party() :: dmsl_domain_thrift:'Party'().
|
||||||
-type contract_id() :: dmsl_domain_thrift:'ContractID'().
|
-type contract_id() :: dmsl_domain_thrift:'ContractID'().
|
||||||
-type contract_tpl() :: dmsl_domain_thrift:'ContractTemplateRef'().
|
-type contract_tpl() :: dmsl_domain_thrift:'ContractTemplateRef'().
|
||||||
|
-type turnover_limit() :: dmsl_domain_thrift:'TurnoverLimit'().
|
||||||
|
-type turnover_limits() :: ordsets:ordset(turnover_limit()).
|
||||||
-type shop_id() :: dmsl_domain_thrift:'ShopID'().
|
-type shop_id() :: dmsl_domain_thrift:'ShopID'().
|
||||||
-type category() :: dmsl_domain_thrift:'CategoryRef'().
|
-type category() :: dmsl_domain_thrift:'CategoryRef'().
|
||||||
-type cash() :: dmsl_domain_thrift:'Cash'().
|
-type cash() :: dmsl_domain_thrift:'Cash'().
|
||||||
@ -390,9 +393,34 @@ create_shop(PartyID, Category, Currency, TemplateRef, PaymentInstRef, PartyClien
|
|||||||
{ok, _Claim} = party_client_thrift:create_claim(PartyID, Changeset, Client, Context),
|
{ok, _Claim} = party_client_thrift:create_claim(PartyID, Changeset, Client, Context),
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
create_shop_(PartyID, Category, Currency, TemplateRef, PaymentInstRef, PartyClient, Fun).
|
create_shop_(PartyID, Category, Currency, TemplateRef, PaymentInstRef, undefined, PartyClient, Fun).
|
||||||
|
|
||||||
create_shop_(PartyID, Category, Currency, TemplateRef, PaymentInstRef, {Client, Context}, CreateShopFun) ->
|
-spec create_shop(
|
||||||
|
party_id(),
|
||||||
|
category(),
|
||||||
|
currency(),
|
||||||
|
contract_tpl(),
|
||||||
|
payment_inst_ref(),
|
||||||
|
turnover_limits(),
|
||||||
|
party_client()
|
||||||
|
) -> shop_id().
|
||||||
|
create_shop(PartyID, Category, Currency, TemplateRef, PaymentInstRef, TurnoverLimits, PartyClient) ->
|
||||||
|
Fun = fun(_, Changeset, Client, Context) ->
|
||||||
|
{ok, _Claim} = party_client_thrift:create_claim(PartyID, Changeset, Client, Context),
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
create_shop_(PartyID, Category, Currency, TemplateRef, PaymentInstRef, TurnoverLimits, PartyClient, Fun).
|
||||||
|
|
||||||
|
create_shop_(
|
||||||
|
PartyID,
|
||||||
|
Category,
|
||||||
|
Currency,
|
||||||
|
TemplateRef,
|
||||||
|
PaymentInstRef,
|
||||||
|
TurnoverLimits0,
|
||||||
|
{Client, Context},
|
||||||
|
CreateShopFun
|
||||||
|
) ->
|
||||||
ShopID = hg_utils:unique_id(),
|
ShopID = hg_utils:unique_id(),
|
||||||
ContractID = hg_utils:unique_id(),
|
ContractID = hg_utils:unique_id(),
|
||||||
PayoutToolID = hg_utils:unique_id(),
|
PayoutToolID = hg_utils:unique_id(),
|
||||||
@ -403,6 +431,8 @@ create_shop_(PartyID, Category, Currency, TemplateRef, PaymentInstRef, {Client,
|
|||||||
ContractParams = make_contract_params(TemplateRef, PaymentInstRef),
|
ContractParams = make_contract_params(TemplateRef, PaymentInstRef),
|
||||||
PayoutToolParams = make_payout_tool_params(),
|
PayoutToolParams = make_payout_tool_params(),
|
||||||
|
|
||||||
|
TurnoverLimits1 = genlib:define(TurnoverLimits0, ordsets:new()),
|
||||||
|
|
||||||
Changeset = [
|
Changeset = [
|
||||||
{contract_modification, #payproc_ContractModificationUnit{
|
{contract_modification, #payproc_ContractModificationUnit{
|
||||||
id = ContractID,
|
id = ContractID,
|
||||||
@ -417,7 +447,8 @@ create_shop_(PartyID, Category, Currency, TemplateRef, PaymentInstRef, {Client,
|
|||||||
}}
|
}}
|
||||||
}},
|
}},
|
||||||
?shop_modification(ShopID, {creation, ShopParams}),
|
?shop_modification(ShopID, {creation, ShopParams}),
|
||||||
?shop_modification(ShopID, {shop_account_creation, ShopAccountParams})
|
?shop_modification(ShopID, {shop_account_creation, ShopAccountParams}),
|
||||||
|
?shop_modification(ShopID, {turnover_limits_modification, TurnoverLimits1})
|
||||||
],
|
],
|
||||||
|
|
||||||
ok = CreateShopFun(PartyID, Changeset, Client, Context),
|
ok = CreateShopFun(PartyID, Changeset, Client, Context),
|
||||||
@ -465,7 +496,7 @@ create_battle_ready_shop(PartyID, Category, Currency, TemplateRef, PaymentInstRe
|
|||||||
Fun = fun(_, Changeset, _, _) ->
|
Fun = fun(_, Changeset, _, _) ->
|
||||||
create_claim(PartyID, Changeset, PartyPair)
|
create_claim(PartyID, Changeset, PartyPair)
|
||||||
end,
|
end,
|
||||||
create_shop_(PartyID, Category, Currency, TemplateRef, PaymentInstRef, PartyPair, Fun).
|
create_shop_(PartyID, Category, Currency, TemplateRef, PaymentInstRef, undefined, PartyPair, Fun).
|
||||||
|
|
||||||
-spec adjust_contract(party_id(), contract_id(), contract_tpl(), party_client()) -> ok.
|
-spec adjust_contract(party_id(), contract_id(), contract_tpl(), party_client()) -> ok.
|
||||||
adjust_contract(PartyID, ContractID, TemplateRef, Client) ->
|
adjust_contract(PartyID, ContractID, TemplateRef, Client) ->
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
register_payment/4,
|
register_payment/4,
|
||||||
start_payment/3,
|
start_payment/3,
|
||||||
start_payment_ev/2,
|
start_payment_ev/2,
|
||||||
start_payment_ev_no_risk_scoring/2,
|
register_payment_ev_no_risk_scoring/2,
|
||||||
await_payment_session_started/4,
|
await_payment_session_started/4,
|
||||||
await_payment_capture/3,
|
await_payment_capture/3,
|
||||||
await_payment_capture/4,
|
await_payment_capture/4,
|
||||||
@ -237,7 +237,7 @@ register_payment(InvoiceID, RegisterPaymentParams, WithRiskScoring, Client) ->
|
|||||||
true ->
|
true ->
|
||||||
start_payment_ev(InvoiceID, Client);
|
start_payment_ev(InvoiceID, Client);
|
||||||
false ->
|
false ->
|
||||||
start_payment_ev_no_risk_scoring(InvoiceID, Client)
|
register_payment_ev_no_risk_scoring(InvoiceID, Client)
|
||||||
end,
|
end,
|
||||||
?payment_ev(PaymentID, ?cash_flow_changed(_)) =
|
?payment_ev(PaymentID, ?cash_flow_changed(_)) =
|
||||||
next_change(InvoiceID, Client),
|
next_change(InvoiceID, Client),
|
||||||
@ -255,17 +255,21 @@ start_payment(InvoiceID, PaymentParams, Client) ->
|
|||||||
start_payment_ev(InvoiceID, Client) ->
|
start_payment_ev(InvoiceID, Client) ->
|
||||||
[
|
[
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_RiskScore)),
|
?payment_ev(PaymentID, ?risk_score_changed(_RiskScore)),
|
||||||
?payment_ev(PaymentID, ?route_changed(Route))
|
?payment_ev(PaymentID, ?route_changed(Route))
|
||||||
] = next_changes(InvoiceID, 3, Client),
|
] = next_changes(InvoiceID, 5, Client),
|
||||||
Route.
|
Route.
|
||||||
|
|
||||||
-spec start_payment_ev_no_risk_scoring(_, _) -> _.
|
-spec register_payment_ev_no_risk_scoring(_, _) -> _.
|
||||||
start_payment_ev_no_risk_scoring(InvoiceID, Client) ->
|
register_payment_ev_no_risk_scoring(InvoiceID, Client) ->
|
||||||
[
|
[
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
?payment_ev(PaymentID, ?route_changed(Route))
|
?payment_ev(PaymentID, ?route_changed(Route))
|
||||||
] = next_changes(InvoiceID, 2, Client),
|
] = next_changes(InvoiceID, 4, Client),
|
||||||
Route.
|
Route.
|
||||||
|
|
||||||
-spec await_payment_session_started(_, _, _, _) -> _.
|
-spec await_payment_session_started(_, _, _, _) -> _.
|
||||||
@ -322,10 +326,12 @@ await_payment_capture_finish(InvoiceID, PaymentID, Reason, Cost, Cart, Client) -
|
|||||||
-spec await_payment_cash_flow(_, _, _) -> _.
|
-spec await_payment_cash_flow(_, _, _) -> _.
|
||||||
await_payment_cash_flow(InvoiceID, PaymentID, Client) ->
|
await_payment_cash_flow(InvoiceID, PaymentID, Client) ->
|
||||||
[
|
[
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)),
|
?payment_ev(PaymentID, ?risk_score_changed(_)),
|
||||||
?payment_ev(PaymentID, ?route_changed(Route)),
|
?payment_ev(PaymentID, ?route_changed(Route)),
|
||||||
?payment_ev(PaymentID, ?cash_flow_changed(CashFlow))
|
?payment_ev(PaymentID, ?cash_flow_changed(CashFlow))
|
||||||
] = next_changes(InvoiceID, 3, Client),
|
] = next_changes(InvoiceID, 5, Client),
|
||||||
{CashFlow, Route}.
|
{CashFlow, Route}.
|
||||||
|
|
||||||
-spec construct_ta_context(_, _, _) -> _.
|
-spec construct_ta_context(_, _, _) -> _.
|
||||||
|
@ -232,10 +232,12 @@ payment_w_all_blacklisted(C) ->
|
|||||||
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||||
[
|
[
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_RiskScore)),
|
?payment_ev(PaymentID, ?risk_score_changed(_RiskScore)),
|
||||||
?payment_ev(PaymentID, ?route_changed(_Route)),
|
?payment_ev(PaymentID, ?route_changed(_Route)),
|
||||||
?payment_ev(PaymentID, ?payment_rollback_started({failure, _Failure}))
|
?payment_ev(PaymentID, ?payment_rollback_started({failure, _Failure}))
|
||||||
] = next_changes(InvoiceID, 4, Client),
|
] = next_changes(InvoiceID, 6, Client),
|
||||||
?invoice_state(
|
?invoice_state(
|
||||||
?invoice_w_status(?invoice_unpaid()),
|
?invoice_w_status(?invoice_unpaid()),
|
||||||
[_PaymentSt]
|
[_PaymentSt]
|
||||||
|
@ -37,6 +37,9 @@
|
|||||||
-export([invalid_payment_amount/1]).
|
-export([invalid_payment_amount/1]).
|
||||||
|
|
||||||
-export([payment_limit_success/1]).
|
-export([payment_limit_success/1]).
|
||||||
|
-export([payment_shop_limit_success/1]).
|
||||||
|
-export([payment_shop_limit_overflow/1]).
|
||||||
|
-export([payment_shop_limit_more_overflow/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]).
|
||||||
-export([payment_limit_other_shop_success/1]).
|
-export([payment_limit_other_shop_success/1]).
|
||||||
@ -220,11 +223,13 @@ init([]) ->
|
|||||||
|
|
||||||
-define(PARTY_ID_WITH_LIMIT, <<"bIg merch limit">>).
|
-define(PARTY_ID_WITH_LIMIT, <<"bIg merch limit">>).
|
||||||
-define(PARTY_ID_WITH_SEVERAL_LIMITS, <<"bIg merch limit cascading">>).
|
-define(PARTY_ID_WITH_SEVERAL_LIMITS, <<"bIg merch limit cascading">>).
|
||||||
|
-define(PARTY_ID_WITH_SHOP_LIMITS, <<"small merch limit shop">>).
|
||||||
-define(PARTYID_EXTERNAL, <<"DUBTV">>).
|
-define(PARTYID_EXTERNAL, <<"DUBTV">>).
|
||||||
-define(LIMIT_ID, <<"ID">>).
|
-define(LIMIT_ID, <<"ID">>).
|
||||||
-define(LIMIT_ID2, <<"ID2">>).
|
-define(LIMIT_ID2, <<"ID2">>).
|
||||||
-define(LIMIT_ID3, <<"ID3">>).
|
-define(LIMIT_ID3, <<"ID3">>).
|
||||||
-define(LIMIT_ID4, <<"ID4">>).
|
-define(LIMIT_ID4, <<"ID4">>).
|
||||||
|
-define(SHOPLIMIT_ID, <<"SHOPLIMITID">>).
|
||||||
-define(LIMIT_UPPER_BOUNDARY, 100000).
|
-define(LIMIT_UPPER_BOUNDARY, 100000).
|
||||||
-define(BIG_LIMIT_UPPER_BOUNDARY, 1000000).
|
-define(BIG_LIMIT_UPPER_BOUNDARY, 1000000).
|
||||||
-define(DEFAULT_NEXT_CHANGE_TIMEOUT, 12000).
|
-define(DEFAULT_NEXT_CHANGE_TIMEOUT, 12000).
|
||||||
@ -378,6 +383,9 @@ groups() ->
|
|||||||
|
|
||||||
{operation_limits, [], [
|
{operation_limits, [], [
|
||||||
payment_limit_success,
|
payment_limit_success,
|
||||||
|
payment_shop_limit_success,
|
||||||
|
payment_shop_limit_overflow,
|
||||||
|
payment_shop_limit_more_overflow,
|
||||||
payment_routes_limit_values,
|
payment_routes_limit_values,
|
||||||
register_payment_limit_success,
|
register_payment_limit_success,
|
||||||
payment_limit_other_shop_success,
|
payment_limit_other_shop_success,
|
||||||
@ -1100,9 +1108,18 @@ register_invoice_payment(Route, ShopID, Client, C) ->
|
|||||||
init_operation_limits_group(C) ->
|
init_operation_limits_group(C) ->
|
||||||
PartyID1 = ?PARTY_ID_WITH_LIMIT,
|
PartyID1 = ?PARTY_ID_WITH_LIMIT,
|
||||||
PartyID2 = ?PARTY_ID_WITH_SEVERAL_LIMITS,
|
PartyID2 = ?PARTY_ID_WITH_SEVERAL_LIMITS,
|
||||||
|
PartyID3 = ?PARTY_ID_WITH_SHOP_LIMITS,
|
||||||
_ = hg_ct_helper:create_party(PartyID1, cfg(party_client, C)),
|
_ = hg_ct_helper:create_party(PartyID1, cfg(party_client, C)),
|
||||||
_ = hg_ct_helper:create_party(PartyID2, cfg(party_client, C)),
|
_ = hg_ct_helper:create_party(PartyID2, cfg(party_client, C)),
|
||||||
[{limits, #{party_id => PartyID1, party_id_w_several_limits => PartyID2}} | C].
|
_ = hg_ct_helper:create_party(PartyID3, cfg(party_client, C)),
|
||||||
|
[
|
||||||
|
{limits, #{
|
||||||
|
party_id => PartyID1,
|
||||||
|
party_id_w_several_limits => PartyID2,
|
||||||
|
party_id_w_shop_limits => PartyID3
|
||||||
|
}}
|
||||||
|
| C
|
||||||
|
].
|
||||||
|
|
||||||
-spec payment_limit_success(config()) -> test_return().
|
-spec payment_limit_success(config()) -> test_return().
|
||||||
payment_limit_success(C) ->
|
payment_limit_success(C) ->
|
||||||
@ -1117,6 +1134,78 @@ payment_limit_success(C) ->
|
|||||||
[?payment_state(_Payment)]
|
[?payment_state(_Payment)]
|
||||||
) = create_payment(PartyID, ShopID, 10000, Client, ?pmt_sys(<<"visa-ref">>)).
|
) = create_payment(PartyID, ShopID, 10000, Client, ?pmt_sys(<<"visa-ref">>)).
|
||||||
|
|
||||||
|
-spec payment_shop_limit_success(config()) -> test_return().
|
||||||
|
payment_shop_limit_success(C) ->
|
||||||
|
RootUrl = cfg(root_url, C),
|
||||||
|
PartyClient = cfg(party_client, C),
|
||||||
|
PartyID = cfg(party_id_big_merch, C),
|
||||||
|
TurnoverLimits = [
|
||||||
|
#domain_TurnoverLimit{
|
||||||
|
id = ?SHOPLIMIT_ID,
|
||||||
|
upper_boundary = ?LIMIT_UPPER_BOUNDARY,
|
||||||
|
domain_revision = dmt_client:get_last_version()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
ShopID = hg_ct_helper:create_shop(PartyID, ?cat(1), <<"RUB">>, ?tmpl(1), ?pinst(1), TurnoverLimits, PartyClient),
|
||||||
|
Client = hg_client_invoicing:start_link(hg_ct_helper:create_client(RootUrl)),
|
||||||
|
|
||||||
|
PaymentAmount = ?LIMIT_UPPER_BOUNDARY - 1,
|
||||||
|
?invoice_state(
|
||||||
|
?invoice_w_status(?invoice_paid()),
|
||||||
|
[?payment_state(_Payment)]
|
||||||
|
) = create_payment(PartyID, ShopID, PaymentAmount, Client, ?pmt_sys(<<"visa-ref">>)).
|
||||||
|
|
||||||
|
-spec payment_shop_limit_overflow(config()) -> test_return().
|
||||||
|
payment_shop_limit_overflow(C) ->
|
||||||
|
RootUrl = cfg(root_url, C),
|
||||||
|
PartyClient = cfg(party_client, C),
|
||||||
|
PartyID = cfg(party_id_big_merch, C),
|
||||||
|
TurnoverLimits = ordsets:from_list([
|
||||||
|
#domain_TurnoverLimit{
|
||||||
|
id = ?SHOPLIMIT_ID,
|
||||||
|
upper_boundary = ?LIMIT_UPPER_BOUNDARY,
|
||||||
|
domain_revision = dmt_client:get_last_version()
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
ShopID = hg_ct_helper:create_shop(PartyID, ?cat(1), <<"RUB">>, ?tmpl(1), ?pinst(1), TurnoverLimits, PartyClient),
|
||||||
|
Client = hg_client_invoicing:start_link(hg_ct_helper:create_client(RootUrl)),
|
||||||
|
|
||||||
|
PaymentAmount = ?LIMIT_UPPER_BOUNDARY + 1,
|
||||||
|
Failure = create_payment_shop_limit_overflow(PartyID, ShopID, PaymentAmount, Client, ?pmt_sys(<<"visa-ref">>)),
|
||||||
|
ok = payproc_errors:match('PaymentFailure', Failure, fun(
|
||||||
|
{authorization_failed, {shop_limit_exceeded, {unknown, _}}}
|
||||||
|
) ->
|
||||||
|
ok
|
||||||
|
end).
|
||||||
|
|
||||||
|
-spec payment_shop_limit_more_overflow(config()) -> test_return().
|
||||||
|
payment_shop_limit_more_overflow(C) ->
|
||||||
|
RootUrl = cfg(root_url, C),
|
||||||
|
PartyClient = cfg(party_client, C),
|
||||||
|
PartyID = cfg(party_id_big_merch, C),
|
||||||
|
TurnoverLimits = ordsets:from_list([
|
||||||
|
#domain_TurnoverLimit{
|
||||||
|
id = ?SHOPLIMIT_ID,
|
||||||
|
upper_boundary = ?LIMIT_UPPER_BOUNDARY,
|
||||||
|
domain_revision = dmt_client:get_last_version()
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
ShopID = hg_ct_helper:create_shop(PartyID, ?cat(1), <<"RUB">>, ?tmpl(1), ?pinst(1), TurnoverLimits, PartyClient),
|
||||||
|
Client = hg_client_invoicing:start_link(hg_ct_helper:create_client(RootUrl)),
|
||||||
|
|
||||||
|
PaymentAmount = ?LIMIT_UPPER_BOUNDARY - 1,
|
||||||
|
?invoice_state(
|
||||||
|
?invoice_w_status(?invoice_paid()),
|
||||||
|
[?payment_state(_Payment)]
|
||||||
|
) = create_payment(PartyID, ShopID, PaymentAmount, Client, ?pmt_sys(<<"visa-ref">>)),
|
||||||
|
|
||||||
|
Failure = create_payment_shop_limit_overflow(PartyID, ShopID, PaymentAmount, Client, ?pmt_sys(<<"visa-ref">>)),
|
||||||
|
ok = payproc_errors:match('PaymentFailure', Failure, fun(
|
||||||
|
{authorization_failed, {shop_limit_exceeded, {unknown, _}}}
|
||||||
|
) ->
|
||||||
|
ok
|
||||||
|
end).
|
||||||
|
|
||||||
-spec payment_routes_limit_values(config()) -> test_return().
|
-spec payment_routes_limit_values(config()) -> test_return().
|
||||||
payment_routes_limit_values(C) ->
|
payment_routes_limit_values(C) ->
|
||||||
RootUrl = cfg(root_url, C),
|
RootUrl = cfg(root_url, C),
|
||||||
@ -1386,6 +1475,15 @@ create_payment_limit_overflow(PartyID, ShopID, Amount, Client, PmtSys) ->
|
|||||||
PaymentID = await_payment_started(InvoiceID, PaymentID, Client),
|
PaymentID = await_payment_started(InvoiceID, PaymentID, Client),
|
||||||
await_payment_rollback(InvoiceID, PaymentID, Client).
|
await_payment_rollback(InvoiceID, PaymentID, Client).
|
||||||
|
|
||||||
|
create_payment_shop_limit_overflow(PartyID, ShopID, Amount, Client, PmtSys) ->
|
||||||
|
InvoiceParams = make_invoice_params(PartyID, ShopID, <<"rubberduck">>, make_due_date(10), make_cash(Amount)),
|
||||||
|
InvoiceID = create_invoice(InvoiceParams, Client),
|
||||||
|
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),
|
||||||
|
PaymentParams = make_payment_params(PmtSys),
|
||||||
|
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||||
|
PaymentID = await_payment_started(InvoiceID, PaymentID, Client),
|
||||||
|
await_payment_shop_limit_rollback(InvoiceID, PaymentID, Client).
|
||||||
|
|
||||||
%%----------------- operation_limits group end
|
%%----------------- operation_limits group end
|
||||||
|
|
||||||
-spec payment_success_ruleset(config()) -> test_return().
|
-spec payment_success_ruleset(config()) -> test_return().
|
||||||
@ -1435,9 +1533,11 @@ payment_w_misconfigured_routing_failed(C) ->
|
|||||||
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||||
[
|
[
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)),
|
?payment_ev(PaymentID, ?risk_score_changed(_)),
|
||||||
?payment_ev(PaymentID, ?payment_status_changed(?failed({failure, Failure})))
|
?payment_ev(PaymentID, ?payment_status_changed(?failed({failure, Failure})))
|
||||||
] = next_changes(InvoiceID, 3, Client),
|
] = next_changes(InvoiceID, 5, Client),
|
||||||
Reason = genlib:format({routing_decisions, {delegates, []}}),
|
Reason = genlib:format({routing_decisions, {delegates, []}}),
|
||||||
?assertRouteNotFound(Failure, {unknown, {{unknown_error, <<"misconfiguration">>}, _}}, Reason).
|
?assertRouteNotFound(Failure, {unknown, {{unknown_error, <<"misconfiguration">>}, _}}, Reason).
|
||||||
|
|
||||||
@ -2193,10 +2293,12 @@ payment_risk_score_check(C) ->
|
|||||||
?payment_state(?payment(PaymentID3)) = hg_client_invoicing:start_payment(InvoiceID3, PaymentParams, Client),
|
?payment_state(?payment(PaymentID3)) = hg_client_invoicing:start_payment(InvoiceID3, PaymentParams, Client),
|
||||||
[
|
[
|
||||||
?payment_ev(PaymentID3, ?payment_started(?payment_w_status(?pending()))),
|
?payment_ev(PaymentID3, ?payment_started(?payment_w_status(?pending()))),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
% fatal risk score is not going to be covered
|
% fatal risk score is not going to be covered
|
||||||
?payment_ev(PaymentID3, ?risk_score_changed(fatal)),
|
?payment_ev(PaymentID3, ?risk_score_changed(fatal)),
|
||||||
?payment_ev(PaymentID3, ?payment_status_changed(?failed({failure, Failure})))
|
?payment_ev(PaymentID3, ?payment_status_changed(?failed({failure, Failure})))
|
||||||
] = next_changes(InvoiceID3, 3, Client),
|
] = next_changes(InvoiceID3, 5, Client),
|
||||||
ok = payproc_errors:match(
|
ok = payproc_errors:match(
|
||||||
'PaymentFailure',
|
'PaymentFailure',
|
||||||
Failure,
|
Failure,
|
||||||
@ -2721,7 +2823,7 @@ registered_payment_adjustment_success(C) ->
|
|||||||
},
|
},
|
||||||
?payment_state(?payment(PaymentID)) =
|
?payment_state(?payment(PaymentID)) =
|
||||||
hg_client_invoicing:register_payment(InvoiceID, PaymentParams, Client),
|
hg_client_invoicing:register_payment(InvoiceID, PaymentParams, Client),
|
||||||
_ = start_payment_ev_no_risk_scoring(InvoiceID, Client),
|
_ = register_payment_ev_no_risk_scoring(InvoiceID, Client),
|
||||||
?payment_ev(PaymentID, ?cash_flow_changed(CF1)) =
|
?payment_ev(PaymentID, ?cash_flow_changed(CF1)) =
|
||||||
next_change(InvoiceID, Client),
|
next_change(InvoiceID, Client),
|
||||||
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
PaymentID = await_payment_session_started(InvoiceID, PaymentID, Client, ?processed()),
|
||||||
@ -5100,8 +5202,12 @@ repair_fail_routing_succeeded(C) ->
|
|||||||
%% Payment
|
%% Payment
|
||||||
PaymentParams = make_payment_params(?pmt_sys(<<"visa-ref">>)),
|
PaymentParams = make_payment_params(?pmt_sys(<<"visa-ref">>)),
|
||||||
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) = next_change(InvoiceID, Client),
|
[
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_RS)) = next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
|
?payment_ev(PaymentID, ?risk_score_changed(_))
|
||||||
|
] = next_changes(InvoiceID, 4, Client),
|
||||||
%% routing broken
|
%% routing broken
|
||||||
timeout = next_change(InvoiceID, 2000, Client),
|
timeout = next_change(InvoiceID, 2000, Client),
|
||||||
|
|
||||||
@ -5154,9 +5260,13 @@ repair_fail_cash_flow_building_succeeded(C) ->
|
|||||||
%% Payment
|
%% Payment
|
||||||
PaymentParams = make_payment_params(?pmt_sys(<<"visa-ref">>)),
|
PaymentParams = make_payment_params(?pmt_sys(<<"visa-ref">>)),
|
||||||
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) = next_change(InvoiceID, Client),
|
[
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_RS)) = next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
?payment_ev(PaymentID, ?route_changed(Route)) = next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
|
?payment_ev(PaymentID, ?risk_score_changed(_)),
|
||||||
|
?payment_ev(PaymentID, ?route_changed(Route))
|
||||||
|
] = next_changes(InvoiceID, 5, Client),
|
||||||
%% cash_flow_building broken
|
%% cash_flow_building broken
|
||||||
timeout = next_change(InvoiceID, 2000, Client),
|
timeout = next_change(InvoiceID, 2000, Client),
|
||||||
|
|
||||||
@ -6075,10 +6185,12 @@ payment_cascade_success(C) ->
|
|||||||
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),
|
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),
|
||||||
{ok, Limit} = hg_limiter_helper:get_payment_limit_amount(?LIMIT_ID4, hg_domain:head(), Payment, Invoice),
|
{ok, Limit} = hg_limiter_helper:get_payment_limit_amount(?LIMIT_ID4, hg_domain:head(), Payment, Invoice),
|
||||||
InitialAccountedAmount = hg_limiter_helper:get_amount(Limit),
|
InitialAccountedAmount = hg_limiter_helper:get_amount(Limit),
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
[
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)) =
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
|
?payment_ev(PaymentID, ?risk_score_changed(_))
|
||||||
|
] = next_changes(InvoiceID, 4, Client),
|
||||||
{Route1, _CashFlow1, TrxID1, Failure1} =
|
{Route1, _CashFlow1, TrxID1, Failure1} =
|
||||||
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
||||||
ok = payproc_errors:match('PaymentFailure', Failure1, fun({preauthorization_failed, {card_blocked, _}}) -> ok end),
|
ok = payproc_errors:match('PaymentFailure', Failure1, fun({preauthorization_failed, {card_blocked, _}}) -> ok end),
|
||||||
@ -6461,10 +6573,12 @@ payment_cascade_limit_overflow(C) ->
|
|||||||
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),
|
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),
|
||||||
{ok, Limit} = hg_limiter_helper:get_payment_limit_amount(?LIMIT_ID4, hg_domain:head(), Payment, Invoice),
|
{ok, Limit} = hg_limiter_helper:get_payment_limit_amount(?LIMIT_ID4, hg_domain:head(), Payment, Invoice),
|
||||||
InitialAccountedAmount = hg_limiter_helper:get_amount(Limit),
|
InitialAccountedAmount = hg_limiter_helper:get_amount(Limit),
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
[
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)) =
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
|
?payment_ev(PaymentID, ?risk_score_changed(_))
|
||||||
|
] = next_changes(InvoiceID, 4, Client),
|
||||||
{Route1, _CashFlow1, _TrxID1, Failure1} =
|
{Route1, _CashFlow1, _TrxID1, Failure1} =
|
||||||
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
||||||
ok = payproc_errors:match('PaymentFailure', Failure1, fun({authorization_failed, {unknown, _}}) -> ok end),
|
ok = payproc_errors:match('PaymentFailure', Failure1, fun({authorization_failed, {unknown, _}}) -> ok end),
|
||||||
@ -6515,10 +6629,12 @@ payment_big_cascade_success(C) ->
|
|||||||
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),
|
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),
|
||||||
{ok, Limit} = hg_limiter_helper:get_payment_limit_amount(?LIMIT_ID4, hg_domain:head(), Payment, Invoice),
|
{ok, Limit} = hg_limiter_helper:get_payment_limit_amount(?LIMIT_ID4, hg_domain:head(), Payment, Invoice),
|
||||||
InitialAccountedAmount = hg_limiter_helper:get_amount(Limit),
|
InitialAccountedAmount = hg_limiter_helper:get_amount(Limit),
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
[
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)) =
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
|
?payment_ev(PaymentID, ?risk_score_changed(_))
|
||||||
|
] = next_changes(InvoiceID, 4, Client),
|
||||||
[
|
[
|
||||||
(fun() ->
|
(fun() ->
|
||||||
{_Route, _CashFlow, _TrxID, Failure} =
|
{_Route, _CashFlow, _TrxID, Failure} =
|
||||||
@ -6672,10 +6788,12 @@ payment_cascade_fail_provider_error(C) ->
|
|||||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, ?pmt_sys(<<"visa-ref">>)),
|
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, ?pmt_sys(<<"visa-ref">>)),
|
||||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||||
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
[
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)) =
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
|
?payment_ev(PaymentID, ?risk_score_changed(_))
|
||||||
|
] = next_changes(InvoiceID, 4, Client),
|
||||||
{_Route1, _CashFlow1, _TrxID1, Failure1} =
|
{_Route1, _CashFlow1, _TrxID1, Failure1} =
|
||||||
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
||||||
%% And again
|
%% And again
|
||||||
@ -6774,10 +6892,12 @@ payment_cascade_fail_ui(C) ->
|
|||||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(preauth_3ds, ?pmt_sys(<<"visa-ref">>)),
|
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(preauth_3ds, ?pmt_sys(<<"visa-ref">>)),
|
||||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||||
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
[
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)) =
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
|
?payment_ev(PaymentID, ?risk_score_changed(_))
|
||||||
|
] = next_changes(InvoiceID, 4, Client),
|
||||||
{_Route1, _CashFlow1, _TrxID1, Failure1} =
|
{_Route1, _CashFlow1, _TrxID1, Failure1} =
|
||||||
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
||||||
ok = payproc_errors:match('PaymentFailure', Failure1, fun({authorization_failed, {unknown, _}}) -> ok end),
|
ok = payproc_errors:match('PaymentFailure', Failure1, fun({authorization_failed, {unknown, _}}) -> ok end),
|
||||||
@ -6983,10 +7103,12 @@ payment_cascade_fail_wo_available_attempt_limit(C) ->
|
|||||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, ?pmt_sys(<<"visa-ref">>)),
|
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, ?pmt_sys(<<"visa-ref">>)),
|
||||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||||
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
[
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)) =
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
|
?payment_ev(PaymentID, ?risk_score_changed(_))
|
||||||
|
] = next_changes(InvoiceID, 4, Client),
|
||||||
{_Route, _CashFlow, _TrxID, Failure} =
|
{_Route, _CashFlow, _TrxID, Failure} =
|
||||||
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
||||||
?payment_ev(PaymentID, ?payment_status_changed(?failed({failure, Failure}))) =
|
?payment_ev(PaymentID, ?payment_status_changed(?failed({failure, Failure}))) =
|
||||||
@ -7071,10 +7193,12 @@ payment_cascade_failures(C) ->
|
|||||||
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, ?pmt_sys(<<"visa-ref">>)),
|
{PaymentTool, Session} = hg_dummy_provider:make_payment_tool(no_preauth, ?pmt_sys(<<"visa-ref">>)),
|
||||||
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
PaymentParams = make_payment_params(PaymentTool, Session, instant),
|
||||||
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
[
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)) =
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
|
?payment_ev(PaymentID, ?risk_score_changed(_))
|
||||||
|
] = next_changes(InvoiceID, 4, Client),
|
||||||
{_Route1, _CashFlow1, _TrxID1, Failure1} =
|
{_Route1, _CashFlow1, _TrxID1, Failure1} =
|
||||||
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
||||||
ok = payproc_errors:match('PaymentFailure', Failure1, fun({preauthorization_failed, {card_blocked, _}}) -> ok end),
|
ok = payproc_errors:match('PaymentFailure', Failure1, fun({preauthorization_failed, {card_blocked, _}}) -> ok end),
|
||||||
@ -7170,10 +7294,12 @@ payment_cascade_deadline_failures(C) ->
|
|||||||
processing_deadline = hg_datetime:add_time_span(#base_TimeSpan{seconds = 2}, hg_datetime:format_now())
|
processing_deadline = hg_datetime:add_time_span(#base_TimeSpan{seconds = 2}, hg_datetime:format_now())
|
||||||
},
|
},
|
||||||
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))) =
|
[
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)) =
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
next_change(InvoiceID, Client),
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
|
?payment_ev(PaymentID, ?risk_score_changed(_))
|
||||||
|
] = next_changes(InvoiceID, 4, Client),
|
||||||
{_Route1, _CashFlow1, _TrxID1, Failure1} =
|
{_Route1, _CashFlow1, _TrxID1, Failure1} =
|
||||||
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
await_cascade_triggering(InvoiceID, PaymentID, Client),
|
||||||
ok = payproc_errors:match('PaymentFailure', Failure1, fun({preauthorization_failed, {card_blocked, _}}) -> ok end),
|
ok = payproc_errors:match('PaymentFailure', Failure1, fun({preauthorization_failed, {card_blocked, _}}) -> ok end),
|
||||||
@ -7481,8 +7607,8 @@ register_payment(InvoiceID, RegisterPaymentParams, WithRiskScoring, Client) ->
|
|||||||
start_payment_ev(InvoiceID, Client) ->
|
start_payment_ev(InvoiceID, Client) ->
|
||||||
hg_invoice_helper:start_payment_ev(InvoiceID, Client).
|
hg_invoice_helper:start_payment_ev(InvoiceID, Client).
|
||||||
|
|
||||||
start_payment_ev_no_risk_scoring(InvoiceID, Client) ->
|
register_payment_ev_no_risk_scoring(InvoiceID, Client) ->
|
||||||
hg_invoice_helper:start_payment_ev_no_risk_scoring(InvoiceID, Client).
|
hg_invoice_helper:register_payment_ev_no_risk_scoring(InvoiceID, Client).
|
||||||
|
|
||||||
process_payment(InvoiceID, PaymentParams, Client) ->
|
process_payment(InvoiceID, PaymentParams, Client) ->
|
||||||
hg_invoice_helper:process_payment(InvoiceID, PaymentParams, Client).
|
hg_invoice_helper:process_payment(InvoiceID, PaymentParams, Client).
|
||||||
@ -7497,18 +7623,29 @@ await_payment_cash_flow(InvoiceID, PaymentID, Client) ->
|
|||||||
|
|
||||||
await_payment_cash_flow(RS, Route, InvoiceID, PaymentID, Client) ->
|
await_payment_cash_flow(RS, Route, InvoiceID, PaymentID, Client) ->
|
||||||
[
|
[
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(RS)),
|
?payment_ev(PaymentID, ?risk_score_changed(RS)),
|
||||||
?payment_ev(PaymentID, ?route_changed(Route)),
|
?payment_ev(PaymentID, ?route_changed(Route)),
|
||||||
?payment_ev(PaymentID, ?cash_flow_changed(CashFlow))
|
?payment_ev(PaymentID, ?cash_flow_changed(CashFlow))
|
||||||
] = next_changes(InvoiceID, 3, Client),
|
] = next_changes(InvoiceID, 5, Client),
|
||||||
CashFlow.
|
CashFlow.
|
||||||
|
|
||||||
await_payment_rollback(InvoiceID, PaymentID, Client) ->
|
await_payment_rollback(InvoiceID, PaymentID, Client) ->
|
||||||
[
|
[
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_)),
|
?payment_ev(PaymentID, ?risk_score_changed(_)),
|
||||||
?payment_ev(PaymentID, ?route_changed(_, _)),
|
?payment_ev(PaymentID, ?route_changed(_, _)),
|
||||||
?payment_ev(PaymentID, ?payment_rollback_started({failure, Failure}))
|
?payment_ev(PaymentID, ?payment_rollback_started({failure, Failure}))
|
||||||
] = next_changes(InvoiceID, 3, Client),
|
] = next_changes(InvoiceID, 5, Client),
|
||||||
|
Failure.
|
||||||
|
|
||||||
|
await_payment_shop_limit_rollback(InvoiceID, PaymentID, Client) ->
|
||||||
|
[
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?payment_rollback_started({failure, Failure}))
|
||||||
|
] = next_changes(InvoiceID, 2, Client),
|
||||||
Failure.
|
Failure.
|
||||||
|
|
||||||
await_payment_session_started(InvoiceID, PaymentID, Client, Target) ->
|
await_payment_session_started(InvoiceID, PaymentID, Client, Target) ->
|
||||||
@ -7710,9 +7847,11 @@ execute_payment_w_cascade(InvoiceID, Params, Client, CascadeCount) when CascadeC
|
|||||||
#payproc_InvoicePayment{payment = _Payment} = hg_client_invoicing:start_payment(InvoiceID, Params, Client),
|
#payproc_InvoicePayment{payment = _Payment} = hg_client_invoicing:start_payment(InvoiceID, Params, Client),
|
||||||
[
|
[
|
||||||
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
?payment_ev(PaymentID, ?risk_score_changed(_))
|
?payment_ev(PaymentID, ?risk_score_changed(_))
|
||||||
] =
|
] =
|
||||||
next_changes(InvoiceID, 2, Client),
|
next_changes(InvoiceID, 4, Client),
|
||||||
FailedRoutes = [
|
FailedRoutes = [
|
||||||
begin
|
begin
|
||||||
{Route, _CashFlow, _TrxID, _Failure} =
|
{Route, _CashFlow, _TrxID, _Failure} =
|
||||||
@ -7856,9 +7995,11 @@ payment_customer_risk_score_check(C) ->
|
|||||||
?payment_state(?payment(PaymentID1)) = hg_client_invoicing:start_payment(InvoiceID1, PaymentParams, Client),
|
?payment_state(?payment(PaymentID1)) = hg_client_invoicing:start_payment(InvoiceID1, PaymentParams, Client),
|
||||||
[
|
[
|
||||||
?payment_ev(PaymentID1, ?payment_started(?payment_w_status(?pending()))),
|
?payment_ev(PaymentID1, ?payment_started(?payment_w_status(?pending()))),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_initiated()),
|
||||||
|
?payment_ev(PaymentID, ?shop_limit_applied()),
|
||||||
?payment_ev(PaymentID1, ?risk_score_changed(fatal)),
|
?payment_ev(PaymentID1, ?risk_score_changed(fatal)),
|
||||||
?payment_ev(PaymentID1, ?payment_status_changed(?failed(Failure)))
|
?payment_ev(PaymentID1, ?payment_status_changed(?failed(Failure)))
|
||||||
] = next_changes(InvoiceID1, 3, Client),
|
] = next_changes(InvoiceID1, 5, Client),
|
||||||
{failure, #domain_Failure{
|
{failure, #domain_Failure{
|
||||||
code = <<"no_route_found">>,
|
code = <<"no_route_found">>,
|
||||||
sub = #domain_SubFailure{code = <<"risk_score_is_too_high">>}
|
sub = #domain_SubFailure{code = <<"risk_score_is_too_high">>}
|
||||||
|
@ -23,13 +23,15 @@
|
|||||||
-define(LIMIT_ID2, <<"ID2">>).
|
-define(LIMIT_ID2, <<"ID2">>).
|
||||||
-define(LIMIT_ID3, <<"ID3">>).
|
-define(LIMIT_ID3, <<"ID3">>).
|
||||||
-define(LIMIT_ID4, <<"ID4">>).
|
-define(LIMIT_ID4, <<"ID4">>).
|
||||||
|
-define(SHOPLIMIT_ID, <<"SHOPLIMITID">>).
|
||||||
|
|
||||||
-spec init_per_suite(config()) -> _.
|
-spec init_per_suite(config()) -> _.
|
||||||
init_per_suite(_Config) ->
|
init_per_suite(_Config) ->
|
||||||
_ = dmt_client:upsert({limit_config, mk_config_object(?LIMIT_ID)}),
|
_ = dmt_client:upsert({limit_config, mk_config_object(?LIMIT_ID)}),
|
||||||
_ = dmt_client:upsert({limit_config, mk_config_object(?LIMIT_ID2)}),
|
_ = dmt_client:upsert({limit_config, mk_config_object(?LIMIT_ID2)}),
|
||||||
_ = dmt_client:upsert({limit_config, mk_config_object(?LIMIT_ID3)}),
|
_ = dmt_client:upsert({limit_config, mk_config_object(?LIMIT_ID3)}),
|
||||||
_ = dmt_client:upsert({limit_config, mk_config_object(?LIMIT_ID4)}).
|
_ = dmt_client:upsert({limit_config, mk_config_object(?LIMIT_ID4)}),
|
||||||
|
_ = dmt_client:upsert({limit_config, mk_config_object(?SHOPLIMIT_ID)}).
|
||||||
|
|
||||||
-spec get_amount(_) -> pos_integer().
|
-spec get_amount(_) -> pos_integer().
|
||||||
get_amount(#limiter_Limit{amount = Amount}) ->
|
get_amount(#limiter_Limit{amount = Amount}) ->
|
||||||
|
@ -97,7 +97,7 @@ services:
|
|||||||
disable: true
|
disable: true
|
||||||
|
|
||||||
party-management:
|
party-management:
|
||||||
image: ghcr.io/valitydev/party-management:sha-28c1b38
|
image: ghcr.io/valitydev/party-management:sha-7c202dc
|
||||||
command: /opt/party-management/bin/party-management foreground
|
command: /opt/party-management/bin/party-management foreground
|
||||||
depends_on:
|
depends_on:
|
||||||
machinegun:
|
machinegun:
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
{<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2},
|
{<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2},
|
||||||
{<<"damsel">>,
|
{<<"damsel">>,
|
||||||
{git,"https://github.com/valitydev/damsel.git",
|
{git,"https://github.com/valitydev/damsel.git",
|
||||||
{ref,"781e19277224071639719f9fdfcfd46f9f03a832"}},
|
{ref,"b04aba83100a4d0adc19b5797372970fd632f911"}},
|
||||||
0},
|
0},
|
||||||
{<<"dmt_client">>,
|
{<<"dmt_client">>,
|
||||||
{git,"https://github.com/valitydev/dmt-client.git",
|
{git,"https://github.com/valitydev/dmt-client.git",
|
||||||
|
Loading…
Reference in New Issue
Block a user