TD-443: Produce InteractionCompleted events @ payments / bindings (#23)

* Bump to valitydev/damsel@6655937
* Bump to valitydev/swag-payments@d71aebc
* Ensure backward compatibility
This commit is contained in:
Andrew Mayorov 2022-11-01 18:06:57 +03:00 committed by GitHub
parent 4d785873da
commit e5b4f7d540
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 255 additions and 27 deletions

View File

@ -462,10 +462,19 @@ decode_customer_binding_change(BindingID, {status_changed, StatusChange}) ->
}, },
decode_customer_binding_status(Status) decode_customer_binding_status(Status)
)}; )};
decode_customer_binding_change(BindingID, {interaction_requested, InteractionRequest}) -> decode_customer_binding_change(BindingID, {interaction_changed, InteractionChange}) ->
#payproc_CustomerBindingInteractionRequested{interaction = UserInteraction} = InteractionRequest, #payproc_CustomerBindingInteractionChanged{
interaction = UserInteraction,
status = Status
} = InteractionChange,
ChangeType =
case Status of
{requested, _} -> <<"CustomerBindingInteractionRequested">>;
{completed, _} -> <<"CustomerBindingInteractionCompleted">>;
undefined -> <<"CustomerBindingInteractionRequested">>
end,
{true, #{ {true, #{
<<"changeType">> => <<"CustomerBindingInteractionRequested">>, <<"changeType">> => ChangeType,
<<"customerBindingID">> => BindingID, <<"customerBindingID">> => BindingID,
<<"userInteraction">> => capi_handler_decoder_invoicing:decode_user_interaction(UserInteraction) <<"userInteraction">> => capi_handler_decoder_invoicing:decode_user_interaction(UserInteraction)
}}. }}.

View File

@ -389,13 +389,22 @@ decode_payment_change(
_InvoiceID, _InvoiceID,
PaymentID, PaymentID,
{invoice_payment_session_change, #payproc_InvoicePaymentSessionChange{ {invoice_payment_session_change, #payproc_InvoicePaymentSessionChange{
payload = {session_interaction_requested, InteractionRequested} payload =
{session_interaction_changed, #payproc_SessionInteractionChanged{
interaction = Interaction,
status = Status
}}
}}, }},
_Context _Context
) -> ) ->
#payproc_SessionInteractionRequested{interaction = Interaction} = InteractionRequested, ChangeType =
case Status of
{requested, _} -> <<"PaymentInteractionRequested">>;
{completed, _} -> <<"PaymentInteractionCompleted">>;
undefined -> <<"PaymentInteractionRequested">>
end,
#{ #{
<<"changeType">> => <<"PaymentInteractionRequested">>, <<"changeType">> => ChangeType,
<<"paymentID">> => PaymentID, <<"paymentID">> => PaymentID,
<<"userInteraction">> => capi_handler_decoder_invoicing:decode_user_interaction(Interaction) <<"userInteraction">> => capi_handler_decoder_invoicing:decode_user_interaction(Interaction)
}; };

View File

@ -6,6 +6,7 @@
-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -include_lib("damsel/include/dmsl_payproc_thrift.hrl").
-include_lib("damsel/include/dmsl_base_thrift.hrl"). -include_lib("damsel/include/dmsl_base_thrift.hrl").
-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("damsel/include/dmsl_user_interaction_thrift.hrl").
-include_lib("capi_dummy_data.hrl"). -include_lib("capi_dummy_data.hrl").
-export([all/0]). -export([all/0]).
@ -236,13 +237,51 @@ get_customer_events_ok_test(Config) ->
_ = capi_ct_helper:mock_services( _ = capi_ct_helper:mock_services(
[ [
{customer_management, fun {customer_management, fun
('Get', _) -> {ok, ?CUSTOMER}; ('Get', _) ->
('GetEvents', _) -> {ok, []} {ok, ?CUSTOMER};
('GetEvents', _) ->
{ok, [
?CUSTOMER_EVENT(1),
?CUSTOMER_EVENT(2),
?CUSTOMER_EVENT(3)
]}
end} end}
], ],
Config Config
), ),
{ok, _} = capi_client_customers:get_customer_events(?config(context, Config), ?STRING, 10). {ok, [Event1, _, _]} = capi_client_customers:get_customer_events(?config(context, Config), ?STRING, 10),
_ = ?assertMatch(
#{
<<"id">> := 1,
<<"createdAt">> := ?TIMESTAMP,
<<"changes">> := [
#{
<<"changeType">> := <<"CustomerBindingStarted">>,
<<"customerBinding">> := #{}
},
#{
<<"changeType">> := <<"CustomerBindingStatusChanged">>,
<<"customerBindingID">> := ?STRING,
<<"status">> := <<"failed">>
},
#{
<<"changeType">> := <<"CustomerBindingInteractionRequested">>,
<<"userInteraction">> := #{
<<"interactionType">> := <<"Redirect">>,
<<"request">> := #{}
}
},
#{
<<"changeType">> := <<"CustomerBindingInteractionCompleted">>,
<<"userInteraction">> := #{
<<"interactionType">> := <<"Redirect">>,
<<"request">> := #{}
}
}
]
},
Event1
).
-spec get_customer_payment_methods_ok_test(config()) -> _. -spec get_customer_payment_methods_ok_test(config()) -> _.
get_customer_payment_methods_ok_test(Config) -> get_customer_payment_methods_ok_test(Config) ->

