mirror of
https://github.com/valitydev/hellgate.git
synced 2024-11-06 02:45:20 +00:00
IMP-331: Implements provider host's session change handler (#145)
* IMP-331: Implements provider host's session change handler * Implements session' failure change * Adds session change testcase * Fixes helper' spec * Refactors testcase w/ more asserts and fixes session finalizing on status change * Bumps damsel
This commit is contained in:
parent
24f9f6bd63
commit
fa7cd47a79
@ -24,6 +24,7 @@
|
|||||||
-define(NS, <<"invoice">>).
|
-define(NS, <<"invoice">>).
|
||||||
|
|
||||||
-export([process_callback/2]).
|
-export([process_callback/2]).
|
||||||
|
-export([process_session_change_by_tag/2]).
|
||||||
|
|
||||||
-export_type([activity/0]).
|
-export_type([activity/0]).
|
||||||
-export_type([invoice/0]).
|
-export_type([invoice/0]).
|
||||||
@ -211,14 +212,14 @@ get_payment_state(PaymentSession) ->
|
|||||||
%%
|
%%
|
||||||
|
|
||||||
-type tag() :: dmsl_base_thrift:'Tag'().
|
-type tag() :: dmsl_base_thrift:'Tag'().
|
||||||
|
-type session_change() :: hg_session:change().
|
||||||
-type callback() :: {provider, dmsl_proxy_provider_thrift:'Callback'()}.
|
-type callback() :: {provider, dmsl_proxy_provider_thrift:'Callback'()}.
|
||||||
-type callback_response() :: dmsl_proxy_provider_thrift:'CallbackResponse'().
|
-type callback_response() :: dmsl_proxy_provider_thrift:'CallbackResponse'().
|
||||||
|
|
||||||
-spec process_callback(tag(), callback()) ->
|
-spec process_callback(tag(), callback()) ->
|
||||||
{ok, callback_response()} | {error, invalid_callback | notfound | failed} | no_return().
|
{ok, callback_response()} | {error, invalid_callback | notfound | failed} | no_return().
|
||||||
process_callback(Tag, Callback) ->
|
process_callback(Tag, Callback) ->
|
||||||
case hg_machine_tag:get_binding(namespace(), Tag) of
|
process_with_tag(Tag, fun(MachineID) ->
|
||||||
{ok, _EntityID, MachineID} ->
|
|
||||||
case hg_machine:call(?NS, MachineID, {callback, Tag, Callback}) of
|
case hg_machine:call(?NS, MachineID, {callback, Tag, Callback}) of
|
||||||
{ok, _} = Ok ->
|
{ok, _} = Ok ->
|
||||||
Ok;
|
Ok;
|
||||||
@ -226,7 +227,27 @@ process_callback(Tag, Callback) ->
|
|||||||
{error, invalid_callback};
|
{error, invalid_callback};
|
||||||
{error, _} = Error ->
|
{error, _} = Error ->
|
||||||
Error
|
Error
|
||||||
end;
|
end
|
||||||
|
end).
|
||||||
|
|
||||||
|
-spec process_session_change_by_tag(tag(), session_change()) ->
|
||||||
|
ok | {error, notfound | failed} | no_return().
|
||||||
|
process_session_change_by_tag(Tag, SessionChange) ->
|
||||||
|
process_with_tag(Tag, fun(MachineID) ->
|
||||||
|
case hg_machine:call(?NS, MachineID, {session_change, Tag, SessionChange}) of
|
||||||
|
ok ->
|
||||||
|
ok;
|
||||||
|
{exception, invalid_callback} ->
|
||||||
|
{error, notfound};
|
||||||
|
{error, _} = Error ->
|
||||||
|
Error
|
||||||
|
end
|
||||||
|
end).
|
||||||
|
|
||||||
|
process_with_tag(Tag, F) ->
|
||||||
|
case hg_machine_tag:get_binding(namespace(), Tag) of
|
||||||
|
{ok, _EntityID, MachineID} ->
|
||||||
|
F(MachineID);
|
||||||
{error, _} = Error ->
|
{error, _} = Error ->
|
||||||
Error
|
Error
|
||||||
end.
|
end.
|
||||||
@ -339,7 +360,8 @@ handle_expiration(St) ->
|
|||||||
|
|
||||||
-type thrift_call() :: hg_machine:thrift_call().
|
-type thrift_call() :: hg_machine:thrift_call().
|
||||||
-type callback_call() :: {callback, tag(), callback()}.
|
-type callback_call() :: {callback, tag(), callback()}.
|
||||||
-type call() :: thrift_call() | callback_call().
|
-type session_change_call() :: {session_change, tag(), session_change()}.
|
||||||
|
-type call() :: thrift_call() | callback_call() | session_change_call().
|
||||||
-type call_result() :: #{
|
-type call_result() :: #{
|
||||||
changes => [invoice_change()],
|
changes => [invoice_change()],
|
||||||
action => hg_machine_action:t(),
|
action => hg_machine_action:t(),
|
||||||
@ -455,14 +477,20 @@ handle_call({{'Invoicing', 'CreatePaymentAdjustment'}, {_InvoiceID, PaymentID, P
|
|||||||
hg_invoice_payment:create_adjustment(Timestamp, Params, PaymentSession, Opts),
|
hg_invoice_payment:create_adjustment(Timestamp, Params, PaymentSession, Opts),
|
||||||
St
|
St
|
||||||
);
|
);
|
||||||
handle_call({callback, Tag, Callback}, St) ->
|
handle_call({callback, _Tag, _Callback} = Call, St) ->
|
||||||
dispatch_callback(Tag, Callback, St).
|
dispatch_to_session(Call, St);
|
||||||
|
handle_call({session_change, _Tag, _SessionChange} = Call, St) ->
|
||||||
|
dispatch_to_session(Call, St).
|
||||||
|
|
||||||
-spec dispatch_callback(tag(), callback(), st()) -> call_result().
|
-spec dispatch_to_session({callback, tag(), callback()} | {session_change, tag(), session_change()}, st()) ->
|
||||||
dispatch_callback(Tag, {provider, Payload}, St = #st{activity = {payment, PaymentID}}) ->
|
call_result().
|
||||||
|
dispatch_to_session({callback, Tag, {provider, Payload}}, St = #st{activity = {payment, PaymentID}}) ->
|
||||||
PaymentSession = get_payment_session(PaymentID, St),
|
PaymentSession = get_payment_session(PaymentID, St),
|
||||||
process_payment_call({callback, Tag, Payload}, PaymentID, PaymentSession, St);
|
process_payment_call({callback, Tag, Payload}, PaymentID, PaymentSession, St);
|
||||||
dispatch_callback(_Tag, _Callback, _St) ->
|
dispatch_to_session({session_change, _Tag, _SessionChange} = Call, St = #st{activity = {payment, PaymentID}}) ->
|
||||||
|
PaymentSession = get_payment_session(PaymentID, St),
|
||||||
|
process_payment_call(Call, PaymentID, PaymentSession, St);
|
||||||
|
dispatch_to_session(_Call, _St) ->
|
||||||
throw(invalid_callback).
|
throw(invalid_callback).
|
||||||
|
|
||||||
assert_no_pending_payment(#st{activity = {payment, PaymentID}}) ->
|
assert_no_pending_payment(#st{activity = {payment, PaymentID}}) ->
|
||||||
|
@ -200,6 +200,7 @@
|
|||||||
-type trx_info() :: dmsl_domain_thrift:'TransactionInfo'().
|
-type trx_info() :: dmsl_domain_thrift:'TransactionInfo'().
|
||||||
-type tag() :: dmsl_proxy_provider_thrift:'CallbackTag'().
|
-type tag() :: dmsl_proxy_provider_thrift:'CallbackTag'().
|
||||||
-type callback() :: dmsl_proxy_provider_thrift:'Callback'().
|
-type callback() :: dmsl_proxy_provider_thrift:'Callback'().
|
||||||
|
-type session_change() :: hg_session:change().
|
||||||
-type callback_response() :: dmsl_proxy_provider_thrift:'CallbackResponse'().
|
-type callback_response() :: dmsl_proxy_provider_thrift:'CallbackResponse'().
|
||||||
-type make_recurrent() :: true | false.
|
-type make_recurrent() :: true | false.
|
||||||
-type retry_strategy() :: hg_retry:strategy().
|
-type retry_strategy() :: hg_retry:strategy().
|
||||||
@ -1924,12 +1925,20 @@ repair_process_timeout(Activity, Action, St = #st{repair_scenario = Scenario}) -
|
|||||||
process_timeout(Activity, Action, St)
|
process_timeout(Activity, Action, St)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec process_call({callback, tag(), callback()}, st(), opts()) -> {callback_response(), machine_result()}.
|
-spec process_call
|
||||||
|
({callback, tag(), callback()}, st(), opts()) -> {callback_response(), machine_result()};
|
||||||
|
({session_change, tag(), session_change()}, st(), opts()) -> {ok, machine_result()}.
|
||||||
process_call({callback, Tag, Payload}, St, Options) ->
|
process_call({callback, Tag, Payload}, St, Options) ->
|
||||||
scoper:scope(
|
scoper:scope(
|
||||||
payment,
|
payment,
|
||||||
get_st_meta(St),
|
get_st_meta(St),
|
||||||
fun() -> process_callback(Tag, Payload, St#st{opts = Options}) end
|
fun() -> process_callback(Tag, Payload, St#st{opts = Options}) end
|
||||||
|
);
|
||||||
|
process_call({session_change, Tag, SessionChange}, St, Options) ->
|
||||||
|
scoper:scope(
|
||||||
|
payment,
|
||||||
|
get_st_meta(St),
|
||||||
|
fun() -> process_session_change(Tag, SessionChange, St#st{opts = Options}) end
|
||||||
).
|
).
|
||||||
|
|
||||||
-spec process_callback(tag(), callback(), st()) -> {callback_response(), machine_result()}.
|
-spec process_callback(tag(), callback(), st()) -> {callback_response(), machine_result()}.
|
||||||
@ -1937,6 +1946,11 @@ process_callback(Tag, Payload, St) ->
|
|||||||
Session = get_activity_session(St),
|
Session = get_activity_session(St),
|
||||||
process_callback(Tag, Payload, Session, St).
|
process_callback(Tag, Payload, Session, St).
|
||||||
|
|
||||||
|
-spec process_session_change(tag(), session_change(), st()) -> {ok, machine_result()}.
|
||||||
|
process_session_change(Tag, SessionChange, St) ->
|
||||||
|
Session = get_activity_session(St),
|
||||||
|
process_session_change(Tag, SessionChange, Session, St).
|
||||||
|
|
||||||
process_callback(Tag, Payload, Session, St) when Session /= undefined ->
|
process_callback(Tag, Payload, Session, St) when Session /= undefined ->
|
||||||
case {hg_session:status(Session), hg_session:tags(Session)} of
|
case {hg_session:status(Session), hg_session:tags(Session)} of
|
||||||
{suspended, [Tag | _]} ->
|
{suspended, [Tag | _]} ->
|
||||||
@ -1947,6 +1961,19 @@ process_callback(Tag, Payload, Session, St) when Session /= undefined ->
|
|||||||
process_callback(_Tag, _Payload, undefined, _St) ->
|
process_callback(_Tag, _Payload, undefined, _St) ->
|
||||||
throw(invalid_callback).
|
throw(invalid_callback).
|
||||||
|
|
||||||
|
process_session_change(Tag, SessionChange, Session0, St) when Session0 /= undefined ->
|
||||||
|
%% NOTE Change allowed only for suspended session. Not suspended
|
||||||
|
%% session does not have registered callback with tag.
|
||||||
|
case {hg_session:status(Session0), hg_session:tags(Session0)} of
|
||||||
|
{suspended, [Tag | _]} ->
|
||||||
|
{Result, Session1} = hg_session:process_change(SessionChange, Session0),
|
||||||
|
{ok, finish_session_processing(get_activity(St), Result, Session1, St)};
|
||||||
|
_ ->
|
||||||
|
throw(invalid_callback)
|
||||||
|
end;
|
||||||
|
process_session_change(_Tag, _Payload, undefined, _St) ->
|
||||||
|
throw(invalid_callback).
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
-spec process_shop_limit_initialization(action(), st()) -> machine_result().
|
-spec process_shop_limit_initialization(action(), st()) -> machine_result().
|
||||||
|
@ -49,11 +49,16 @@ handle_function('GetPayment', {Tag}, _) ->
|
|||||||
end;
|
end;
|
||||||
{error, notfound} ->
|
{error, notfound} ->
|
||||||
hg_woody_service_wrapper:raise(#proxy_provider_PaymentNotFound{})
|
hg_woody_service_wrapper:raise(#proxy_provider_PaymentNotFound{})
|
||||||
end.
|
end;
|
||||||
|
handle_function('ChangePaymentSession', {Tag, SessionChange}, _) ->
|
||||||
|
handle_callback_result(hg_invoice:process_session_change_by_tag(Tag, SessionChange)).
|
||||||
|
|
||||||
-spec handle_callback_result
|
-spec handle_callback_result
|
||||||
|
(ok) -> ok;
|
||||||
({ok, callback_response()}) -> callback_response();
|
({ok, callback_response()}) -> callback_response();
|
||||||
({error, any()}) -> no_return().
|
({error, any()}) -> no_return().
|
||||||
|
handle_callback_result(ok) ->
|
||||||
|
ok;
|
||||||
handle_callback_result({ok, Response}) ->
|
handle_callback_result({ok, Response}) ->
|
||||||
Response;
|
Response;
|
||||||
handle_callback_result({error, invalid_callback}) ->
|
handle_callback_result({error, invalid_callback}) ->
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
-type repair_scenario() :: {result, proxy_result()}.
|
-type repair_scenario() :: {result, proxy_result()}.
|
||||||
|
|
||||||
-export_type([t/0]).
|
-export_type([t/0]).
|
||||||
|
-export_type([change/0]).
|
||||||
-export_type([event_context/0]).
|
-export_type([event_context/0]).
|
||||||
-export_type([process_result/0]).
|
-export_type([process_result/0]).
|
||||||
|
|
||||||
@ -73,6 +74,7 @@
|
|||||||
|
|
||||||
-export([process/1]).
|
-export([process/1]).
|
||||||
-export([process_callback/2]).
|
-export([process_callback/2]).
|
||||||
|
-export([process_change/2]).
|
||||||
|
|
||||||
%% Internal types
|
%% Internal types
|
||||||
|
|
||||||
@ -88,6 +90,7 @@
|
|||||||
-type interaction() :: dmsl_user_interaction_thrift:'UserInteraction'().
|
-type interaction() :: dmsl_user_interaction_thrift:'UserInteraction'().
|
||||||
-type payment_info() :: dmsl_proxy_provider_thrift:'PaymentInfo'().
|
-type payment_info() :: dmsl_proxy_provider_thrift:'PaymentInfo'().
|
||||||
-type timings() :: hg_timings:t().
|
-type timings() :: hg_timings:t().
|
||||||
|
-type change() :: dmsl_proxy_provider_thrift:'PaymentSessionChange'().
|
||||||
|
|
||||||
-type wrapped_event() :: dmsl_payproc_thrift:'InvoicePaymentChangePayload'().
|
-type wrapped_event() :: dmsl_payproc_thrift:'InvoicePaymentChangePayload'().
|
||||||
-type wrapped_events() :: [wrapped_event()].
|
-type wrapped_events() :: [wrapped_event()].
|
||||||
@ -201,6 +204,18 @@ process_callback(Payload, Session) ->
|
|||||||
{Response, Result} = handle_callback_result(CallbackResult, Session),
|
{Response, Result} = handle_callback_result(CallbackResult, Session),
|
||||||
{Response, apply_result(Result, Session)}.
|
{Response, apply_result(Result, Session)}.
|
||||||
|
|
||||||
|
-spec process_change(change(), t()) -> process_result().
|
||||||
|
process_change(#proxy_provider_PaymentSessionChange{status = {failure, Failure}}, Session) ->
|
||||||
|
SessionEvents = [
|
||||||
|
?session_activated(),
|
||||||
|
?session_finished(?session_failed({failure, Failure}))
|
||||||
|
],
|
||||||
|
Result = {SessionEvents, hg_machine_action:instant()},
|
||||||
|
apply_result(Result, Session);
|
||||||
|
process_change(_Change, _Session) ->
|
||||||
|
%% NOTE For now there is no other applicable change defined in protocol.
|
||||||
|
throw(unknown_change).
|
||||||
|
|
||||||
-spec deduce_activity(t()) -> activity().
|
-spec deduce_activity(t()) -> activity().
|
||||||
deduce_activity(#{repair_scenario := Scenario}) when Scenario =/= undefined ->
|
deduce_activity(#{repair_scenario := Scenario}) when Scenario =/= undefined ->
|
||||||
repair;
|
repair;
|
||||||
|
@ -431,7 +431,6 @@ create_shop_(
|
|||||||
ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(Currency)},
|
ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(Currency)},
|
||||||
|
|
||||||
ContractParams = make_contract_params(TemplateRef, PaymentInstRef),
|
ContractParams = make_contract_params(TemplateRef, PaymentInstRef),
|
||||||
PayoutToolParams = make_payout_tool_params(),
|
|
||||||
|
|
||||||
TurnoverLimits1 = genlib:define(TurnoverLimits0, ordsets:new()),
|
TurnoverLimits1 = genlib:define(TurnoverLimits0, ordsets:new()),
|
||||||
|
|
||||||
@ -440,14 +439,6 @@ create_shop_(
|
|||||||
id = ContractID,
|
id = ContractID,
|
||||||
modification = {creation, ContractParams}
|
modification = {creation, ContractParams}
|
||||||
}},
|
}},
|
||||||
{contract_modification, #payproc_ContractModificationUnit{
|
|
||||||
id = ContractID,
|
|
||||||
modification =
|
|
||||||
{payout_tool_modification, #payproc_PayoutToolModificationUnit{
|
|
||||||
payout_tool_id = PayoutToolID,
|
|
||||||
modification = {creation, PayoutToolParams}
|
|
||||||
}}
|
|
||||||
}},
|
|
||||||
?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})
|
?shop_modification(ShopID, {turnover_limits_modification, TurnoverLimits1})
|
||||||
@ -559,19 +550,6 @@ make_contractor() ->
|
|||||||
russian_bank_account = BankAccount
|
russian_bank_account = BankAccount
|
||||||
}}}.
|
}}}.
|
||||||
|
|
||||||
-spec make_payout_tool_params() -> dmsl_payproc_thrift:'PayoutToolParams'().
|
|
||||||
make_payout_tool_params() ->
|
|
||||||
#payproc_PayoutToolParams{
|
|
||||||
currency = ?cur(<<"RUB">>),
|
|
||||||
tool_info =
|
|
||||||
{russian_bank_account, #domain_RussianBankAccount{
|
|
||||||
account = <<"4276300010908312893">>,
|
|
||||||
bank_name = <<"SomeBank">>,
|
|
||||||
bank_post_account = <<"123129876">>,
|
|
||||||
bank_bik = <<"66642666">>
|
|
||||||
}}
|
|
||||||
}.
|
|
||||||
|
|
||||||
-spec make_invoice_params(party_id(), shop_id(), binary(), cash()) -> invoice_params().
|
-spec make_invoice_params(party_id(), shop_id(), binary(), cash()) -> invoice_params().
|
||||||
make_invoice_params(PartyID, ShopID, Product, Cost) ->
|
make_invoice_params(PartyID, ShopID, Product, Cost) ->
|
||||||
make_invoice_params(PartyID, ShopID, Product, make_due_date(), Cost).
|
make_invoice_params(PartyID, ShopID, Product, make_due_date(), Cost).
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
-export([get_callback_url/0]).
|
-export([get_callback_url/0]).
|
||||||
-export([construct_silent_callback/1]).
|
-export([construct_silent_callback/1]).
|
||||||
|
|
||||||
|
-export([change_payment_session/2]).
|
||||||
|
|
||||||
-export([make_payment_tool/2]).
|
-export([make_payment_tool/2]).
|
||||||
-export([mk_trx/1]).
|
-export([mk_trx/1]).
|
||||||
|
|
||||||
@ -733,6 +735,9 @@ get_payment_tool_scenario(
|
|||||||
| {preauth_3ds, integer()}
|
| {preauth_3ds, integer()}
|
||||||
| {preauth_3ds_sleep, integer()}.
|
| {preauth_3ds_sleep, integer()}.
|
||||||
|
|
||||||
|
-type tag() :: dmsl_proxy_provider_thrift:'CallbackTag'().
|
||||||
|
-type session_change() :: dmsl_proxy_provider_thrift:'PaymentSessionChange'().
|
||||||
|
|
||||||
-spec make_payment_tool(payment_tool_code(), payment_system()) -> payment_tool().
|
-spec make_payment_tool(payment_tool_code(), payment_system()) -> payment_tool().
|
||||||
make_payment_tool(Code, PSys) when
|
make_payment_tool(Code, PSys) when
|
||||||
Code =:= no_preauth orelse
|
Code =:= no_preauth orelse
|
||||||
@ -864,6 +869,15 @@ terminate(_Reason, _Req, _State) ->
|
|||||||
get_callback_url() ->
|
get_callback_url() ->
|
||||||
genlib:to_binary("http://127.0.0.1:" ++ integer_to_list(?COWBOY_PORT)).
|
genlib:to_binary("http://127.0.0.1:" ++ integer_to_list(?COWBOY_PORT)).
|
||||||
|
|
||||||
|
-spec change_payment_session(tag(), session_change()) -> ok | {exception, _Reason} | {error, _Reason}.
|
||||||
|
change_payment_session(Tag, Change) ->
|
||||||
|
Client = hg_client_api:new(hg_ct_helper:get_hellgate_url()),
|
||||||
|
case hg_client_api:call(proxy_host_provider, 'ChangePaymentSession', [Tag, Change], Client) of
|
||||||
|
{{ok, ok}, _} -> ok;
|
||||||
|
{{exception, _Reason} = Exception, _} -> Exception;
|
||||||
|
{{error, _Reason} = Error, _} -> Error
|
||||||
|
end.
|
||||||
|
|
||||||
handle_user_interaction_response(<<"POST">>, Req) ->
|
handle_user_interaction_response(<<"POST">>, Req) ->
|
||||||
{ok, Body, Req2} = cowboy_req:read_body(Req),
|
{ok, Body, Req2} = cowboy_req:read_body(Req),
|
||||||
Form = maps:from_list(cow_qs:parse_qs(Body)),
|
Form = maps:from_list(cow_qs:parse_qs(Body)),
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
-include("hg_ct_domain.hrl").
|
-include("hg_ct_domain.hrl").
|
||||||
-include("hg_ct_invoice.hrl").
|
-include("hg_ct_invoice.hrl").
|
||||||
-include_lib("damsel/include/dmsl_repair_thrift.hrl").
|
-include_lib("damsel/include/dmsl_repair_thrift.hrl").
|
||||||
|
-include_lib("damsel/include/dmsl_proxy_provider_thrift.hrl").
|
||||||
-include_lib("hellgate/include/allocation.hrl").
|
-include_lib("hellgate/include/allocation.hrl").
|
||||||
-include_lib("fault_detector_proto/include/fd_proto_fault_detector_thrift.hrl").
|
-include_lib("fault_detector_proto/include/fd_proto_fault_detector_thrift.hrl").
|
||||||
|
|
||||||
@ -69,6 +70,7 @@
|
|||||||
-export([payment_success_with_decreased_cost/1]).
|
-export([payment_success_with_decreased_cost/1]).
|
||||||
-export([refund_payment_with_decreased_cost/1]).
|
-export([refund_payment_with_decreased_cost/1]).
|
||||||
-export([payment_fail_after_silent_callback/1]).
|
-export([payment_fail_after_silent_callback/1]).
|
||||||
|
-export([payment_session_changed_to_fail/1]).
|
||||||
-export([invoice_success_on_third_payment/1]).
|
-export([invoice_success_on_third_payment/1]).
|
||||||
-export([party_revision_check/1]).
|
-export([party_revision_check/1]).
|
||||||
-export([payment_customer_risk_score_check/1]).
|
-export([payment_customer_risk_score_check/1]).
|
||||||
@ -331,6 +333,8 @@ groups() ->
|
|||||||
payment_success_with_decreased_cost,
|
payment_success_with_decreased_cost,
|
||||||
refund_payment_with_decreased_cost,
|
refund_payment_with_decreased_cost,
|
||||||
payment_fail_after_silent_callback,
|
payment_fail_after_silent_callback,
|
||||||
|
payment_session_changed_to_fail,
|
||||||
|
|
||||||
payment_temporary_unavailability_retry_success,
|
payment_temporary_unavailability_retry_success,
|
||||||
payment_temporary_unavailability_too_many_retries,
|
payment_temporary_unavailability_too_many_retries,
|
||||||
invoice_success_on_third_payment,
|
invoice_success_on_third_payment,
|
||||||
@ -2337,6 +2341,39 @@ payment_fail_after_silent_callback(C) ->
|
|||||||
_ = assert_success_post_request({URL, hg_dummy_provider:construct_silent_callback(Form)}),
|
_ = assert_success_post_request({URL, hg_dummy_provider:construct_silent_callback(Form)}),
|
||||||
PaymentID = await_payment_process_timeout(InvoiceID, PaymentID, Client).
|
PaymentID = await_payment_process_timeout(InvoiceID, PaymentID, Client).
|
||||||
|
|
||||||
|
-spec payment_session_changed_to_fail(config()) -> _ | no_return().
|
||||||
|
payment_session_changed_to_fail(C) ->
|
||||||
|
Client = cfg(client, C),
|
||||||
|
InvoiceID = start_invoice(<<"rubberdick">>, make_due_date(20), 42000, C),
|
||||||
|
%% Payment w/ preauth for suspend w/ user interaction occurrence.
|
||||||
|
PaymentID = start_payment(InvoiceID, make_tds_payment_params(instant, ?pmt_sys(<<"visa-ref">>)), Client),
|
||||||
|
UserInteraction = await_payment_process_interaction(InvoiceID, PaymentID, Client),
|
||||||
|
|
||||||
|
Failure = payproc_errors:construct(
|
||||||
|
'PaymentFailure',
|
||||||
|
{authorization_failed, {operation_blocked, ?err_gen_failure()}},
|
||||||
|
genlib:unique()
|
||||||
|
),
|
||||||
|
Change = #proxy_provider_PaymentSessionChange{status = {failure, Failure}},
|
||||||
|
|
||||||
|
%% Unknown session callback tag
|
||||||
|
?assertMatch(
|
||||||
|
{exception, #base_InvalidRequest{errors = [<<"Not found">>]}},
|
||||||
|
hg_dummy_provider:change_payment_session(<<"unknown tag">>, Change)
|
||||||
|
),
|
||||||
|
|
||||||
|
%% Since we expect UI to be a redirect, then parse tag value from
|
||||||
|
%% from request parameter.
|
||||||
|
Tag = user_interaction_callback_tag(UserInteraction),
|
||||||
|
ok = hg_dummy_provider:change_payment_session(Tag, Change),
|
||||||
|
{failed, PaymentID, {failure, Failure}} = await_payment_process_failure(InvoiceID, PaymentID, Client),
|
||||||
|
|
||||||
|
%% Bad session callback tag must not be found again
|
||||||
|
?assertMatch(
|
||||||
|
{exception, #base_InvalidRequest{errors = [<<"Not found">>]}},
|
||||||
|
hg_dummy_provider:change_payment_session(Tag, Change)
|
||||||
|
).
|
||||||
|
|
||||||
-spec payments_w_bank_card_issuer_conditions(config()) -> test_return().
|
-spec payments_w_bank_card_issuer_conditions(config()) -> test_return().
|
||||||
payments_w_bank_card_issuer_conditions(C) ->
|
payments_w_bank_card_issuer_conditions(C) ->
|
||||||
PmtSys = ?pmt_sys(<<"visa-ref">>),
|
PmtSys = ?pmt_sys(<<"visa-ref">>),
|
||||||
@ -8308,6 +8345,13 @@ assert_success_post_request(Req) ->
|
|||||||
assert_invalid_post_request(Req) ->
|
assert_invalid_post_request(Req) ->
|
||||||
{ok, 400, _RespHeaders, _RespBody} = post_request(Req).
|
{ok, 400, _RespHeaders, _RespBody} = post_request(Req).
|
||||||
|
|
||||||
|
user_interaction_callback_tag(
|
||||||
|
{redirect, {post_request, #user_interaction_BrowserPostRequest{form = #{<<"tag">> := Tag}}}}
|
||||||
|
) ->
|
||||||
|
Tag;
|
||||||
|
user_interaction_callback_tag(_UserInteraction) ->
|
||||||
|
undefined.
|
||||||
|
|
||||||
post_request({URL, Form}) ->
|
post_request({URL, Form}) ->
|
||||||
Method = post,
|
Method = post,
|
||||||
Headers = [],
|
Headers = [],
|
||||||
|
@ -27,7 +27,7 @@ services:
|
|||||||
command: /sbin/init
|
command: /sbin/init
|
||||||
|
|
||||||
dominant:
|
dominant:
|
||||||
image: ghcr.io/valitydev/dominant:sha-2150eea
|
image: ghcr.io/valitydev/dominant:sha-fae8726
|
||||||
command: /opt/dominant/bin/dominant foreground
|
command: /opt/dominant/bin/dominant foreground
|
||||||
depends_on:
|
depends_on:
|
||||||
machinegun:
|
machinegun:
|
||||||
@ -97,7 +97,7 @@ services:
|
|||||||
disable: true
|
disable: true
|
||||||
|
|
||||||
party-management:
|
party-management:
|
||||||
image: ghcr.io/valitydev/party-management:sha-9af7d71
|
image: ghcr.io/valitydev/party-management:sha-b78d0f5
|
||||||
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,"9d4aa513fcbc1cc7ba5eedd9f96d8bc8590a6ac2"}},
|
{ref,"b149379e9f706dafcace7d36b124145d71fb1bc6"}},
|
||||||
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