ED-87: Add tokenization method, token provider for none tokenizate bank card (#131)

This commit is contained in:
Boris 2021-10-05 16:35:33 +03:00 committed by GitHub
parent 597a987f45
commit ec5d3addbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 28 deletions

View File

@ -12,8 +12,7 @@
UserID :: binary() | undefined,
RequestContext :: swag_server:request_context(),
WoodyContext :: woody_context:ctx()
) ->
capi_bouncer_context:fragments().
) -> capi_bouncer_context:fragments().
gather_context_fragments(TokenContextFragment, UserID, ReqCtx, WoodyCtx) ->
{Base, External0} = capi_bouncer_context:new(),
External1 = External0#{<<"token-keeper">> => {encoded_fragment, TokenContextFragment}},

View File

@ -342,7 +342,9 @@ unwrap_merchant_id(Provider, EncodedID) ->
case binary:split(EncodedID, <<$:>>, [global]) of
[RealmMode, PartyID, ShopID] ->
#{
realm => RealmMode, party => PartyID, shop => ShopID
realm => RealmMode,
party => PartyID,
shop => ShopID
};
_ ->
_ = logger:warning("invalid merchant id: ~p ~p", [Provider, EncodedID]),
@ -529,16 +531,18 @@ process_tokenized_card_data_result(
valid_until = ValidUntil
}
) ->
TokenProvider = get_payment_token_provider(PaymentDetails, PaymentData),
TokenProvider = get_payment_token_provider(PaymentDetails),
TokenizationMethod = get_tokenization_method(PaymentData),
{NS, ProviderMetadata} = extract_payment_tool_provider_metadata(PaymentDetails),
BankCard1 = BankCard#domain_BankCard{
bin = get_tokenized_bin(PaymentData),
payment_system_deprecated = PaymentSystem,
last_digits = get_tokenized_pan(Last4, PaymentData),
token_provider_deprecated = TokenProvider,
is_cvv_empty = set_is_empty_cvv(TokenProvider, BankCard),
is_cvv_empty = set_is_empty_cvv(TokenizationMethod, BankCard),
exp_date = encode_exp_date(genlib_map:get(exp_date, ExtraCardData)),
cardholder_name = genlib_map:get(cardholder, ExtraCardData)
cardholder_name = genlib_map:get(cardholder, ExtraCardData),
tokenization_method = TokenizationMethod
},
BankCard2 = add_metadata(NS, ProviderMetadata, BankCard1),
Deadline = capi_utils:deadline_from_binary(ValidUntil),
@ -556,33 +560,27 @@ get_tokenized_pan(_Last4, {card, #paytoolprv_Card{pan = PAN}}) ->
get_tokenized_pan(Last4, _PaymentData) when Last4 =/= undefined ->
Last4.
get_tokenization_method({card, _}) ->
none;
get_tokenization_method({tokenized_card, _}) ->
dpan.
% Do not drop is_cvv_empty flag for tokenized bank cards which looks like
% simple bank card. This prevent wrong routing decisions in hellgate
% when cvv is empty, but is_cvv_empty = undefined, which forces routing to bypass
% restrictions and crash adapter. This situation is
% only applicable for GooglePay with tokenized bank card via browser.
set_is_empty_cvv(undefined, BankCard) ->
% restrictions and crash adapter.
set_is_empty_cvv(none, BankCard) ->
BankCard#domain_BankCard.is_cvv_empty;
set_is_empty_cvv(_, _) ->
undefined.
get_payment_token_provider({yandex, _}, _) ->
% TODO
% Infamous Yandex.Pay is exempt from the following consideration, because we need that. And because
% dropping following reclassification is too dangerous because of domain config complexity. I really
% hope this hyperkludge won't live long.
get_payment_token_provider({yandex, _}) ->
yandexpay;
get_payment_token_provider(_PaymentDetails, {card, _}) ->
% TODO
% We deliberately hide the fact that we've got that payment tool from the likes of Google Chrome browser
% in order to make our internal services think of it as if it was good ol' plain bank card. Without a
% CVV though. A better solution would be to distinguish between a _token provider_ and an _origin_.
undefined;
get_payment_token_provider({apple, _}, _PaymentData) ->
get_payment_token_provider({apple, _}) ->
applepay;
get_payment_token_provider({google, _}, _PaymentData) ->
get_payment_token_provider({google, _}) ->
googlepay;
get_payment_token_provider({samsung, _}, _PaymentData) ->
get_payment_token_provider({samsung, _}) ->
samsungpay.
%% TODO

View File

@ -797,6 +797,7 @@ create_applepay_tokenized_payment_resource_ok_test(Config) ->
),
ClientInfo = #{<<"fingerprint">> => <<"test fingerprint">>},
{ok, #{
<<"paymentToolToken">> := PaymentToolToken,
<<"paymentToolDetails">> := Details = #{
<<"paymentSystem">> := <<"mastercard">>,
<<"cardNumberMask">> := <<"************7892">>,
@ -812,7 +813,15 @@ create_applepay_tokenized_payment_resource_ok_test(Config) ->
},
<<"clientInfo">> => ClientInfo
}),
false = maps:is_key(<<"first6">>, Details).
false = maps:is_key(<<"first6">>, Details),
{bank_card, BankCard} = decrypt_payment_tool(PaymentToolToken),
?assertMatch(
#domain_BankCard{
tokenization_method = dpan,
token_provider_deprecated = applepay
},
BankCard
).
-spec create_googlepay_tokenized_payment_resource_ok_test(_) -> _.
create_googlepay_tokenized_payment_resource_ok_test(Config) ->
@ -832,6 +841,7 @@ create_googlepay_tokenized_payment_resource_ok_test(Config) ->
),
ClientInfo = #{<<"fingerprint">> => <<"test fingerprint">>},
{ok, #{
<<"paymentToolToken">> := PaymentToolToken,
<<"paymentToolDetails">> := Details = #{
<<"paymentSystem">> := <<"mastercard">>,
<<"tokenProvider">> := <<"googlepay">>,
@ -848,7 +858,14 @@ create_googlepay_tokenized_payment_resource_ok_test(Config) ->
},
<<"clientInfo">> => ClientInfo
}),
?assertEqual(error, maps:find(<<"first6">>, Details)).
?assertEqual(error, maps:find(<<"first6">>, Details)),
{bank_card, BankCard} = decrypt_payment_tool(PaymentToolToken),
?assertMatch(
#domain_BankCard{
tokenization_method = dpan
},
BankCard
).
-spec create_googlepay_plain_payment_resource_ok_test(_) -> _.
create_googlepay_plain_payment_resource_ok_test(Config) ->
@ -876,7 +893,8 @@ create_googlepay_plain_payment_resource_ok_test(Config) ->
ClientInfo = #{<<"fingerprint">> => <<"test fingerprint">>},
{ok, #{
<<"paymentToolToken">> := PaymentToolToken,
<<"paymentToolDetails">> := Details = #{
<<"paymentToolDetails">> := #{
<<"tokenProvider">> := <<"googlepay">>,
<<"paymentSystem">> := <<"mastercard">>,
<<"cardNumberMask">> := <<"532130******7892">>,
<<"first6">> := <<"532130">>,
@ -892,7 +910,6 @@ create_googlepay_plain_payment_resource_ok_test(Config) ->
},
<<"clientInfo">> => ClientInfo
}),
false = maps:is_key(<<"tokenProvider">>, Details),
%% is_cvv_empty = true for GooglePay tokenized plain bank card
%% see capi_handler_tokens:set_is_empty_cvv/2 for more info
{bank_card, BankCard} = decrypt_payment_tool(PaymentToolToken),
@ -900,7 +917,8 @@ create_googlepay_plain_payment_resource_ok_test(Config) ->
#domain_BankCard{
payment_system_deprecated = mastercard,
last_digits = <<"7892">>,
is_cvv_empty = true
is_cvv_empty = true,
tokenization_method = none
},
BankCard
).
@ -944,6 +962,7 @@ create_yandexpay_tokenized_payment_resource_ok_test(Config) ->
PaymentTool = decrypt_payment_tool(EncryptedToken),
?assertMatch(
{bank_card, #domain_BankCard{
tokenization_method = dpan,
metadata = #{
<<"com.rbkmoney.payment-tool-provider">> :=
{obj, #{