Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions apps/hellgate/src/hg_invoice_payment.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2522,14 +2522,15 @@ reject_routes(GroupReason, RejectedRoutes, Ctx) ->
get_limit_overflow_routes(Routes, VS, Iter, St) ->
Opts = get_opts(St),
Revision = get_payment_revision(St),
Session = get_activity_session(St),
Payment = get_payment(St),
Invoice = get_invoice(Opts),
lists:foldl(
fun(Route, {RoutesNoOverflowIn, RejectedIn, LimitsIn}) ->
PaymentRoute = hg_route:to_payment_route(Route),
ProviderTerms = hg_routing:get_payment_terms(PaymentRoute, VS, Revision),
TurnoverLimits = get_turnover_limits(ProviderTerms, strict),
case hg_limiter:check_limits(TurnoverLimits, Invoice, Payment, PaymentRoute, Iter) of
case hg_limiter:check_limits(TurnoverLimits, Invoice, Payment, Session, PaymentRoute, Iter) of
{ok, Limits} ->
{[Route | RoutesNoOverflowIn], RejectedIn, LimitsIn#{PaymentRoute => Limits}};
{error, {limit_overflow, IDs, Limits}} ->
Expand Down Expand Up @@ -2596,6 +2597,7 @@ get_shop_turnover_limits(ShopConfig) ->
hold_limit_routes(Routes0, VS, Iter, St) ->
Opts = get_opts(St),
Revision = get_payment_revision(St),
Session = get_activity_session(St),
Payment = get_payment(St),
Invoice = get_invoice(Opts),
{Routes1, Rejected} = lists:foldl(
Expand All @@ -2604,7 +2606,7 @@ hold_limit_routes(Routes0, VS, Iter, St) ->
ProviderTerms = hg_routing:get_payment_terms(PaymentRoute, VS, Revision),
TurnoverLimits = get_turnover_limits(ProviderTerms, strict),
try
ok = hg_limiter:hold_payment_limits(TurnoverLimits, Invoice, Payment, PaymentRoute, Iter),
ok = hg_limiter:hold_payment_limits(TurnoverLimits, Invoice, Payment, Session, PaymentRoute, Iter),
{[Route | LimitHeldRoutes], RejectedRoutes}
catch
error:(#limiter_LimitNotFound{} = LimiterError) ->
Expand All @@ -2630,20 +2632,22 @@ do_reject_route(LimiterError, Route, TurnoverLimits, {LimitHeldRoutes, RejectedR
rollback_payment_limits(Routes, Iter, St, Flags) ->
Opts = get_opts(St),
Revision = get_payment_revision(St),
Session = get_activity_session(St),
Payment = get_payment(St),
Invoice = get_invoice(Opts),
VS = get_varset(St, #{}),
lists:foreach(
fun(Route) ->
ProviderTerms = hg_routing:get_payment_terms(Route, VS, Revision),
TurnoverLimits = get_turnover_limits(ProviderTerms, strict),
ok = hg_limiter:rollback_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter, Flags)
ok = hg_limiter:rollback_payment_limits(TurnoverLimits, Invoice, Payment, Session, Route, Iter, Flags)
end,
Routes
).

rollback_broken_payment_limits(St) ->
Opts = get_opts(St),
Session = get_activity_session(St),
Payment = get_payment(St),
Invoice = get_invoice(Opts),
LimitValues = get_limit_values_(St, lenient),
Expand All @@ -2661,7 +2665,7 @@ rollback_broken_payment_limits(St) ->
[],
Values
),
ok = hg_limiter:rollback_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter, [
ok = hg_limiter:rollback_payment_limits(TurnoverLimits, Invoice, Payment, Session, Route, Iter, [
ignore_business_error
])
end,
Expand All @@ -2681,14 +2685,15 @@ get_turnover_limits(ProviderTerms, Mode) ->
commit_payment_limits(#st{capture_data = CaptureData} = St) ->
Opts = get_opts(St),
Revision = get_payment_revision(St),
Session = get_activity_session(St),
Payment = get_payment(St),
#payproc_InvoicePaymentCaptureData{cash = CapturedCash} = CaptureData,
Invoice = get_invoice(Opts),
Route = get_route(St),
ProviderTerms = get_provider_payment_terms(St, Revision),
TurnoverLimits = get_turnover_limits(ProviderTerms, strict),
Iter = get_iter(St),
hg_limiter:commit_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter, CapturedCash).
hg_limiter:commit_payment_limits(TurnoverLimits, Invoice, Payment, Session, Route, Iter, CapturedCash).

commit_payment_cashflow(St) ->
Plan = get_cashflow_plan(St),
Expand Down Expand Up @@ -3482,6 +3487,7 @@ get_limit_values(St, Opts) ->
get_limit_values_(St, Mode) ->
{PaymentInstitution, VS, Revision} = route_args(St),
Ctx = build_routing_context(PaymentInstitution, VS, Revision, St),
Session = get_activity_session(St),
Payment = get_payment(St),
Invoice = get_invoice(get_opts(St)),
%% NOTE If event 'route_changed' didn't occur, then there may be
Expand All @@ -3498,7 +3504,7 @@ get_limit_values_(St, Mode) ->
ProviderTerms = hg_routing:get_payment_terms(PaymentRoute, VS, Revision),
TurnoverLimits = get_turnover_limits(ProviderTerms, Mode),
TurnoverLimitValues =
hg_limiter:get_limit_values(TurnoverLimits, Invoice, Payment, PaymentRoute, Iter),
hg_limiter:get_limit_values(TurnoverLimits, Invoice, Payment, Session, PaymentRoute, Iter),
Acc#{PaymentRoute => TurnoverLimitValues}
end,
#{},
Expand Down Expand Up @@ -3633,7 +3639,7 @@ get_payment_state(InvoiceID, PaymentID) ->
throw(#payproc_InvoicePaymentNotFound{})
end.

-spec get_session(target(), st()) -> session().
-spec get_session(target(), st()) -> session() | undefined.
get_session(Target, #st{sessions = Sessions, routes = [Route | _PreviousRoutes]}) ->
TargetSessions = maps:get(get_target_type(Target), Sessions, []),
MatchingRoute = fun(#{route := SR}) -> SR =:= Route end,
Expand Down
2 changes: 1 addition & 1 deletion apps/hellgate/src/hg_invoice_registered_payment.erl
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ hold_payment_limits(Invoice, Payment, St) ->
Route = hg_invoice_payment:get_route(St),
TurnoverLimits = get_turnover_limits(Payment, Route, St),
Iter = hg_invoice_payment:get_iter(St),
hg_limiter:hold_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter).
hg_limiter:hold_payment_limits(TurnoverLimits, Invoice, Payment, undefined, Route, Iter).

get_turnover_limits(Payment, Route, St) ->
Route = hg_invoice_payment:get_route(St),
Expand Down
81 changes: 57 additions & 24 deletions apps/hellgate/src/hg_limiter.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
-type turnover_limit() :: dmsl_domain_thrift:'TurnoverLimit'().
-type invoice() :: dmsl_domain_thrift:'Invoice'().
-type payment() :: dmsl_domain_thrift:'InvoicePayment'().
-type session() :: hg_session:t().
-type route() :: hg_route:payment_route().
-type refund() :: hg_invoice_payment:domain_refund().
-type cash() :: dmsl_domain_thrift:'Cash'().
Expand All @@ -21,18 +22,18 @@
-export_type([turnover_limit_value/0]).

-export([get_turnover_limits/2]).
-export([check_limits/5]).
-export([check_limits/6]).
-export([check_shop_limits/5]).
-export([hold_payment_limits/5]).
-export([hold_payment_limits/6]).
-export([hold_shop_limits/5]).
-export([hold_refund_limits/5]).
-export([commit_payment_limits/6]).
-export([commit_payment_limits/7]).
-export([commit_shop_limits/5]).
-export([commit_refund_limits/5]).
-export([rollback_payment_limits/6]).
-export([rollback_payment_limits/7]).
-export([rollback_shop_limits/6]).
-export([rollback_refund_limits/5]).
-export([get_limit_values/5]).
-export([get_limit_values/6]).

-define(route(ProviderRef, TerminalRef), #domain_PaymentRoute{
provider = ProviderRef,
Expand Down Expand Up @@ -77,9 +78,10 @@ filter_existing_turnover_limits(Limits, Mode) ->
Limits
).

-spec get_limit_values([turnover_limit()], invoice(), payment(), route(), pos_integer()) -> [turnover_limit_value()].
get_limit_values(TurnoverLimits, Invoice, Payment, Route, Iter) ->
Context = gen_limit_context(Invoice, Payment, Route),
-spec get_limit_values([turnover_limit()], invoice(), payment(), session() | undefined, route(), pos_integer()) ->
[turnover_limit_value()].
get_limit_values(TurnoverLimits, Invoice, Payment, Session, Route, Iter) ->
Context = gen_limit_context(Invoice, Payment, Session, Route),
get_limit_values(Context, TurnoverLimits, make_route_operation_segments(Invoice, Payment, Route, Iter)).

make_route_operation_segments(Invoice, Payment, ?route(ProviderRef, TerminalRef), Iter) ->
Expand All @@ -105,11 +107,11 @@ get_batch_limit_values(Context, TurnoverLimits, OperationIdSegments) ->
hg_limiter_client:get_batch(LimitRequest, Context)
).

-spec check_limits([turnover_limit()], invoice(), payment(), route(), pos_integer()) ->
-spec check_limits([turnover_limit()], invoice(), payment(), session() | undefined, route(), pos_integer()) ->
{ok, [turnover_limit_value()]}
| {error, {limit_overflow, [binary()], [turnover_limit_value()]}}.
check_limits(TurnoverLimits, Invoice, Payment, Route, Iter) ->
Context = gen_limit_context(Invoice, Payment, Route),
check_limits(TurnoverLimits, Invoice, Payment, Session, Route, Iter) ->
Context = gen_limit_context(Invoice, Payment, Session, Route),
Limits = get_limit_values(Context, TurnoverLimits, make_route_operation_segments(Invoice, Payment, Route, Iter)),
try
ok = check_limits_(Limits, Context),
Expand Down Expand Up @@ -166,9 +168,10 @@ check_limits_([TurnoverLimitValue | TLVs], Context) ->
throw(limit_overflow)
end.

-spec hold_payment_limits([turnover_limit()], invoice(), payment(), route(), pos_integer()) -> ok.
hold_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter) ->
Context = gen_limit_context(Invoice, Payment, Route),
-spec hold_payment_limits([turnover_limit()], invoice(), payment(), session() | undefined, route(), pos_integer()) ->
ok.
hold_payment_limits(TurnoverLimits, Invoice, Payment, Session, Route, Iter) ->
Context = gen_limit_context(Invoice, Payment, Session, Route),
ok = batch_hold_limits(Context, TurnoverLimits, make_route_operation_segments(Invoice, Payment, Route, Iter)).

batch_hold_limits(_Context, [], _OperationIdSegments) ->
Expand Down Expand Up @@ -197,9 +200,17 @@ make_refund_operation_segments(Invoice, Payment, Refund) ->
{refund_session, get_refund_id(Refund)}
].

-spec commit_payment_limits([turnover_limit()], invoice(), payment(), route(), pos_integer(), cash() | undefined) -> ok.
commit_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter, CapturedCash) ->
Context = gen_limit_context(Invoice, Payment, Route, CapturedCash),
-spec commit_payment_limits(
[turnover_limit()],
invoice(),
payment(),
session() | undefined,
route(),
pos_integer(),
cash() | undefined
) -> ok.
commit_payment_limits(TurnoverLimits, Invoice, Payment, Session, Route, Iter, CapturedCash) ->
Context = gen_limit_context(Invoice, Payment, Session, Route, CapturedCash),
OperationIdSegments = make_route_operation_segments(Invoice, Payment, Route, Iter),
ok = batch_commit_limits(Context, TurnoverLimits, OperationIdSegments).

Expand Down Expand Up @@ -243,10 +254,18 @@ batch_commit_limits(Context, TurnoverLimits, OperationIdSegments) ->
%%
%% - `ignore_not_found` -- does not raise error if limiter won't be able to
%% find according posting plan in accountant service
-spec rollback_payment_limits([turnover_limit()], invoice(), payment(), route(), pos_integer(), [handling_flag()]) ->
-spec rollback_payment_limits(
[turnover_limit()],
invoice(),
payment(),
session() | undefined,
route(),
pos_integer(),
[handling_flag()]
) ->
ok.
rollback_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter, Flags) ->
Context = gen_limit_context(Invoice, Payment, Route),
rollback_payment_limits(TurnoverLimits, Invoice, Payment, Session, Route, Iter, Flags) ->
Context = gen_limit_context(Invoice, Payment, Session, Route),
OperationIdSegments = make_route_operation_segments(Invoice, Payment, Route, Iter),
ok = batch_rollback_limits(Context, TurnoverLimits, OperationIdSegments, Flags).

Expand Down Expand Up @@ -281,10 +300,10 @@ rollback_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
OperationIdSegments = make_refund_operation_segments(Invoice, Payment, Refund),
ok = batch_rollback_limits(Context, TurnoverLimits, OperationIdSegments, []).

gen_limit_context(Invoice, Payment, Route) ->
gen_limit_context(Invoice, Payment, Route, undefined).
gen_limit_context(Invoice, Payment, Session, Route) ->
gen_limit_context(Invoice, Payment, Session, Route, undefined).

gen_limit_context(Invoice, Payment, Route, CapturedCash) ->
gen_limit_context(Invoice, Payment, Session, Route, CapturedCash) ->
PaymentCtx = #context_payproc_InvoicePayment{
payment = Payment#domain_InvoicePayment{
status = {captured, #domain_InvoicePaymentCaptured{cost = CapturedCash}}
Expand All @@ -296,11 +315,25 @@ gen_limit_context(Invoice, Payment, Route, CapturedCash) ->
op = {invoice_payment, #context_payproc_OperationInvoicePayment{}},
invoice = #context_payproc_Invoice{
invoice = Invoice,
payment = PaymentCtx
payment = PaymentCtx,
session = gen_limit_session_context(Session)
}
}
}.

gen_limit_session_context(undefined) ->
undefined;
gen_limit_session_context(Session) ->
#{target := SessionTargetStatus, trx := SessionTransactionInfo, route := Route} = Session,
#context_payproc_InvoicePaymentSession{
session = #payproc_InvoicePaymentSession{
target_status = SessionTargetStatus,
transaction_info = SessionTransactionInfo
},
result = maps:get(result, Session, undefined),
route = convert_to_limit_route(Route)
}.