View File

@ -950,6 +950,33 @@
} }
}). }).
-define(USER_INTERACTION,
{redirect,
{post_request, #user_interaction_BrowserPostRequest{
uri = ?URL,
form = #{
<<"redirect">> => ?URL
}
}}}
).
-define(USER_INTERACTION_REQUESTED, {requested, #user_interaction_Requested{}}).
-define(USER_INTERACTION_COMPLETED, {completed, #user_interaction_Completed{}}).
-define(INVOICE_PAYMENT_CHANGE(Payload),
{invoice_payment_change, #payproc_InvoicePaymentChange{
id = ?STRING,
payload = Payload
}}
).
-define(SESSION_CHANGE(Target, Payload),
{invoice_payment_session_change, #payproc_InvoicePaymentSessionChange{
target = Target,
payload = Payload
}}
).
-define(INVOICE_EVENT(ID), #payproc_Event{ -define(INVOICE_EVENT(ID), #payproc_Event{
id = ID, id = ID,
created_at = ?TIMESTAMP, created_at = ?TIMESTAMP,
@ -959,7 +986,33 @@
{invoice_status_changed, #payproc_InvoiceStatusChanged{status = ?INVOICE_STATUS(unpaid)}}, {invoice_status_changed, #payproc_InvoiceStatusChanged{status = ?INVOICE_STATUS(unpaid)}},
{invoice_status_changed, #payproc_InvoiceStatusChanged{status = ?INVOICE_STATUS(paid)}}, {invoice_status_changed, #payproc_InvoiceStatusChanged{status = ?INVOICE_STATUS(paid)}},
{invoice_status_changed, #payproc_InvoiceStatusChanged{status = ?INVOICE_STATUS(cancelled)}}, {invoice_status_changed, #payproc_InvoiceStatusChanged{status = ?INVOICE_STATUS(cancelled)}},
{invoice_status_changed, #payproc_InvoiceStatusChanged{status = ?INVOICE_STATUS(fulfilled)}} {invoice_status_changed, #payproc_InvoiceStatusChanged{status = ?INVOICE_STATUS(fulfilled)}},
?INVOICE_PAYMENT_CHANGE(
?SESSION_CHANGE(
{processed, #domain_InvoicePaymentProcessed{}},
{session_interaction_changed, #payproc_SessionInteractionChanged{
interaction = ?USER_INTERACTION
}}
)
),
?INVOICE_PAYMENT_CHANGE(
?SESSION_CHANGE(
{processed, #domain_InvoicePaymentProcessed{}},
{session_interaction_changed, #payproc_SessionInteractionChanged{
interaction = ?USER_INTERACTION,
status = ?USER_INTERACTION_REQUESTED
}}
)
),
?INVOICE_PAYMENT_CHANGE(
?SESSION_CHANGE(
{processed, #domain_InvoicePaymentProcessed{}},
{session_interaction_changed, #payproc_SessionInteractionChanged{
interaction = ?USER_INTERACTION,
status = ?USER_INTERACTION_COMPLETED
}}
)
)
]}, ]},
source = {invoice_id, ?STRING} source = {invoice_id, ?STRING}
}). }).
@ -969,14 +1022,12 @@
created_at = ?TIMESTAMP, created_at = ?TIMESTAMP,
payload = payload =
{invoice_changes, [ {invoice_changes, [
{invoice_payment_change, #payproc_InvoicePaymentChange{ ?INVOICE_PAYMENT_CHANGE(
id = <<"1">>, ?SESSION_CHANGE(
payload = {processed, #domain_InvoicePaymentProcessed{}},
{invoice_payment_session_change, #payproc_InvoicePaymentSessionChange{ {session_started, #payproc_SessionStarted{}}
target = {processed, #domain_InvoicePaymentProcessed{}}, )
payload = {session_started, #payproc_SessionStarted{}} )
}}
}}
]}, ]},
source = {invoice_id, ?STRING} source = {invoice_id, ?STRING}
}). }).
@ -1057,13 +1108,15 @@
id = ID, id = ID,
owner_id = ?STRING, owner_id = ?STRING,
shop_id = ?STRING, shop_id = ?STRING,
status = {ready, #payproc_CustomerReady{}}, status = ?CUSTOMER_READY,
created_at = ?TIMESTAMP, created_at = ?TIMESTAMP,
bindings = [?CUSTOMER_BINDING], bindings = [?CUSTOMER_BINDING],
contact_info = ?CONTACT_INFO, contact_info = ?CONTACT_INFO,
metadata = {obj, #{}} metadata = {obj, #{}}
}). }).
-define(CUSTOMER_READY, {ready, #payproc_CustomerReady{}}).
-define(CUSTOMER_BINDING, ?CUSTOMER_BINDING(?STRING, ?STRING)). -define(CUSTOMER_BINDING, ?CUSTOMER_BINDING(?STRING, ?STRING)).
-define(CUSTOMER_BINDING(ID, RECID), #payproc_CustomerBinding{ -define(CUSTOMER_BINDING(ID, RECID), #payproc_CustomerBinding{
@ -1073,6 +1126,58 @@
status = {succeeded, #payproc_CustomerBindingSucceeded{}} status = {succeeded, #payproc_CustomerBindingSucceeded{}}
}). }).
-define(CUSTOMER_EVENT(ID), #payproc_Event{
id = ID,
created_at = ?TIMESTAMP,
source = {customer_id, ?STRING},
payload =
{customer_changes, [
{customer_created, #payproc_CustomerCreated{
customer_id = ?STRING,
owner_id = ?STRING,
shop_id = ?STRING,
created_at = ?TIMESTAMP,
contact_info = ?CONTACT_INFO,
metadata = {obj, #{}}
}},
{customer_status_changed, #payproc_CustomerStatusChanged{
status = ?CUSTOMER_READY
}},
{customer_binding_changed, #payproc_CustomerBindingChanged{
id = ?STRING,
payload =
{started, #payproc_CustomerBindingStarted{
binding = ?CUSTOMER_BINDING
}}
}},
{customer_binding_changed, #payproc_CustomerBindingChanged{
id = ?STRING,
payload =
{status_changed, #payproc_CustomerBindingStatusChanged{
status =
{failed, #payproc_CustomerBindingFailed{
failure = {failure, #domain_Failure{code = <<"error_code">>}}
}}
}}
}},
{customer_binding_changed, #payproc_CustomerBindingChanged{
id = ?STRING,
payload =
{interaction_changed, #payproc_CustomerBindingInteractionChanged{
interaction = ?USER_INTERACTION
}}
}},
{customer_binding_changed, #payproc_CustomerBindingChanged{
id = ?STRING,
payload =
{interaction_changed, #payproc_CustomerBindingInteractionChanged{
interaction = ?USER_INTERACTION,
status = ?USER_INTERACTION_COMPLETED
}}
}}
]}
}).
-define(PUT_CARD_RESULT, #'PutCardResult'{ -define(PUT_CARD_RESULT, #'PutCardResult'{
bank_card = ?BANK_CARD bank_card = ?BANK_CARD
}). }).

