mirror of
https://github.com/valitydev/limiter.git
synced 2024-11-06 00:55:22 +00:00
TD-305: Add new payproc context and payment tool scope implementetion (#9)
* updated limiter proto * added payproc context * fixed linter * bumped proto * added base tests * added payment tool tests * added minor test * fixed dialyzer * fixed
This commit is contained in:
parent
d36b97f44a
commit
2dff7b518d
@ -8,7 +8,7 @@
|
||||
currency := currency()
|
||||
}.
|
||||
|
||||
-type currency() :: lim_base_thrift:'CurrencySymbolicCode'().
|
||||
-type currency() :: lim_domain_thrift:'CurrencySymbolicCode'().
|
||||
-type config() :: lim_config_machine:config().
|
||||
-type body_type() :: full | partial.
|
||||
|
||||
|
@ -85,16 +85,16 @@ marshal_behaviour(addition) ->
|
||||
marshal_time_range_type({calendar, CalendarType}) ->
|
||||
{calendar, marshal_calendar_time_range_type(CalendarType)};
|
||||
marshal_time_range_type({interval, Amount}) ->
|
||||
{interval, #time_range_TimeRangeTypeInterval{amount = Amount}}.
|
||||
{interval, #limiter_time_range_TimeRangeTypeInterval{amount = Amount}}.
|
||||
|
||||
marshal_calendar_time_range_type(day) ->
|
||||
{day, #time_range_TimeRangeTypeCalendarDay{}};
|
||||
{day, #limiter_time_range_TimeRangeTypeCalendarDay{}};
|
||||
marshal_calendar_time_range_type(week) ->
|
||||
{week, #time_range_TimeRangeTypeCalendarWeek{}};
|
||||
{week, #limiter_time_range_TimeRangeTypeCalendarWeek{}};
|
||||
marshal_calendar_time_range_type(month) ->
|
||||
{month, #time_range_TimeRangeTypeCalendarMonth{}};
|
||||
{month, #limiter_time_range_TimeRangeTypeCalendarMonth{}};
|
||||
marshal_calendar_time_range_type(year) ->
|
||||
{year, #time_range_TimeRangeTypeCalendarYear{}}.
|
||||
{year, #limiter_time_range_TimeRangeTypeCalendarYear{}}.
|
||||
|
||||
marshal_context_type(payment_processing) ->
|
||||
{payment_processing, #limiter_config_LimitContextTypePaymentProcessing{}}.
|
||||
@ -235,7 +235,7 @@ unmarshal_body_type_deprecated({cash, #limiter_config_LimitBodyTypeCash{currency
|
||||
|
||||
unmarshal_time_range_type({calendar, CalendarType}) ->
|
||||
{calendar, unmarshal_calendar_time_range_type(CalendarType)};
|
||||
unmarshal_time_range_type({interval, #time_range_TimeRangeTypeInterval{amount = Amount}}) ->
|
||||
unmarshal_time_range_type({interval, #limiter_time_range_TimeRangeTypeInterval{amount = Amount}}) ->
|
||||
{interval, Amount}.
|
||||
|
||||
unmarshal_calendar_time_range_type({day, _}) ->
|
||||
@ -308,7 +308,7 @@ unmarshal_created_w_deprecated_body_type_test_() ->
|
||||
created_at = lim_time:to_rfc3339(Now),
|
||||
started_at = <<"2000-01-01T00:00:00Z">>,
|
||||
shard_size = 42,
|
||||
time_range_type = {calendar, {day, #time_range_TimeRangeTypeCalendarDay{}}},
|
||||
time_range_type = {calendar, {day, #limiter_time_range_TimeRangeTypeCalendarDay{}}},
|
||||
context_type = {payment_processing, #limiter_config_LimitContextTypePaymentProcessing{}},
|
||||
body_type_deprecated = {cash, #limiter_config_LimitBodyTypeCash{currency = <<"☭☭☭"/utf8>>}}
|
||||
},
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
-type limit_type() :: {turnover, lim_turnover_metric:t()}.
|
||||
-type limit_scope() :: ordsets:ordset(limit_scope_type()).
|
||||
-type limit_scope_type() :: party | shop | wallet | identity.
|
||||
-type limit_scope_type() :: party | shop | wallet | identity | payment_tool.
|
||||
-type shard_size() :: pos_integer().
|
||||
-type shard_id() :: binary().
|
||||
-type prefix() :: binary().
|
||||
@ -560,11 +560,27 @@ append_context_bits(shop, Bits) ->
|
||||
% Also we need to preserve order between party / shop to ensure backwards compatibility.
|
||||
{order, 1, {from, payment_processing, owner_id, invoice}},
|
||||
{order, 2, {from, payment_processing, shop_id, invoice}}
|
||||
]).
|
||||
]);
|
||||
append_context_bits(payment_tool, Bits) ->
|
||||
ordsets:add_element(
|
||||
{from, payment_processing, payer, invoice_payment},
|
||||
Bits
|
||||
).
|
||||
|
||||
-spec extract_context_bit(context_bit(), lim_context()) -> {ok, binary()}.
|
||||
extract_context_bit({order, _, Bit}, LimitContext) ->
|
||||
extract_context_bit(Bit, LimitContext);
|
||||
extract_context_bit({from, payment_processing, payer, Op}, LimitContext) ->
|
||||
{ok, {_, PayerData}} = lim_context:get_from_context(payment_processing, payer, Op, LimitContext),
|
||||
#{payment_tool := {PaymentToolType, PaymentToolData}} = PayerData,
|
||||
case PaymentToolType of
|
||||
bank_card ->
|
||||
Token = maps:get(token, PaymentToolData),
|
||||
ExpData = maps:get(exp_date, PaymentToolData, <<>>),
|
||||
{ok, <<Token/binary, "/", ExpData/binary>>};
|
||||
_ ->
|
||||
{error, {unsupported_payment_tool_type, PaymentToolType}}
|
||||
end;
|
||||
extract_context_bit({from, ContextType, ValueName, Op}, LimitContext) ->
|
||||
lim_context:get_from_context(ContextType, ValueName, Op, LimitContext).
|
||||
|
||||
|
@ -23,7 +23,7 @@ handle_function(Fn, Args, WoodyCtx, Opts) ->
|
||||
-spec handle_function_(woody:func(), woody:args(), lim_context:t(), woody:options()) -> {ok, woody:result()}.
|
||||
handle_function_(
|
||||
'CreateLegacy',
|
||||
{#limiter_cfg_LimitCreateParams{
|
||||
{#limiter_configurator_LimitCreateParams{
|
||||
id = ID,
|
||||
name = Name,
|
||||
description = Description,
|
||||
@ -51,7 +51,7 @@ handle_function_(
|
||||
{error, {name, notfound}} ->
|
||||
woody_error:raise(
|
||||
business,
|
||||
#limiter_cfg_LimitConfigNameNotFound{}
|
||||
#limiter_configurator_LimitConfigNameNotFound{}
|
||||
)
|
||||
end;
|
||||
handle_function_('Create', {Params}, LimitContext, _Opts) ->
|
||||
@ -70,7 +70,7 @@ handle_function_('Get', {LimitID}, LimitContext, _Opts) ->
|
||||
{ok, LimitConfig} ->
|
||||
{ok, lim_config_codec:marshal_config(LimitConfig)};
|
||||
{error, notfound} ->
|
||||
woody_error:raise(business, #limiter_cfg_LimitConfigNotFound{})
|
||||
woody_error:raise(business, #limiter_configurator_LimitConfigNotFound{})
|
||||
end.
|
||||
|
||||
map_type({turnover, _}) ->
|
||||
@ -78,7 +78,7 @@ map_type({turnover, _}) ->
|
||||
map_type(_) ->
|
||||
woody_error:raise(
|
||||
business,
|
||||
#limiter_base_InvalidRequest{errors = [<<"Config type not found.">>]}
|
||||
#'InvalidRequest'{errors = [<<"Config type not found.">>]}
|
||||
).
|
||||
|
||||
mk_limit_config(<<"ShopDayTurnover">>) ->
|
||||
|
@ -18,6 +18,8 @@
|
||||
-type thrift_context() :: lim_limiter_thrift:'LimitContext'().
|
||||
-type clock() :: lim_limiter_thrift:'Clock'().
|
||||
-type id() :: binary().
|
||||
-type token() :: binary().
|
||||
-type exp_date() :: binary().
|
||||
-type cash() :: lim_body:cash().
|
||||
|
||||
-type t() :: #{
|
||||
@ -52,8 +54,8 @@
|
||||
shop_id => id(),
|
||||
cost => cash(),
|
||||
created_at => timestamp(),
|
||||
effective_adjustment => payment_processing_adjustment(),
|
||||
effective_payment => payment_processing_payment()
|
||||
adjustment => payment_processing_adjustment(),
|
||||
payment => payment_processing_payment()
|
||||
}.
|
||||
|
||||
-type payment_processing_adjustment() :: #{
|
||||
@ -68,10 +70,26 @@
|
||||
capture_cost => cash(),
|
||||
created_at => timestamp(),
|
||||
flow => instant | hold,
|
||||
payer => payment_resource | customer | recurrent,
|
||||
effective_adjustment => payment_processing_payment_adjustment(),
|
||||
effective_refund => payment_processing_payment_refund(),
|
||||
effective_chargeback => payment_processing_payment_chargeback()
|
||||
payer => payment_processing_payer(),
|
||||
adjustment => payment_processing_payment_adjustment(),
|
||||
refund => payment_processing_payment_refund(),
|
||||
chargeback => payment_processing_payment_chargeback()
|
||||
}.
|
||||
|
||||
-type payment_processing_payer() ::
|
||||
{payment_resource, payment_processing_payer_data()}
|
||||
| {customer, payment_processing_payer_data()}
|
||||
| {recurrent, payment_processing_payer_data()}.
|
||||
|
||||
-type payment_processing_payer_data() :: #{
|
||||
payment_tool => payment_processing_payment_tool()
|
||||
}.
|
||||
|
||||
-type payment_processing_payment_tool() :: {bank_card, payment_processing_bank_card()}.
|
||||
|
||||
-type payment_processing_bank_card() :: #{
|
||||
token => token(),
|
||||
exp_date => exp_date()
|
||||
}.
|
||||
|
||||
-type payment_processing_payment_adjustment() :: #{
|
||||
@ -93,6 +111,7 @@
|
||||
}.
|
||||
|
||||
-export_type([t/0]).
|
||||
-export_type([context/0]).
|
||||
-export_type([context_type/0]).
|
||||
-export_type([context_operation/0]).
|
||||
|
||||
@ -156,23 +175,23 @@ get_from_context(_, _ValueName, _Op, _LimContext) ->
|
||||
|
||||
get_payment_processing_operation_context(invoice, #{invoice := Invoice}) ->
|
||||
{ok, Invoice};
|
||||
get_payment_processing_operation_context(invoice_adjustment, #{invoice := #{effective_adjustment := Adjustment}}) ->
|
||||
get_payment_processing_operation_context(invoice_adjustment, #{invoice := #{adjustment := Adjustment}}) ->
|
||||
{ok, Adjustment};
|
||||
get_payment_processing_operation_context(invoice_payment, #{invoice := #{effective_payment := Payment}}) ->
|
||||
get_payment_processing_operation_context(invoice_payment, #{invoice := #{payment := Payment}}) ->
|
||||
{ok, Payment};
|
||||
get_payment_processing_operation_context(
|
||||
invoice_payment_adjustment,
|
||||
#{invoice := #{effective_payment := #{effective_adjustment := Adjustment}}}
|
||||
#{invoice := #{payment := #{adjustment := Adjustment}}}
|
||||
) ->
|
||||
{ok, Adjustment};
|
||||
get_payment_processing_operation_context(
|
||||
invoice_payment_refund,
|
||||
#{invoice := #{effective_payment := #{effective_refund := Refund}}}
|
||||
#{invoice := #{payment := #{refund := Refund}}}
|
||||
) ->
|
||||
{ok, Refund};
|
||||
get_payment_processing_operation_context(
|
||||
invoice_payment_chargeback,
|
||||
#{invoice := #{effective_payment := #{effective_chargeback := Chargeback}}}
|
||||
#{invoice := #{payment := #{chargeback := Chargeback}}}
|
||||
) ->
|
||||
{ok, Chargeback};
|
||||
get_payment_processing_operation_context(_, _) ->
|
||||
@ -180,126 +199,13 @@ get_payment_processing_operation_context(_, _) ->
|
||||
|
||||
%%
|
||||
|
||||
unmarshal_context(#limiter_context_LimitContext{payment_processing = PaymentProcessing}) ->
|
||||
#{payment_processing => unmarshal_payment_processing_context(PaymentProcessing)};
|
||||
unmarshal_context(#limiter_context_LimitContext{limiter_payment_processing = PaymentProcessing}) when
|
||||
PaymentProcessing =/= undefined
|
||||
->
|
||||
#{payment_processing => lim_limiter_context:unmarshal(PaymentProcessing)};
|
||||
unmarshal_context(#limiter_context_LimitContext{payment_processing = PaymentProcessing}) when
|
||||
PaymentProcessing =/= undefined
|
||||
->
|
||||
#{payment_processing => lim_payproc_context:unmarshal(PaymentProcessing)};
|
||||
unmarshal_context(_) ->
|
||||
#{}.
|
||||
|
||||
unmarshal_payment_processing_context(#limiter_context_ContextPaymentProcessing{
|
||||
op = {Operation, _},
|
||||
invoice = Invoice
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
op => Operation,
|
||||
invoice => maybe_unmarshal(Invoice, fun unmarshal_payment_processing_invoice/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice(#limiter_context_Invoice{
|
||||
id = ID,
|
||||
owner_id = OwnerID,
|
||||
shop_id = ShopID,
|
||||
cost = Cost,
|
||||
created_at = CreatedAt,
|
||||
effective_payment = EffectivePayment,
|
||||
effective_adjustment = EffectiveAdjustment
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1),
|
||||
shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1),
|
||||
cost => maybe_unmarshal(Cost, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1),
|
||||
effective_adjustment => maybe_unmarshal(
|
||||
EffectiveAdjustment,
|
||||
fun unmarshal_payment_processing_invoice_adjustment/1
|
||||
),
|
||||
effective_payment => maybe_unmarshal(EffectivePayment, fun unmarshal_payment_processing_invoice_payment/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_adjustment(#limiter_context_InvoiceAdjustment{id = ID}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_payment(#limiter_context_InvoicePayment{
|
||||
id = ID,
|
||||
owner_id = OwnerID,
|
||||
shop_id = ShopID,
|
||||
cost = Cost,
|
||||
capture_cost = CaptureCost,
|
||||
created_at = CreatedAt,
|
||||
flow = Flow,
|
||||
payer = Payer,
|
||||
effective_adjustment = EffectiveAdjustment,
|
||||
effective_refund = EffectiveRefund,
|
||||
effective_chargeback = EffectiveChargeback
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1),
|
||||
shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1),
|
||||
cost => maybe_unmarshal(Cost, fun unmarshal_cash/1),
|
||||
capture_cost => maybe_unmarshal(CaptureCost, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1),
|
||||
flow => maybe_unmarshal(Flow, fun unmarshal_payment_processing_invoice_payment_flow/1),
|
||||
payer => maybe_unmarshal(Payer, fun unmarshal_payment_processing_invoice_payment_payer/1),
|
||||
effective_adjustment => maybe_unmarshal(
|
||||
EffectiveAdjustment,
|
||||
fun unmarshal_payment_processing_invoice_payment_adjustment/1
|
||||
),
|
||||
effective_refund => maybe_unmarshal(EffectiveRefund, fun unmarshal_payment_processing_invoice_payment_refund/1),
|
||||
effective_chargeback => maybe_unmarshal(
|
||||
EffectiveChargeback,
|
||||
fun unmarshal_payment_processing_invoice_payment_chargeback/1
|
||||
)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_flow({Flow, _}) ->
|
||||
Flow.
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_payer({Payer, _}) ->
|
||||
Payer.
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_adjustment(#limiter_context_InvoicePaymentAdjustment{
|
||||
id = ID,
|
||||
created_at = CreatedAt
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_refund(#limiter_context_InvoicePaymentRefund{
|
||||
id = ID,
|
||||
cost = Cost,
|
||||
created_at = CreatedAt
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
cost => maybe_unmarshal(Cost, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_chargeback(#limiter_context_InvoicePaymentChargeback{
|
||||
id = ID,
|
||||
levy = Levy,
|
||||
body = Body,
|
||||
created_at = CreatedAt
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
levy => maybe_unmarshal(Levy, fun unmarshal_cash/1),
|
||||
body => maybe_unmarshal(Body, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_cash(#limiter_base_Cash{amount = Amount, currency = #limiter_base_CurrencyRef{symbolic_code = Currency}}) ->
|
||||
#{amount => Amount, currency => Currency}.
|
||||
|
||||
unmarshal_string(Value) ->
|
||||
Value.
|
||||
|
||||
maybe_unmarshal(undefined, _) ->
|
||||
undefined;
|
||||
maybe_unmarshal(Value, UnmarshalFun) ->
|
||||
UnmarshalFun(Value).
|
||||
|
@ -84,7 +84,7 @@ handle_get_error(Error) ->
|
||||
|
||||
-spec handle_hold_error(_) -> no_return().
|
||||
handle_hold_error({_, {invalid_request, Errors}}) ->
|
||||
woody_error:raise(business, #limiter_base_InvalidRequest{errors = Errors});
|
||||
woody_error:raise(business, #'InvalidRequest'{errors = Errors});
|
||||
handle_hold_error(Error) ->
|
||||
handle_default_error(Error).
|
||||
|
||||
@ -92,13 +92,13 @@ handle_hold_error(Error) ->
|
||||
handle_commit_error({_, {forbidden_operation_amount, Error}}) ->
|
||||
handle_forbidden_operation_amount_error(Error);
|
||||
handle_commit_error({_, {invalid_request, Errors}}) ->
|
||||
woody_error:raise(business, #limiter_base_InvalidRequest{errors = Errors});
|
||||
woody_error:raise(business, #'InvalidRequest'{errors = Errors});
|
||||
handle_commit_error(Error) ->
|
||||
handle_default_error(Error).
|
||||
|
||||
-spec handle_rollback_error(_) -> no_return().
|
||||
handle_rollback_error({_, {invalid_request, Errors}}) ->
|
||||
woody_error:raise(business, #limiter_base_InvalidRequest{errors = Errors});
|
||||
woody_error:raise(business, #'InvalidRequest'{errors = Errors});
|
||||
handle_rollback_error(Error) ->
|
||||
handle_default_error(Error).
|
||||
|
||||
|
129
apps/limiter/src/lim_limiter_context.erl
Normal file
129
apps/limiter/src/lim_limiter_context.erl
Normal file
@ -0,0 +1,129 @@
|
||||
-module(lim_limiter_context).
|
||||
|
||||
-include_lib("limiter_proto/include/lim_limiter_context_thrift.hrl").
|
||||
|
||||
-export([unmarshal/1]).
|
||||
|
||||
-type thrift_context() :: lim_limiter_context_thrift:'ContextPaymentProcessing'().
|
||||
|
||||
%%
|
||||
|
||||
-spec unmarshal(thrift_context()) -> lim_context:context().
|
||||
unmarshal(#limiter_context_ContextPaymentProcessing{
|
||||
op = {Operation, _},
|
||||
invoice = Invoice
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
op => Operation,
|
||||
invoice => maybe_unmarshal(Invoice, fun unmarshal_payment_processing_invoice/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice(#limiter_context_Invoice{
|
||||
id = ID,
|
||||
owner_id = OwnerID,
|
||||
shop_id = ShopID,
|
||||
cost = Cost,
|
||||
created_at = CreatedAt,
|
||||
effective_payment = Payment,
|
||||
effective_adjustment = Adjustment
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1),
|
||||
shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1),
|
||||
cost => maybe_unmarshal(Cost, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1),
|
||||
adjustment => maybe_unmarshal(
|
||||
Adjustment,
|
||||
fun unmarshal_payment_processing_invoice_adjustment/1
|
||||
),
|
||||
payment => maybe_unmarshal(Payment, fun unmarshal_payment_processing_invoice_payment/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_adjustment(#limiter_context_InvoiceAdjustment{id = ID}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_payment(#limiter_context_InvoicePayment{
|
||||
id = ID,
|
||||
owner_id = OwnerID,
|
||||
shop_id = ShopID,
|
||||
cost = Cost,
|
||||
capture_cost = CaptureCost,
|
||||
created_at = CreatedAt,
|
||||
flow = Flow,
|
||||
payer = Payer,
|
||||
effective_adjustment = Adjustment,
|
||||
effective_refund = EffectiveRefund,
|
||||
effective_chargeback = EffectiveChargeback
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1),
|
||||
shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1),
|
||||
cost => maybe_unmarshal(Cost, fun unmarshal_cash/1),
|
||||
capture_cost => maybe_unmarshal(CaptureCost, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1),
|
||||
flow => maybe_unmarshal(Flow, fun unmarshal_payment_processing_invoice_payment_flow/1),
|
||||
payer => maybe_unmarshal(Payer, fun unmarshal_payment_processing_invoice_payment_payer/1),
|
||||
adjustment => maybe_unmarshal(
|
||||
Adjustment,
|
||||
fun unmarshal_payment_processing_invoice_payment_adjustment/1
|
||||
),
|
||||
refund => maybe_unmarshal(EffectiveRefund, fun unmarshal_payment_processing_invoice_payment_refund/1),
|
||||
chargeback => maybe_unmarshal(
|
||||
EffectiveChargeback,
|
||||
fun unmarshal_payment_processing_invoice_payment_chargeback/1
|
||||
)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_flow({Flow, _}) ->
|
||||
Flow.
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_payer({Payer, _}) ->
|
||||
{Payer, #{}}.
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_adjustment(#limiter_context_InvoicePaymentAdjustment{
|
||||
id = ID,
|
||||
created_at = CreatedAt
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_refund(#limiter_context_InvoicePaymentRefund{
|
||||
id = ID,
|
||||
cost = Cost,
|
||||
created_at = CreatedAt
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
cost => maybe_unmarshal(Cost, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_chargeback(#limiter_context_InvoicePaymentChargeback{
|
||||
id = ID,
|
||||
levy = Levy,
|
||||
body = Body,
|
||||
created_at = CreatedAt
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
levy => maybe_unmarshal(Levy, fun unmarshal_cash/1),
|
||||
body => maybe_unmarshal(Body, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_cash(#domain_Cash{amount = Amount, currency = #domain_CurrencyRef{symbolic_code = Currency}}) ->
|
||||
#{amount => Amount, currency => Currency}.
|
||||
|
||||
unmarshal_string(Value) ->
|
||||
Value.
|
||||
|
||||
maybe_unmarshal(undefined, _) ->
|
||||
undefined;
|
||||
maybe_unmarshal(Value, UnmarshalFun) ->
|
||||
UnmarshalFun(Value).
|
213
apps/limiter/src/lim_payproc_context.erl
Normal file
213
apps/limiter/src/lim_payproc_context.erl
Normal file
@ -0,0 +1,213 @@
|
||||
-module(lim_payproc_context).
|
||||
|
||||
-include_lib("limiter_proto/include/lim_limiter_payproc_context_thrift.hrl").
|
||||
|
||||
-export([unmarshal/1]).
|
||||
|
||||
-type thrift_context() :: lim_limiter_payproc_context_thrift:'Context'().
|
||||
|
||||
%%
|
||||
|
||||
-spec unmarshal(thrift_context()) -> lim_context:context().
|
||||
unmarshal(#limiter_context_payproc_Context{
|
||||
op = {Operation, _},
|
||||
invoice = Invoice
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
op => Operation,
|
||||
invoice => maybe_unmarshal(Invoice, fun unmarshal_payment_processing_invoice/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice(#limiter_context_payproc_Invoice{
|
||||
invoice = #domain_Invoice{
|
||||
id = ID,
|
||||
owner_id = OwnerID,
|
||||
shop_id = ShopID,
|
||||
cost = Cost,
|
||||
created_at = CreatedAt
|
||||
},
|
||||
payment = Payment,
|
||||
adjustment = Adjustment
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1),
|
||||
shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1),
|
||||
cost => maybe_unmarshal(Cost, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1),
|
||||
adjustment => maybe_unmarshal(
|
||||
Adjustment,
|
||||
fun unmarshal_payment_processing_invoice_adjustment/1
|
||||
),
|
||||
payment => maybe_unmarshal(Payment, fun unmarshal_payment_processing_invoice_payment/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_adjustment(#domain_InvoiceAdjustment{id = ID}) ->
|
||||
#{id => unmarshal_string(ID)}.
|
||||
|
||||
unmarshal_payment_processing_invoice_payment(#limiter_context_payproc_InvoicePayment{
|
||||
payment = #domain_InvoicePayment{
|
||||
id = ID,
|
||||
owner_id = OwnerID,
|
||||
shop_id = ShopID,
|
||||
cost = Cost,
|
||||
created_at = CreatedAt,
|
||||
flow = Flow,
|
||||
status = Status,
|
||||
payer = Payer
|
||||
},
|
||||
adjustment = Adjustment,
|
||||
refund = EffectiveRefund,
|
||||
chargeback = EffectiveChargeback
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
owner_id => maybe_unmarshal(OwnerID, fun unmarshal_string/1),
|
||||
shop_id => maybe_unmarshal(ShopID, fun unmarshal_string/1),
|
||||
cost => maybe_unmarshal(Cost, fun unmarshal_cash/1),
|
||||
capture_cost => get_capture_cost_from_status(Status),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1),
|
||||
flow => maybe_unmarshal(Flow, fun unmarshal_payment_processing_invoice_payment_flow/1),
|
||||
payer => maybe_unmarshal(Payer, fun unmarshal_payment_processing_invoice_payment_payer/1),
|
||||
adjustment => maybe_unmarshal(
|
||||
Adjustment,
|
||||
fun unmarshal_payment_processing_invoice_payment_adjustment/1
|
||||
),
|
||||
refund => maybe_unmarshal(EffectiveRefund, fun unmarshal_payment_processing_invoice_payment_refund/1),
|
||||
chargeback => maybe_unmarshal(
|
||||
EffectiveChargeback,
|
||||
fun unmarshal_payment_processing_invoice_payment_chargeback/1
|
||||
)
|
||||
}).
|
||||
|
||||
get_capture_cost_from_status({captured, #domain_InvoicePaymentCaptured{cost = Cost}}) ->
|
||||
maybe_unmarshal(Cost, fun unmarshal_cash/1);
|
||||
get_capture_cost_from_status(_) ->
|
||||
undefined.
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_flow({Flow, _}) ->
|
||||
Flow.
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_payer({Payer, Data}) ->
|
||||
{Payer, unmarshal_payment_processing_invoice_payment_payer_data(Data)}.
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_payer_data(#domain_PaymentResourcePayer{
|
||||
resource = #domain_DisposablePaymentResource{payment_tool = PaymentTool}
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
payment_tool => maybe_unmarshal(PaymentTool, fun unmarshal_payment_processing_payment_tool/1)
|
||||
});
|
||||
unmarshal_payment_processing_invoice_payment_payer_data(#domain_CustomerPayer{payment_tool = PaymentTool}) ->
|
||||
genlib_map:compact(#{
|
||||
payment_tool => maybe_unmarshal(PaymentTool, fun unmarshal_payment_processing_payment_tool/1)
|
||||
});
|
||||
unmarshal_payment_processing_invoice_payment_payer_data(#domain_RecurrentPayer{payment_tool = PaymentTool}) ->
|
||||
genlib_map:compact(#{
|
||||
payment_tool => maybe_unmarshal(PaymentTool, fun unmarshal_payment_processing_payment_tool/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_payment_tool({bank_card, #domain_BankCard{token = Token, exp_date = ExpDate}}) ->
|
||||
{bank_card, #{
|
||||
token => Token,
|
||||
exp_date => maybe_unmarshal(ExpDate, fun unmarshal_payment_processing_bank_card_exp_data/1)
|
||||
}};
|
||||
unmarshal_payment_processing_payment_tool(_) ->
|
||||
undefined.
|
||||
|
||||
unmarshal_payment_processing_bank_card_exp_data(#domain_BankCardExpDate{month = Month, year = Year}) ->
|
||||
BinaryMonth = integer_to_binary(Month),
|
||||
BinaryYear = integer_to_binary(Year),
|
||||
<<BinaryMonth/binary, "/", BinaryYear/binary>>.
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_adjustment(#domain_InvoicePaymentAdjustment{
|
||||
id = ID,
|
||||
created_at = CreatedAt
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_refund(#domain_InvoicePaymentRefund{
|
||||
id = ID,
|
||||
cash = Cost,
|
||||
created_at = CreatedAt
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
cost => maybe_unmarshal(Cost, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_payment_processing_invoice_payment_chargeback(#domain_InvoicePaymentChargeback{
|
||||
id = ID,
|
||||
levy = Levy,
|
||||
body = Body,
|
||||
created_at = CreatedAt
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => maybe_unmarshal(ID, fun unmarshal_string/1),
|
||||
levy => maybe_unmarshal(Levy, fun unmarshal_cash/1),
|
||||
body => maybe_unmarshal(Body, fun unmarshal_cash/1),
|
||||
created_at => maybe_unmarshal(CreatedAt, fun unmarshal_string/1)
|
||||
}).
|
||||
|
||||
unmarshal_cash(#domain_Cash{amount = Amount, currency = #domain_CurrencyRef{symbolic_code = Currency}}) ->
|
||||
#{amount => Amount, currency => Currency}.
|
||||
|
||||
unmarshal_string(Value) ->
|
||||
Value.
|
||||
|
||||
maybe_unmarshal(undefined, _) ->
|
||||
undefined;
|
||||
maybe_unmarshal(Value, UnmarshalFun) ->
|
||||
UnmarshalFun(Value).
|
||||
|
||||
-ifdef(TEST).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
-spec test() -> _.
|
||||
|
||||
-spec marshal_unmarshal_created_test() -> _.
|
||||
marshal_unmarshal_created_test() ->
|
||||
ExpDate = #domain_BankCardExpDate{month = 2, year = 2022},
|
||||
PaymentTool =
|
||||
{bank_card, #domain_BankCard{
|
||||
token = <<"Token">>,
|
||||
bin = <<"bin">>,
|
||||
exp_date = ExpDate,
|
||||
last_digits = <<"1234">>
|
||||
}},
|
||||
Data0 = #domain_PaymentResourcePayer{
|
||||
resource = #domain_DisposablePaymentResource{payment_tool = PaymentTool},
|
||||
contact_info = #domain_ContactInfo{}
|
||||
},
|
||||
#{payment_tool := _} = unmarshal_payment_processing_invoice_payment_payer_data(Data0),
|
||||
Data1 = #domain_CustomerPayer{
|
||||
customer_id = <<"customer_id">>,
|
||||
customer_binding_id = <<"customer_binding_id">>,
|
||||
rec_payment_tool_id = <<"rec_payment_tool_id">>,
|
||||
payment_tool = PaymentTool,
|
||||
contact_info = #domain_ContactInfo{}
|
||||
},
|
||||
#{payment_tool := _} = unmarshal_payment_processing_invoice_payment_payer_data(Data1),
|
||||
Data2 = #domain_RecurrentPayer{
|
||||
payment_tool = PaymentTool,
|
||||
recurrent_parent = #domain_RecurrentParentPayment{
|
||||
invoice_id = <<"invoice_id">>,
|
||||
payment_id = <<"payment_id">>
|
||||
},
|
||||
contact_info = #domain_ContactInfo{}
|
||||
},
|
||||
#{payment_tool := _} = unmarshal_payment_processing_invoice_payment_payer_data(Data2),
|
||||
Data3 = #domain_RecurrentPayer{
|
||||
payment_tool = {payment_terminal, #domain_PaymentTerminal{}},
|
||||
recurrent_parent = #domain_RecurrentParentPayment{
|
||||
invoice_id = <<"invoice_id">>,
|
||||
payment_id = <<"payment_id">>
|
||||
},
|
||||
contact_info = #domain_ContactInfo{}
|
||||
},
|
||||
#{} = unmarshal_payment_processing_invoice_payment_payer_data(Data3).
|
||||
|
||||
-endif.
|
@ -48,7 +48,7 @@ marshal(time_range, #{
|
||||
account_id_from := AccountIDFrom,
|
||||
account_id_to := AccountIDTo
|
||||
}) ->
|
||||
#time_range_TimeRange{
|
||||
#limiter_time_range_TimeRange{
|
||||
upper = Upper,
|
||||
lower = Lower,
|
||||
account_id_from = AccountIDFrom,
|
||||
@ -57,15 +57,15 @@ marshal(time_range, #{
|
||||
marshal(time_range_type, {calendar, SubType}) ->
|
||||
{calendar, marshal(time_range_sub_type, SubType)};
|
||||
marshal(time_range_type, {interval, Interval}) ->
|
||||
{interval, #time_range_TimeRangeTypeInterval{amount = Interval}};
|
||||
{interval, #limiter_time_range_TimeRangeTypeInterval{amount = Interval}};
|
||||
marshal(time_range_sub_type, year) ->
|
||||
{year, #time_range_TimeRangeTypeCalendarYear{}};
|
||||
{year, #limiter_time_range_TimeRangeTypeCalendarYear{}};
|
||||
marshal(time_range_sub_type, month) ->
|
||||
{month, #time_range_TimeRangeTypeCalendarMonth{}};
|
||||
{month, #limiter_time_range_TimeRangeTypeCalendarMonth{}};
|
||||
marshal(time_range_sub_type, week) ->
|
||||
{week, #time_range_TimeRangeTypeCalendarWeek{}};
|
||||
{week, #limiter_time_range_TimeRangeTypeCalendarWeek{}};
|
||||
marshal(time_range_sub_type, day) ->
|
||||
{day, #time_range_TimeRangeTypeCalendarDay{}};
|
||||
{day, #limiter_time_range_TimeRangeTypeCalendarDay{}};
|
||||
marshal(timestamp, {DateTime, USec}) ->
|
||||
DateTimeinSeconds = genlib_time:daytime_to_unixtime(DateTime),
|
||||
{TimeinUnit, Unit} =
|
||||
@ -99,7 +99,7 @@ unmarshal(range, #limiter_range_LimitRange{
|
||||
created_at => CreatedAt,
|
||||
currency => Currency
|
||||
});
|
||||
unmarshal(time_range, #time_range_TimeRange{
|
||||
unmarshal(time_range, #limiter_time_range_TimeRange{
|
||||
upper = Upper,
|
||||
lower = Lower,
|
||||
account_id_from = AccountIDFrom,
|
||||
@ -113,7 +113,7 @@ unmarshal(time_range, #time_range_TimeRange{
|
||||
};
|
||||
unmarshal(time_range_type, {calendar, SubType}) ->
|
||||
{calendar, unmarshal(time_range_sub_type, SubType)};
|
||||
unmarshal(time_range_type, {interval, #time_range_TimeRangeTypeInterval{amount = Interval}}) ->
|
||||
unmarshal(time_range_type, {interval, #limiter_time_range_TimeRangeTypeInterval{amount = Interval}}) ->
|
||||
{interval, Interval};
|
||||
unmarshal(time_range_sub_type, {year, _}) ->
|
||||
year;
|
||||
|
@ -3,7 +3,7 @@
|
||||
-export([compute/4]).
|
||||
|
||||
-type amount() :: lim_body:amount().
|
||||
-type currency() :: lim_base_thrift:'CurrencySymbolicCode'().
|
||||
-type currency() :: lim_domain_thrift:'CurrencySymbolicCode'().
|
||||
-type stage() :: hold | commit.
|
||||
-type t() :: number | {amount, currency()}.
|
||||
|
||||
|
@ -81,7 +81,7 @@ legacy_create_config(C) ->
|
||||
Client = lim_client:new(),
|
||||
ID = ?config(limit_id, C),
|
||||
Description = genlib:unique(),
|
||||
Params = #limiter_cfg_LimitCreateParams{
|
||||
Params = #limiter_configurator_LimitCreateParams{
|
||||
id = ID,
|
||||
name = <<"GlobalMonthTurnover">>,
|
||||
description = Description,
|
||||
@ -150,7 +150,7 @@ get_config(C) ->
|
||||
|
||||
prepare_environment(ID, LimitName, _C) ->
|
||||
Client = lim_client:new(),
|
||||
Params = #limiter_cfg_LimitCreateParams{
|
||||
Params = #limiter_configurator_LimitCreateParams{
|
||||
id = ID,
|
||||
name = LimitName,
|
||||
description = <<"description">>,
|
||||
|
@ -4,11 +4,13 @@
|
||||
-include_lib("limiter_proto/include/lim_configurator_thrift.hrl").
|
||||
|
||||
-define(currency, <<"RUB">>).
|
||||
-define(string, <<"STRING">>).
|
||||
-define(timestamp, <<"2000-01-01T00:00:00Z">>).
|
||||
|
||||
-define(cash(Amount), ?cash(Amount, ?currency)).
|
||||
-define(cash(Amount, Currency), #limiter_base_Cash{
|
||||
-define(cash(Amount, Currency), #domain_Cash{
|
||||
amount = Amount,
|
||||
currency = #limiter_base_CurrencyRef{symbolic_code = Currency}
|
||||
currency = #domain_CurrencyRef{symbolic_code = Currency}
|
||||
}).
|
||||
|
||||
-define(scope(Types), {multi, ordsets:from_list(Types)}).
|
||||
@ -16,6 +18,7 @@
|
||||
|
||||
-define(scope_party(), {party, #limiter_config_LimitScopeEmptyDetails{}}).
|
||||
-define(scope_shop(), {shop, #limiter_config_LimitScopeEmptyDetails{}}).
|
||||
-define(scope_payment_tool(), {payment_tool, #limiter_config_LimitScopeEmptyDetails{}}).
|
||||
|
||||
-define(lim_type_turnover(), ?lim_type_turnover(?turnover_metric_number())).
|
||||
-define(lim_type_turnover(Metric),
|
||||
@ -29,13 +32,16 @@
|
||||
).
|
||||
|
||||
-define(time_range_day(),
|
||||
{calendar, {day, #time_range_TimeRangeTypeCalendarDay{}}}
|
||||
{calendar, {day, #limiter_time_range_TimeRangeTypeCalendarDay{}}}
|
||||
).
|
||||
-define(time_range_week(),
|
||||
{calendar, {week, #time_range_TimeRangeTypeCalendarWeek{}}}
|
||||
{calendar, {week, #limiter_time_range_TimeRangeTypeCalendarWeek{}}}
|
||||
).
|
||||
-define(time_range_month(),
|
||||
{calendar, {month, #time_range_TimeRangeTypeCalendarMonth{}}}
|
||||
{calendar, {month, #limiter_time_range_TimeRangeTypeCalendarMonth{}}}
|
||||
).
|
||||
-define(time_range_year(),
|
||||
{calendar, {year, #limiter_time_range_TimeRangeTypeCalendarYear{}}}
|
||||
).
|
||||
|
||||
-define(op_behaviour(), ?op_behaviour(?op_addition())).
|
||||
@ -54,7 +60,7 @@
|
||||
-define(op_invoice_payment(), {invoice_payment, #limiter_context_PaymentProcessingOperationInvoicePayment{}}).
|
||||
|
||||
-define(ctx_invoice(Cost), #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
limiter_payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
op = ?op_invoice(),
|
||||
invoice = #limiter_context_Invoice{
|
||||
created_at = <<"2000-01-01T00:00:00Z">>,
|
||||
@ -66,7 +72,7 @@
|
||||
-define(ctx_invoice_payment(Cost, CaptureCost), ?ctx_invoice_payment(undefined, undefined, Cost, CaptureCost)).
|
||||
|
||||
-define(ctx_invoice_payment(OwnerID, ShopID, Cost, CaptureCost), #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
limiter_payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
op = ?op_invoice_payment(),
|
||||
invoice = #limiter_context_Invoice{
|
||||
owner_id = OwnerID,
|
||||
@ -74,14 +80,19 @@
|
||||
effective_payment = #limiter_context_InvoicePayment{
|
||||
created_at = <<"2000-01-01T00:00:00Z">>,
|
||||
cost = Cost,
|
||||
capture_cost = CaptureCost
|
||||
}
|
||||
capture_cost = CaptureCost,
|
||||
flow = {hold, #limiter_context_InvoicePaymentFlowHold{}},
|
||||
payer = {payment_resource, #limiter_context_PaymentResourcePayer{}},
|
||||
effective_adjustment = #limiter_context_InvoicePaymentAdjustment{},
|
||||
effective_chargeback = #limiter_context_InvoicePaymentChargeback{}
|
||||
},
|
||||
effective_adjustment = #limiter_context_InvoiceAdjustment{}
|
||||
}
|
||||
}
|
||||
}).
|
||||
|
||||
-define(ctx_invoice_payment(Payment), #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
limiter_payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
op = ?op_invoice_payment(),
|
||||
invoice = #limiter_context_Invoice{
|
||||
effective_payment = Payment
|
||||
@ -90,7 +101,7 @@
|
||||
}).
|
||||
|
||||
-define(ctx_invoice_payment_refund(OwnerID, ShopID, Cost, CaptureCost, RefundCost), #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
limiter_payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
op = {invoice_payment_refund, #limiter_context_PaymentProcessingOperationInvoicePaymentRefund{}},
|
||||
invoice = #limiter_context_Invoice{
|
||||
owner_id = OwnerID,
|
||||
@ -108,4 +119,109 @@
|
||||
}
|
||||
}).
|
||||
|
||||
%% Payproc
|
||||
|
||||
-define(payproc_op_invoice, {invoice, #limiter_context_payproc_OperationInvoice{}}).
|
||||
-define(payproc_op_invoice_payment, {invoice_payment, #limiter_context_payproc_OperationInvoicePayment{}}).
|
||||
|
||||
-define(payproc_bank_card(),
|
||||
?payproc_bank_card(?string, 2, 2022)
|
||||
).
|
||||
|
||||
-define(payproc_bank_card(Token, Month, Year), #domain_BankCard{
|
||||
token = Token,
|
||||
bin = ?string,
|
||||
last_digits = ?string,
|
||||
exp_date = #domain_BankCardExpDate{month = Month, year = Year}
|
||||
}).
|
||||
|
||||
-define(payproc_invoice(OwnerID, ShopID, Cost), #domain_Invoice{
|
||||
id = ?string,
|
||||
owner_id = OwnerID,
|
||||
shop_id = ShopID,
|
||||
created_at = ?timestamp,
|
||||
status = {unpaid, #domain_InvoiceUnpaid{}},
|
||||
details = #domain_InvoiceDetails{product = ?string},
|
||||
due = ?timestamp,
|
||||
cost = Cost
|
||||
}).
|
||||
|
||||
-define(payproc_invoice_payment(Cost, CaptureCost),
|
||||
?payproc_invoice_payment(Cost, CaptureCost, {bank_card, ?payproc_bank_card()})
|
||||
).
|
||||
|
||||
-define(payproc_invoice_payment(Cost, CaptureCost, PaymentTool), #domain_InvoicePayment{
|
||||
id = ?string,
|
||||
created_at = ?timestamp,
|
||||
status = {captured, #domain_InvoicePaymentCaptured{cost = CaptureCost}},
|
||||
cost = Cost,
|
||||
domain_revision = 1,
|
||||
flow = {instant, #domain_InvoicePaymentFlowInstant{}},
|
||||
payer =
|
||||
{payment_resource, #domain_PaymentResourcePayer{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = PaymentTool
|
||||
},
|
||||
contact_info = #domain_ContactInfo{}
|
||||
}}
|
||||
}).
|
||||
|
||||
-define(payproc_ctx_invoice(Cost), #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_payproc_Context{
|
||||
op = ?payproc_op_invoice,
|
||||
invoice = #limiter_context_payproc_Invoice{
|
||||
invoice = ?payproc_invoice(?string, ?string, Cost)
|
||||
}
|
||||
}
|
||||
}).
|
||||
|
||||
-define(payproc_ctx_invoice_payment(Cost, CaptureCost),
|
||||
?payproc_ctx_invoice_payment(?string, ?string, Cost, CaptureCost)
|
||||
).
|
||||
|
||||
-define(payproc_ctx_invoice_payment(OwnerID, ShopID, Cost, CaptureCost), #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_payproc_Context{
|
||||
op = ?payproc_op_invoice_payment,
|
||||
invoice = #limiter_context_payproc_Invoice{
|
||||
invoice = ?payproc_invoice(OwnerID, ShopID, Cost),
|
||||
payment = #limiter_context_payproc_InvoicePayment{
|
||||
payment = ?payproc_invoice_payment(Cost, CaptureCost)
|
||||
}
|
||||
}
|
||||
}
|
||||
}).
|
||||
|
||||
-define(payproc_ctx_invoice_payment(Payment), #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_payproc_Context{
|
||||
op = ?payproc_op_invoice_payment,
|
||||
invoice = #limiter_context_payproc_Invoice{
|
||||
invoice = ?payproc_invoice(?string, ?string, ?cash(10)),
|
||||
payment = #limiter_context_payproc_InvoicePayment{
|
||||
payment = Payment
|
||||
}
|
||||
}
|
||||
}
|
||||
}).
|
||||
|
||||
-define(payproc_ctx_invoice_payment_refund(OwnerID, ShopID, Cost, CaptureCost, RefundCost),
|
||||
#limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_payproc_Context{
|
||||
op = {invoice_payment_refund, #limiter_context_payproc_OperationInvoicePaymentRefund{}},
|
||||
invoice = #limiter_context_payproc_Invoice{
|
||||
invoice = ?payproc_invoice(OwnerID, ShopID, Cost),
|
||||
payment = #limiter_context_payproc_InvoicePayment{
|
||||
payment = ?payproc_invoice_payment(Cost, CaptureCost),
|
||||
refund = #domain_InvoicePaymentRefund{
|
||||
id = ?string,
|
||||
status = {succeeded, #domain_InvoicePaymentRefundSucceeded{}},
|
||||
created_at = ?timestamp,
|
||||
domain_revision = 1,
|
||||
cash = RefundCost
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
).
|
||||
|
||||
-endif.
|
||||
|
@ -40,6 +40,12 @@
|
||||
-export([commit_refund_keep_number_unchanged/1]).
|
||||
-export([partial_commit_number_counts_as_single_op/1]).
|
||||
|
||||
-export([payproc_hold_ok/1]).
|
||||
-export([payproc_commit_ok/1]).
|
||||
-export([payproc_rollback_ok/1]).
|
||||
-export([payproc_refund_ok/1]).
|
||||
-export([payproc_commit_with_payment_tool_scope_ok/1]).
|
||||
|
||||
-type group_name() :: atom().
|
||||
-type test_case_name() :: atom().
|
||||
|
||||
@ -72,7 +78,12 @@ groups() ->
|
||||
refund_ok,
|
||||
commit_inexistent_hold_fails,
|
||||
partial_commit_inexistent_hold_fails,
|
||||
commit_multirange_limit_ok
|
||||
commit_multirange_limit_ok,
|
||||
payproc_hold_ok,
|
||||
payproc_commit_ok,
|
||||
payproc_rollback_ok,
|
||||
payproc_refund_ok,
|
||||
payproc_commit_with_payment_tool_scope_ok
|
||||
]},
|
||||
{cashless, [parallel], [
|
||||
commit_number_ok,
|
||||
@ -145,13 +156,13 @@ commit_with_default_exchange(C) ->
|
||||
_ = mock_exchange(Rational, C),
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
Context = #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
limiter_payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
op = {invoice, #limiter_context_PaymentProcessingOperationInvoice{}},
|
||||
invoice = #limiter_context_Invoice{
|
||||
created_at = <<"2000-01-01T00:00:00Z">>,
|
||||
cost = #limiter_base_Cash{
|
||||
cost = #domain_Cash{
|
||||
amount = 10000,
|
||||
currency = #limiter_base_CurrencyRef{symbolic_code = <<"SOME_CURRENCY">>}
|
||||
currency = #domain_CurrencyRef{symbolic_code = <<"SOME_CURRENCY">>}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,18 +176,18 @@ partial_commit_with_exchange(C) ->
|
||||
_ = mock_exchange(Rational, C),
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
Context = #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
limiter_payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
op = {invoice_payment, #limiter_context_PaymentProcessingOperationInvoicePayment{}},
|
||||
invoice = #limiter_context_Invoice{
|
||||
effective_payment = #limiter_context_InvoicePayment{
|
||||
created_at = <<"2000-01-01T00:00:00Z">>,
|
||||
cost = #limiter_base_Cash{
|
||||
cost = #domain_Cash{
|
||||
amount = 10000,
|
||||
currency = #limiter_base_CurrencyRef{symbolic_code = <<"USD">>}
|
||||
currency = #domain_CurrencyRef{symbolic_code = <<"USD">>}
|
||||
},
|
||||
capture_cost = #limiter_base_Cash{
|
||||
capture_cost = #domain_Cash{
|
||||
amount = 8000,
|
||||
currency = #limiter_base_CurrencyRef{symbolic_code = <<"USD">>}
|
||||
currency = #domain_CurrencyRef{symbolic_code = <<"USD">>}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -191,13 +202,13 @@ commit_with_exchange(C) ->
|
||||
_ = mock_exchange(Rational, C),
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
Context = #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
limiter_payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
op = {invoice, #limiter_context_PaymentProcessingOperationInvoice{}},
|
||||
invoice = #limiter_context_Invoice{
|
||||
created_at = <<"2000-01-01T00:00:00Z">>,
|
||||
cost = #limiter_base_Cash{
|
||||
cost = #domain_Cash{
|
||||
amount = 10000,
|
||||
currency = #limiter_base_CurrencyRef{symbolic_code = <<"USD">>}
|
||||
currency = #domain_CurrencyRef{symbolic_code = <<"USD">>}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -251,13 +262,13 @@ hold_ok(C) ->
|
||||
commit_ok(C) ->
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
Context = #limiter_context_LimitContext{
|
||||
payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
limiter_payment_processing = #limiter_context_ContextPaymentProcessing{
|
||||
op = {invoice, #limiter_context_PaymentProcessingOperationInvoice{}},
|
||||
invoice = #limiter_context_Invoice{
|
||||
created_at = <<"2000-01-01T00:00:00Z">>,
|
||||
cost = #limiter_base_Cash{
|
||||
cost = #domain_Cash{
|
||||
amount = 10,
|
||||
currency = #limiter_base_CurrencyRef{symbolic_code = <<"RUB">>}
|
||||
currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -299,7 +310,7 @@ commit_inexistent_hold_fails(C) ->
|
||||
% NOTE
|
||||
% We do not expect `LimitChangeNotFound` here because we no longer reconcile with accounter
|
||||
% before requesting him to hold / commit.
|
||||
{exception, #limiter_base_InvalidRequest{}} =
|
||||
{exception, #'InvalidRequest'{}} =
|
||||
lim_client:commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)).
|
||||
|
||||
-spec partial_commit_inexistent_hold_fails(config()) -> _.
|
||||
@ -309,7 +320,7 @@ partial_commit_inexistent_hold_fails(C) ->
|
||||
% NOTE
|
||||
% We do not expect `LimitChangeNotFound` here because we no longer reconcile with accounter
|
||||
% before requesting him to hold / commit.
|
||||
{exception, #limiter_base_InvalidRequest{}} =
|
||||
{exception, #'InvalidRequest'{}} =
|
||||
lim_client:commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)).
|
||||
|
||||
-spec commit_multirange_limit_ok(config()) -> _.
|
||||
@ -468,6 +479,79 @@ partial_commit_number_counts_as_single_op(C) ->
|
||||
|
||||
%%
|
||||
|
||||
-spec payproc_hold_ok(config()) -> _.
|
||||
payproc_hold_ok(C) ->
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
Context = ?payproc_ctx_invoice(?cash(10)),
|
||||
{ok, {vector, #limiter_VectorClock{}}} = lim_client:hold(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
|
||||
-spec payproc_commit_ok(config()) -> _.
|
||||
payproc_commit_ok(C) ->
|
||||
ID = configure_limit(?time_range_year(), ?global(), C),
|
||||
Context = ?payproc_ctx_invoice(?cash(10)),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
|
||||
-spec payproc_rollback_ok(config()) -> _.
|
||||
payproc_rollback_ok(C) ->
|
||||
ID = configure_limit(?time_range_week(), ?global(), C),
|
||||
Context0 = ?payproc_ctx_invoice_payment(?cash(10), ?cash(10)),
|
||||
Context1 = ?payproc_ctx_invoice_payment(?cash(10), ?cash(0)),
|
||||
Change = ?LIMIT_CHANGE(ID),
|
||||
{ok, {vector, _}} = lim_client:hold(Change, Context0, ?config(client, C)),
|
||||
{ok, {vector, _}} = lim_client:commit(Change, Context1, ?config(client, C)).
|
||||
|
||||
-spec payproc_refund_ok(config()) -> _.
|
||||
payproc_refund_ok(C) ->
|
||||
Client = ?config(client, C),
|
||||
OwnerID = <<"WWWcool Ltd">>,
|
||||
ShopID = <<"shop">>,
|
||||
ID = configure_limit(?time_range_day(), ?scope([?scope_party(), ?scope_shop()]), C),
|
||||
Context0 = ?payproc_ctx_invoice_payment(OwnerID, ShopID, ?cash(15), ?cash(15)),
|
||||
RefundContext1 = ?payproc_ctx_invoice_payment_refund(OwnerID, ShopID, ?cash(10), ?cash(10), ?cash(10)),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, <<"Payment">>), Context0, Client),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, <<"Refund">>), RefundContext1, Client),
|
||||
{ok, #limiter_Limit{} = Limit2} = lim_client:get(ID, RefundContext1, Client),
|
||||
?assertEqual(Limit2#limiter_Limit.amount, 5).
|
||||
|
||||
-spec payproc_commit_with_payment_tool_scope_ok(config()) -> _.
|
||||
payproc_commit_with_payment_tool_scope_ok(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?scope([?scope_payment_tool()]), ?turnover_metric_number(), C),
|
||||
Context0 = ?payproc_ctx_invoice_payment(
|
||||
?payproc_invoice_payment(
|
||||
?cash(10),
|
||||
?cash(10),
|
||||
{bank_card, ?payproc_bank_card()}
|
||||
)
|
||||
),
|
||||
Context1 = ?payproc_ctx_invoice_payment(
|
||||
?payproc_invoice_payment(
|
||||
?cash(10),
|
||||
?cash(10),
|
||||
{bank_card, ?payproc_bank_card(<<"OtherToken">>, 2, 2022)}
|
||||
)
|
||||
),
|
||||
Context2 = ?payproc_ctx_invoice_payment(
|
||||
?payproc_invoice_payment(
|
||||
?cash(10),
|
||||
?cash(10),
|
||||
{bank_card, ?payproc_bank_card(?string, 3, 2022)}
|
||||
)
|
||||
),
|
||||
{ok, LimitState0} = lim_client:get(ID, Context0, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 1), Context0, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 2), Context1, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 3), Context2, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Context0, Client),
|
||||
?assertEqual(
|
||||
LimitState1#limiter_Limit.amount,
|
||||
LimitState0#limiter_Limit.amount + 1
|
||||
).
|
||||
|
||||
%%
|
||||
|
||||
gen_change_id(LimitID, ChangeID) ->
|
||||
genlib:format("~s/~p", [LimitID, ChangeID]).
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
||||
% mandatory
|
||||
unmatched_returns,
|
||||
error_handling,
|
||||
race_conditions,
|
||||
% race_conditions,
|
||||
unknown
|
||||
]},
|
||||
{plt_apps, all_deps}
|
||||
|
@ -25,7 +25,7 @@
|
||||
{<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1},
|
||||
{<<"limiter_proto">>,
|
||||
{git,"https://github.com/valitydev/limiter-proto.git",
|
||||
{ref,"6723e862157a7f78194a64271899c2ef1581e177"}},
|
||||
{ref,"ac9705389211682263c0a983ae76f663d4857ec9"}},
|
||||
0},
|
||||
{<<"machinery">>,
|
||||
{git,"https://github.com/valitydev/machinery-erlang.git",
|
||||
|
Loading…
Reference in New Issue
Block a user