gen_limit_shop_context(Invoice, Payment) ->
#limiter_LimitContext{
payment_processing = #context_payproc_Context{
Expand Down
5 changes: 3 additions & 2 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
{gproc, "0.9.0"},
{genlib, {git, "https://github.com/valitydev/genlib.git", {tag, "v1.1.0"}}},
{woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.1"}}},
{damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.23"}}},
{damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "BG-753/ft/card-failure-counter"}}},
{payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}},
{mg_proto, {git, "https://github.com/valitydev/machinegun-proto.git", {branch, "master"}}},
{dmt_client, {git, "https://github.com/valitydev/dmt-client.git", {tag, "v2.0.3"}}},
Expand All @@ -40,7 +40,8 @@
{bender_client, {git, "https://github.com/valitydev/bender-client-erlang.git", {tag, "v1.1.0"}}},
{erl_health, {git, "https://github.com/valitydev/erlang-health.git", {tag, "v1.0.0"}}},
{fault_detector_proto, {git, "https://github.com/valitydev/fault-detector-proto.git", {branch, "master"}}},
{limiter_proto, {git, "https://github.com/valitydev/limiter-proto.git", {tag, "v2.1.0"}}},
{limiter_proto,
{git, "https://github.com/valitydev/limiter-proto.git", {branch, "BG-753/ft/card-failure-counter"}}},
{herd, {git, "https://github.com/wgnet/herd.git", {tag, "1.3.4"}}},
{progressor, {git, "https://github.com/valitydev/progressor.git", {tag, "v1.0.20"}}},
{prometheus, "4.11.0"},
Expand Down
4 changes: 2 additions & 2 deletions rebar.lock
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
{<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2},
{<<"damsel">>,
{git,"https://github.com/valitydev/damsel.git",
{ref,"b5c1dc423365397d8c2d123ba5766147551f19cc"}},
{ref,"6c0af529ca0e32555264b986453bc6b234096ffd"}},
0},
{<<"dmt_client">>,
{git,"https://github.com/valitydev/dmt-client.git",
Expand Down Expand Up @@ -72,7 +72,7 @@
{<<"kafka_protocol">>,{pkg,<<"kafka_protocol">>,<<"4.1.10">>},2},
{<<"limiter_proto">>,
{git,"https://github.com/valitydev/limiter-proto.git",
{ref,"1af3724af24dd8b5ad9ce2ae80cd42318b471397"}},
{ref,"d90c1d123a8a67ec61762cf07a8344247e32ba05"}},
0},
{<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2},
{<<"mg_proto">>,
Expand Down
Loading