View File

@ -7,6 +7,7 @@
-include_lib("damsel/include/dmsl_payproc_error_thrift.hrl"). -include_lib("damsel/include/dmsl_payproc_error_thrift.hrl").
-include_lib("damsel/include/dmsl_base_thrift.hrl"). -include_lib("damsel/include/dmsl_base_thrift.hrl").
-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("damsel/include/dmsl_user_interaction_thrift.hrl").
-include_lib("capi_dummy_data.hrl"). -include_lib("capi_dummy_data.hrl").
@ -190,10 +191,6 @@ get_invoice_ok_test(Config) ->
-spec get_invoice_events_ok_test(config()) -> _. -spec get_invoice_events_ok_test(config()) -> _.
get_invoice_events_ok_test(Config) -> get_invoice_events_ok_test(Config) ->
Inc = fun
(X) when is_integer(X) -> X + 1;
(_) -> 1
end,
_ = capi_ct_helper:mock_services( _ = capi_ct_helper:mock_services(
[ [
{invoicing, fun {invoicing, fun
@ -209,7 +206,7 @@ get_invoice_events_ok_test(Config) ->
?INVOICE_EVENT_PRIVATE(6), ?INVOICE_EVENT_PRIVATE(6),
?INVOICE_EVENT(7) ?INVOICE_EVENT(7)
], ],
Inc(ID), genlib:define(ID, 0) + 1,
N N
)}; )};
('Get', _) -> ('Get', _) ->
@ -225,6 +222,75 @@ get_invoice_events_ok_test(Config) ->
?STRING, ?STRING,
Config Config
), ),
{ok, [Event]} = capi_client_invoices:get_invoice_events(?config(context, Config), ?STRING, 1),
_ = ?assertMatch(
#{
<<"id">> := 1,
<<"createdAt">> := ?TIMESTAMP,
<<"changes">> := [
#{
<<"changeType">> := <<"InvoiceCreated">>,
<<"invoice">> := #{
<<"id">> := ?STRING,
<<"status">> := <<"unpaid">>
}
},
#{
<<"changeType">> := <<"InvoiceStatusChanged">>,
<<"status">> := <<"unpaid">>
},
#{
<<"changeType">> := <<"InvoiceStatusChanged">>,
<<"status">> := <<"paid">>
},
#{
<<"changeType">> := <<"InvoiceStatusChanged">>,
<<"status">> := <<"cancelled">>
},
#{
<<"changeType">> := <<"InvoiceStatusChanged">>,
<<"status">> := <<"fulfilled">>
},
#{
<<"changeType">> := <<"PaymentInteractionRequested">>,
<<"paymentID">> := ?STRING,
<<"userInteraction">> := #{
<<"interactionType">> := <<"Redirect">>,
<<"request">> := #{
<<"requestType">> := <<"BrowserPostRequest">>,
<<"uriTemplate">> := ?URL,
<<"form">> := [#{<<"key">> := _, <<"template">> := _}]
}
}
},
#{
<<"changeType">> := <<"PaymentInteractionRequested">>,
<<"paymentID">> := ?STRING,
<<"userInteraction">> := #{
<<"interactionType">> := <<"Redirect">>,
<<"request">> := #{
<<"requestType">> := <<"BrowserPostRequest">>,
<<"uriTemplate">> := ?URL,
<<"form">> := [_]
}
}
},
#{
<<"changeType">> := <<"PaymentInteractionCompleted">>,
<<"paymentID">> := ?STRING,
<<"userInteraction">> := #{
<<"interactionType">> := <<"Redirect">>,
<<"request">> := #{
<<"requestType">> := <<"BrowserPostRequest">>,
<<"uriTemplate">> := ?URL,
<<"form">> := [_]
}
}
}
]
},
Event
),
{ok, [#{<<"id">> := 1}, #{<<"id">> := 2}, #{<<"id">> := 4}]} = {ok, [#{<<"id">> := 1}, #{<<"id">> := 2}, #{<<"id">> := 4}]} =
capi_client_invoices:get_invoice_events(?config(context, Config), ?STRING, 3), capi_client_invoices:get_invoice_events(?config(context, Config), ?STRING, 3),
{ok, [#{<<"id">> := 4}, #{<<"id">> := 7}]} = {ok, [#{<<"id">> := 4}, #{<<"id">> := 7}]} =

View File

@ -37,7 +37,7 @@
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},1},
{<<"damsel">>, {<<"damsel">>,
{git,"https://github.com/valitydev/damsel.git", {git,"https://github.com/valitydev/damsel.git",
{ref,"60474970af1d5e58752f4e5680e67c65ff64dda9"}}, {ref,"6655937cfd504d14bf83c40f5d09315dbffbdcfc"}},
0}, 0},
{<<"dmt_client">>, {<<"dmt_client">>,
{git,"https://github.com/valitydev/dmt_client.git", {git,"https://github.com/valitydev/dmt_client.git",
@ -119,11 +119,11 @@
{<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2},
{<<"swag_client">>, {<<"swag_client">>,
{git,"https://github.com/valitydev/swag-payments", {git,"https://github.com/valitydev/swag-payments",
{ref,"279d481e4583f8650b0162470fae68b8f30c0cdc"}}, {ref,"a6529bb729abfff1fe265dde5971866bed0669b4"}},
0}, 0},
{<<"swag_server">>, {<<"swag_server">>,
{git,"https://github.com/valitydev/swag-payments", {git,"https://github.com/valitydev/swag-payments",
{ref,"06c30485b102036290a1c05d07e517ea2a0a85de"}}, {ref,"aaa932d06ccafb7c25f80f433557836e80d6d2ac"}},
0}, 0},
{<<"thrift">>, {<<"thrift">>,
{git,"https://github.com/valitydev/thrift_erlang.git", {git,"https://github.com/valitydev/thrift_erlang.git",