From d4fe7e16bd65d0ff84f2b499a215fd2e03437329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Wed, 20 Apr 2022 15:07:35 +0300 Subject: [PATCH] TD-195: Remove old payment methods (#9) * removed legacy * fixed format * fixed * added some tests, refactored for more coverage * added requested changes * fixed dep * fixed * fixed * fixed --- CONTRIBUTING.md | 13 ++ Dockerfile | 18 +-- Dockerfile.dev | 9 +- Makefile | 2 +- README.md | 15 ++ apps/capi/src/capi_crypto.erl | 6 +- apps/capi/src/capi_domain.erl | 74 ---------- apps/capi/src/capi_feature_schemas.erl | 6 +- apps/capi/src/capi_feature_schemas_legacy.erl | 6 +- apps/capi/src/capi_handler_customers.erl | 14 +- .../src/capi_handler_decoder_invoicing.erl | 62 ++++----- apps/capi/src/capi_handler_decoder_party.erl | 93 ++++--------- apps/capi/src/capi_handler_decoder_utils.erl | 25 ++++ apps/capi/src/capi_handler_encoder.erl | 129 ------------------ apps/capi/src/capi_handler_search.erl | 25 ++-- .../test/capi_base_api_token_tests_SUITE.erl | 33 +---- ...capi_customer_access_token_tests_SUITE.erl | 24 +++- apps/capi/test/capi_dummy_data.hrl | 127 +++++++---------- .../test/capi_idempotency_tests_SUITE.erl | 37 +++-- .../capi_invoice_access_token_tests_SUITE.erl | 15 +- rebar.config | 2 +- rebar.lock | 4 +- 22 files changed, 251 insertions(+), 488 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7b9923f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Чеклист по изменениям + +В этом документе будут перечислены архитектурные особенности сервиса, +которые следует учитывать при добавлении новых программных модулей. + +- **Проверить не влияет ли публикуемое изменение на идемпотентность операций, +выполняемых во время перехода между версиями сервиса**. + + При изменении внешнего или внутреннего формата данных нужно учитывать их + использование для формирования запросов к API, так как во время публикации + новой версии сервиса могут возникнуть конфликты в запросах, которые должны + работать идемпотентно. [Подробнее](README.md). +- **При добавлении новых методов в API необходимо доработать [политики авторизации](https://github.com/valitydev/bouncer-policies)**. diff --git a/Dockerfile b/Dockerfile index 6fc6039..be0c666 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,13 +2,12 @@ ARG OTP_VERSION # Build the release FROM docker.io/library/erlang:${OTP_VERSION} AS builder - -ARG BUILDARCH +SHELL ["/bin/bash", "-o", "pipefail", "-c"] # Install thrift compiler ARG THRIFT_VERSION - -RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${BUILDARCH}.tar.gz" \ +ARG TARGETARCH +RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${TARGETARCH}.tar.gz" \ | tar -xvz -C /usr/local/bin/ # Copy sources @@ -17,8 +16,8 @@ COPY . /build/ # Build the release WORKDIR /build -RUN rebar3 compile -RUN rebar3 as prod release +RUN rebar3 compile && \ + rebar3 as prod release # Make a runner image FROM docker.io/library/erlang:${OTP_VERSION}-slim @@ -37,7 +36,10 @@ WORKDIR /opt/${SERVICE_NAME} COPY --from=builder /build/_build/prod/rel/${SERVICE_NAME} /opt/${SERVICE_NAME} +RUN echo "#!/bin/sh" >> /entrypoint.sh && \ + echo "exec /opt/${SERVICE_NAME}/bin/${SERVICE_NAME} foreground" >> /entrypoint.sh && \ + chmod +x /entrypoint.sh ENTRYPOINT [] -CMD /opt/${SERVICE_NAME}/bin/${SERVICE_NAME} foreground +CMD ["/entrypoint.sh"] -EXPOSE 8022 +EXPOSE 8022 \ No newline at end of file diff --git a/Dockerfile.dev b/Dockerfile.dev index 54f1170..c1ca7d0 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,13 +1,12 @@ ARG OTP_VERSION FROM docker.io/library/erlang:${OTP_VERSION} - -ARG BUILDARCH +SHELL ["/bin/bash", "-o", "pipefail", "-c"] # Install thrift compiler ARG THRIFT_VERSION - -RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${BUILDARCH}.tar.gz" \ +ARG TARGETARCH +RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${TARGETARCH}.tar.gz" \ | tar -xvz -C /usr/local/bin/ # Set env @@ -15,4 +14,4 @@ ENV CHARSET=UTF-8 ENV LANG=C.UTF-8 # Set runtime -CMD /bin/bash +CMD ["/bin/bash"] \ No newline at end of file diff --git a/Makefile b/Makefile index 238cf3f..cb8fcee 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ dev-image: .image.dev .image.dev: Dockerfile.dev .env $(DOCKER) build $(DOTENV:%=--build-arg %) -f Dockerfile.dev -t $(DEV_IMAGE_TAG) . - $(DOCKER) image ls -q -f "reference=$(DEV_IMAGE_ID)" | head -n1 > $@ + $(DOCKER) image ls -q -f "reference=$(DEV_IMAGE_TAG)" | head -n1 > $@ clean-dev-image: ifneq ($(DEV_IMAGE_ID),) diff --git a/README.md b/README.md index 032e20a..1221a58 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,21 @@ [1]: http://erlang.org/doc/man/shell.html [2]: https://github.com/erlware/relx [3]: https://docs.docker.com/machine/install-machine/ +[4]: https://github.com/valitydev/feat + +## Реализация идемпотентности запросов + +Идемпотентность запросов создания/изменения сущностей обеспечивается специальной [подсистемой][4], +которая оперирует несколькими понятиями: + - ExternalId - внешний идентификатор сущности. + - Features - значимая часть данных запроса, изменение которых может появлиять на результат выполнения запроса. + - Schema - рецепт как из полной структуры данных запроса получить Features. + +В случае, когда в запросе фигурирует ExternalId, сервис будет обрабатывать запрос идемпотентно. +Для структуры данных запроса существует Schema, по которой извлекается Features. Features ассоциируется с +переданным ExternalId. При повторе запроса с таким же ExternalId код извлечет Features из новых данных и +сравнит их с Features оригинального запроса, в случае совпадения сервис ответит идемпотентно, в противном случае +сервис ответит ошибкой с кодом 409. ## TODO diff --git a/apps/capi/src/capi_crypto.erl b/apps/capi/src/capi_crypto.erl index de1ba9f..904dac9 100644 --- a/apps/capi/src/capi_crypto.erl +++ b/apps/capi/src/capi_crypto.erl @@ -84,9 +84,9 @@ encode_payment_tool_token_payload({digital_wallet, DigitalWallet}) -> {digital_wallet_payload, #ptt_DigitalWalletPayload{ digital_wallet = DigitalWallet }}; -encode_payment_tool_token_payload({crypto_currency_deprecated, CryptoCurrency}) -> +encode_payment_tool_token_payload({crypto_currency, CryptoCurrency}) -> {crypto_currency_payload, #ptt_CryptoCurrencyPayload{ - crypto_currency_deprecated = CryptoCurrency + crypto_currency = CryptoCurrency }}; encode_payment_tool_token_payload({mobile_commerce, MobileCommerce}) -> {mobile_commerce_payload, #ptt_MobileCommercePayload{ @@ -109,7 +109,7 @@ decode_payment_tool_token_payload(PaymentToolToken) -> {digital_wallet_payload, Payload} -> {digital_wallet, Payload#ptt_DigitalWalletPayload.digital_wallet}; {crypto_currency_payload, Payload} -> - {crypto_currency_deprecated, Payload#ptt_CryptoCurrencyPayload.crypto_currency_deprecated}; + {crypto_currency, Payload#ptt_CryptoCurrencyPayload.crypto_currency}; {mobile_commerce_payload, Payload} -> {mobile_commerce, Payload#ptt_MobileCommercePayload.mobile_commerce} end. diff --git a/apps/capi/src/capi_domain.erl b/apps/capi/src/capi_domain.erl index c0901af..1d91241 100644 --- a/apps/capi/src/capi_domain.erl +++ b/apps/capi/src/capi_domain.erl @@ -7,12 +7,8 @@ -export([get_payment_institutions/1]). -export([get/2]). -export([get_objects_by_type/2]). --export([map_to_dictionary_id/2]). --export([map_to_dictionary_id/3]). -export([encode_enum/2]). -export([encode_enum/3]). --export([fetch_type_info/1]). --export([fetch_type_info/2]). -export([extract_type/1]). -type processing_context() :: capi_handler:processing_context(). @@ -80,57 +76,6 @@ get(Ref, Context) -> {error, not_found} end. --spec map_to_dictionary_id(dmt_client:object_type(), ID :: undefined | term()) -> NewRef :: undefined | term(). -map_to_dictionary_id(ObjectName, LegacyID) -> - map_to_dictionary_id(ObjectName, LegacyID, undefined). - --spec map_to_dictionary_id(dmt_client:object_type(), ID :: undefined | term(), NewRef) -> NewRef when - NewRef :: term() | no_return(). -map_to_dictionary_id(ObjectName, LegacyID, NewRef) -> - DictionaryID = - case LegacyID of - undefined -> - NewRef; - _ -> - case fetch_dictionary_id(ObjectName, LegacyID) of - {ok, Ref} when Ref =:= NewRef; NewRef =:= undefined -> - Ref; - {ok, OtherRef} -> - logger:warning( - "Mismatch in mapped to dictionary value and passed ~p: ~p->~p and ~p." - "Using dictionary value (the latter)", - [ObjectName, LegacyID, OtherRef, NewRef] - ), - OtherRef; - {error, _} = Error -> - logger:warning( - "Failed to find mapping ~w with id ~w: " - "chance of domain misconifuration (Error: ~w). Using passed new ref", - [ObjectName, LegacyID, Error] - ), - NewRef - end - end, - case DictionaryID of - undefined -> - error({no_mapping, {ObjectName, LegacyID, DictionaryID}}); - DictionaryID -> - DictionaryID - end. - -fetch_dictionary_id(ObjectName, LegacyID) -> - {dmsl_domain_thrift, RefRecordShortName} = - extract_type(fetch_type_info([{variant, ObjectName}, {field, ref}])), - RefRecordName = dmsl_domain_thrift:record_name(RefRecordShortName), - case get({ObjectName, {RefRecordName, LegacyID}}, undefined) of - {ok, Data} -> - {DataFieldID, _Kind, _Info, data, _Default} = - fetch_type_info([{variant, ObjectName}, {field, data}]), - {ok, element(1 + DataFieldID, Data)}; - {error, _} = Error -> - Error - end. - -spec encode_enum(Type :: atom(), binary()) -> {ok, atom()} | {error, unknown_atom | unknown_variant}. encode_enum(Type, Binary) -> encode_enum(dmsl_domain_thrift, Type, Binary). @@ -148,25 +93,6 @@ encode_enum(Module, Type, Binary) -> {error, unknown_atom} end. --spec fetch_type_info([{variant, atom()} | {field, atom()}]) -> term(). -fetch_type_info(Path) -> - fetch_type_info('DomainObject', Path). - --spec fetch_type_info(TypeInfo :: term(), [{variant, atom()} | {field, atom()}]) -> term(). -fetch_type_info(TypeInfo, []) -> - TypeInfo; -fetch_type_info(TypeInfo, [{variant, Variant} | Rest]) -> - fetch_type_info(fetch_struct_field(TypeInfo, union, Variant), Rest); -fetch_type_info(TypeInfo, [{field, Field} | Rest]) -> - fetch_type_info(fetch_struct_field(TypeInfo, struct, Field), Rest); -fetch_type_info(_, _) -> - error(badarg). - -fetch_struct_field(TypeInfo, Kind, Field) -> - {Module, Type} = extract_type(TypeInfo), - {struct, Kind, Fields} = Module:struct_info(Type), - lists:keyfind(Field, 4, Fields). - -type type() :: atom(). -type type_info() :: type() | {module(), type()} | dmsl_domain_thrift:struct_info(). diff --git a/apps/capi/src/capi_feature_schemas.erl b/apps/capi/src/capi_feature_schemas.erl index d45331c..baa4d4e 100644 --- a/apps/capi/src/capi_feature_schemas.erl +++ b/apps/capi/src/capi_feature_schemas.erl @@ -634,7 +634,7 @@ compare_customer_features_test() -> -spec read_customer_binding_features_test() -> _. read_customer_binding_features_test() -> Session = ?TEST_PAYMENT_SESSION(<<"Session">>), - Tool = ?TEST_PAYMENT_TOOL(visa, <<"TOKEN">>), + Tool = ?TEST_PAYMENT_TOOL(<<"visa">>, <<"TOKEN">>), Request = payment_resource(Session, Tool), Features = #{ ?payment_resource => #{ @@ -657,11 +657,11 @@ read_customer_binding_features_test() -> -spec compare_customer_binding_features_test() -> _. compare_customer_binding_features_test() -> Session1 = ?TEST_PAYMENT_SESSION(<<"Session1">>), - Tool1 = ?TEST_PAYMENT_TOOL(visa), + Tool1 = ?TEST_PAYMENT_TOOL(<<"visa">>), Request1 = payment_resource(Session1, Tool1), Session2 = ?TEST_PAYMENT_SESSION(<<"Session2">>), - Tool2 = ?TEST_PAYMENT_TOOL(mastercard)#{<<"exp_date">> => <<"01/2020">>}, + Tool2 = ?TEST_PAYMENT_TOOL(<<"mastercard">>)#{<<"exp_date">> => <<"01/2020">>}, Request2 = payment_resource(Session2, Tool2), common_compare_tests(customer_binding(), Request1, Request2, [ diff --git a/apps/capi/src/capi_feature_schemas_legacy.erl b/apps/capi/src/capi_feature_schemas_legacy.erl index deb98ac..310f946 100644 --- a/apps/capi/src/capi_feature_schemas_legacy.erl +++ b/apps/capi/src/capi_feature_schemas_legacy.erl @@ -660,7 +660,7 @@ compare_customer_features_test() -> -spec read_customer_binding_features_test() -> _. read_customer_binding_features_test() -> Session = ?TEST_PAYMENT_SESSION(<<"Session">>), - Tool = ?TEST_PAYMENT_TOOL(visa, <<"TOKEN">>), + Tool = ?TEST_PAYMENT_TOOL(<<"visa">>, <<"TOKEN">>), Request = payment_resource(Session, Tool), Features = #{ ?payment_resource => #{ @@ -699,11 +699,11 @@ read_customer_binding_features_test() -> -spec compare_customer_binding_features_test() -> _. compare_customer_binding_features_test() -> Session1 = ?TEST_PAYMENT_SESSION(<<"Session1">>), - Tool1 = ?TEST_PAYMENT_TOOL(visa), + Tool1 = ?TEST_PAYMENT_TOOL(<<"visa">>), Request1 = payment_resource(Session1, Tool1), Session2 = ?TEST_PAYMENT_SESSION(<<"Session2">>), - Tool2 = ?TEST_PAYMENT_TOOL(mastercard)#{<<"exp_date">> => <<"01/2020">>}, + Tool2 = ?TEST_PAYMENT_TOOL(<<"mastercard">>)#{<<"exp_date">> => <<"01/2020">>}, Request2 = payment_resource(Session2, Tool2), common_compare_tests(customer_binding(), Request1, Request2, [ diff --git a/apps/capi/src/capi_handler_customers.erl b/apps/capi/src/capi_handler_customers.erl index 7877417..a2f5c7e 100644 --- a/apps/capi/src/capi_handler_customers.erl +++ b/apps/capi/src/capi_handler_customers.erl @@ -365,23 +365,15 @@ encode_payment_tool_token(Token) -> #{payment_tool := PaymentTool, valid_until := ValidUntil} = TokenData, case capi_utils:deadline_is_reached(ValidUntil) of true -> - logger:warning("Payment tool token expired: ~p", [capi_utils:deadline_to_binary(ValidUntil)]), + logger:info("Payment tool token expired: ~p", [capi_utils:deadline_to_binary(ValidUntil)]), capi_handler:respond(logic_error('invalidPaymentToolToken')); _ -> PaymentTool end; unrecognized -> - encode_legacy_payment_tool_token(Token); + capi_handler:respond(logic_error('invalidPaymentToolToken')); {error, {decryption_failed, Error}} -> - logger:warning("Payment tool token decryption failed: ~p", [Error]), - capi_handler:respond(logic_error('invalidPaymentToolToken')) - end. - -encode_legacy_payment_tool_token(Token) -> - try - capi_handler_encoder:encode_payment_tool(capi_utils:base64url_to_map(Token)) - catch - error:badarg -> + logger:info("Payment tool token decryption failed: ~p", [Error]), capi_handler:respond(logic_error('invalidPaymentToolToken')) end. diff --git a/apps/capi/src/capi_handler_decoder_invoicing.erl b/apps/capi/src/capi_handler_decoder_invoicing.erl index 5636c37..7e0b520 100644 --- a/apps/capi/src/capi_handler_decoder_invoicing.erl +++ b/apps/capi/src/capi_handler_decoder_invoicing.erl @@ -476,7 +476,7 @@ decode_payment_methods(PaymentMethodRefs) -> decode_payment_method(bank_card, Cards) -> {Regular, Tokenized} = lists:partition( - fun(#domain_BankCardPaymentMethod{token_provider_deprecated = TP}) -> TP =:= undefined end, + fun(#domain_BankCardPaymentMethod{payment_token = TP}) -> TP =:= undefined end, Cards ), [ @@ -487,64 +487,50 @@ decode_payment_method(payment_terminal, Providers) -> [ #{ <<"method">> => <<"PaymentTerminal">>, - <<"providers">> => [Id || #domain_PaymentServiceRef{id = Id} <- Providers] + <<"providers">> => [ + capi_handler_decoder_utils:decode_payment_service_ref(Provider) + || Provider <- Providers + ] } ]; decode_payment_method(digital_wallet, Providers) -> [ #{ <<"method">> => <<"DigitalWallet">>, - <<"providers">> => [Id || #domain_PaymentServiceRef{id = Id} <- Providers] + <<"providers">> => [ + capi_handler_decoder_utils:decode_payment_service_ref(Provider) + || Provider <- Providers + ] } ]; decode_payment_method(crypto_currency, CryptoCurrencies) -> [ #{ <<"method">> => <<"CryptoWallet">>, - <<"cryptoCurrencies">> => [Id || #domain_CryptoCurrencyRef{id = Id} <- CryptoCurrencies] + <<"cryptoCurrencies">> => [ + capi_handler_decoder_utils:decode_crypto_currency_ref(Currency) + || Currency <- CryptoCurrencies + ] } ]; decode_payment_method(mobile, MobileOperators) -> [ #{ <<"method">> => <<"MobileCommerce">>, - <<"operators">> => [Id || #domain_MobileOperatorRef{id = Id} <- MobileOperators] + <<"operators">> => [ + capi_handler_decoder_utils:decode_mobile_operator_ref(Operator) + || Operator <- MobileOperators + ] } - ]; -decode_payment_method(empty_cvv_bank_card_deprecated, PaymentSystems) -> - [#{<<"method">> => <<"BankCard">>, <<"paymentSystems">> => lists:map(fun genlib:to_binary/1, PaymentSystems)}]; -decode_payment_method(bank_card_deprecated, PaymentSystems) -> - [#{<<"method">> => <<"BankCard">>, <<"paymentSystems">> => lists:map(fun genlib:to_binary/1, PaymentSystems)}]; -decode_payment_method(tokenized_bank_card_deprecated, TokenizedBankCards) -> - decode_tokenized_bank_cards(TokenizedBankCards); -decode_payment_method(payment_terminal_deprecated, Providers) -> - [#{<<"method">> => <<"PaymentTerminal">>, <<"providers">> => lists:map(fun genlib:to_binary/1, Providers)}]; -decode_payment_method(digital_wallet_deprecated, Providers) -> - [#{<<"method">> => <<"DigitalWallet">>, <<"providers">> => lists:map(fun genlib:to_binary/1, Providers)}]; -decode_payment_method(crypto_currency_deprecated, CryptoCurrencies) -> - Decoder = fun capi_handler_decoder_utils:convert_crypto_currency_to_swag/1, - [ - #{ - <<"method">> => <<"CryptoWallet">>, - <<"cryptoCurrencies">> => lists:map(Decoder, CryptoCurrencies) - } - ]; -decode_payment_method(mobile_deprecated, MobileOperators) -> - [#{<<"method">> => <<"MobileCommerce">>, <<"operators">> => lists:map(fun genlib:to_binary/1, MobileOperators)}]. + ]. -decode_bank_card(#domain_BankCardPaymentMethod{payment_system_deprecated = PS}) -> genlib:to_binary(PS). +decode_bank_card(#domain_BankCardPaymentMethod{payment_system = PS}) -> + capi_handler_decoder_utils:decode_payment_system_ref(PS). decode_tokenized_bank_cards([#domain_BankCardPaymentMethod{} | _] = TokenizedBankCards) -> PropTokenizedBankCards = [ {TP, PS} - || #domain_BankCardPaymentMethod{payment_system_deprecated = PS, token_provider_deprecated = TP} <- - TokenizedBankCards - ], - do_decode_tokenized_bank_cards(PropTokenizedBankCards); -decode_tokenized_bank_cards([#domain_TokenizedBankCard{} | _] = TokenizedBankCards) -> - PropTokenizedBankCards = [ - {TP, PS} - || #domain_TokenizedBankCard{payment_system_deprecated = PS, token_provider_deprecated = TP} <- + || #domain_BankCardPaymentMethod{payment_system = PS, payment_token = TP} <- TokenizedBankCards ], do_decode_tokenized_bank_cards(PropTokenizedBankCards); @@ -563,8 +549,10 @@ do_decode_tokenized_bank_cards(PropTokenizedBankCards) -> decode_tokenized_bank_card(TokenProvider, PaymentSystems) -> #{ <<"method">> => <<"BankCard">>, - <<"paymentSystems">> => lists:map(fun genlib:to_binary/1, PaymentSystems), - <<"tokenProviders">> => [genlib:to_binary(TokenProvider)] + <<"paymentSystems">> => + lists:map(fun capi_handler_decoder_utils:decode_payment_system_ref/1, PaymentSystems), + <<"tokenProviders">> => + [capi_handler_decoder_utils:decode_bank_card_token_service_ref(TokenProvider)] }. -spec make_invoice_and_token(capi_handler_encoder:encode_data(), processing_context()) -> diff --git a/apps/capi/src/capi_handler_decoder_party.erl b/apps/capi/src/capi_handler_decoder_party.erl index 5459057..5eb5261 100644 --- a/apps/capi/src/capi_handler_decoder_party.erl +++ b/apps/capi/src/capi_handler_decoder_party.erl @@ -175,9 +175,7 @@ decode_payment_tool({digital_wallet, DigitalWallet}) -> decode_payment_tool({mobile_commerce, MobileCommerce}) -> decode_mobile_commerce(MobileCommerce); decode_payment_tool({crypto_currency, CryptoCurrency}) -> - decode_crypto_wallet(CryptoCurrency); -decode_payment_tool({crypto_currency_deprecated, LegacyCryptoCurrency}) -> - decode_legacy_crypto_wallet(LegacyCryptoCurrency). + decode_crypto_wallet(CryptoCurrency). -spec wrap_payment_tool_token(capi_handler_decoder_utils:decode_data()) -> binary(). wrap_payment_tool_token(#{<<"type">> := <<"bank_card">>} = BankCard) -> @@ -205,29 +203,28 @@ wrap_payment_tool_token(#{<<"type">> := <<"mobile_commerce">>} = MobileCommerce) decode_bank_card(#domain_BankCard{ 'token' = Token, - 'payment_system' = NewPaymentSystem, - 'payment_system_deprecated' = LegacyPaymentSystem, + 'payment_system' = PaymentSystem, 'bin' = Bin, 'last_digits' = LastDigits, - 'token_provider_deprecated' = TokenProvider, + 'payment_token' = BankCardTokenServiceRef, 'issuer_country' = IssuerCountry, 'bank_name' = BankName, 'metadata' = Metadata, 'is_cvv_empty' = IsCVVEmpty, 'exp_date' = ExpDate, 'cardholder_name' = CardHolder - %% 'tokenization_method' = TokenizationMethod, - %% 'payment_token' = BankCardTokenServiceRef, - %% 'token_provider_deprecated' = LegacyTokenProvider + % 'tokenization_method' = TokenizationMethod }) -> - PaymentSystem = map_to_dictionary_id(payment_system_legacy, LegacyPaymentSystem, NewPaymentSystem), genlib_map:compact(#{ <<"type">> => <<"bank_card">>, <<"token">> => Token, - <<"payment_system">> => PaymentSystem, + <<"payment_system">> => capi_handler_decoder_utils:decode_payment_system_ref(PaymentSystem), <<"bin">> => Bin, <<"masked_pan">> => LastDigits, - <<"token_provider">> => TokenProvider, + <<"token_provider">> => capi_utils:maybe( + BankCardTokenServiceRef, + fun capi_handler_decoder_utils:decode_bank_card_token_service_ref/1 + ), <<"issuer_country">> => IssuerCountry, <<"bank_name">> => BankName, <<"metadata">> => decode_bank_card_metadata(Metadata), @@ -248,26 +245,20 @@ decode_bank_card_metadata(undefined) -> decode_bank_card_metadata(Meta) -> maps:map(fun(_, Data) -> capi_msgp_marshalling:unmarshal(Data) end, Meta). -decode_payment_terminal(#domain_PaymentTerminal{ - payment_service = PaymentService, - terminal_type_deprecated = LegacyTerminalType -}) -> - Type = map_to_dictionary_id(terminal_provider_legacy, LegacyTerminalType, PaymentService), +decode_payment_terminal(#domain_PaymentTerminal{payment_service = PaymentService}) -> #{ <<"type">> => <<"payment_terminal">>, - <<"terminal_type">> => Type + <<"terminal_type">> => capi_handler_decoder_utils:decode_payment_service_ref(PaymentService) }. decode_digital_wallet(#domain_DigitalWallet{ payment_service = PaymentService, - provider_deprecated = LegacyProvider, id = ID, token = Token }) -> - Provider = map_to_dictionary_id(payment_service_legacy, LegacyProvider, PaymentService), genlib_map:compact(#{ <<"type">> => <<"digital_wallet">>, - <<"provider">> => Provider, + <<"provider">> => capi_handler_decoder_utils:decode_payment_service_ref(PaymentService), <<"id">> => ID, <<"token">> => Token }). @@ -275,30 +266,22 @@ decode_digital_wallet(#domain_DigitalWallet{ decode_crypto_wallet(CryptoCurrency) -> #{ <<"type">> => <<"crypto_wallet">>, - <<"crypto_currency">> => CryptoCurrency - }. -decode_legacy_crypto_wallet(LegacyCryptoCurrency) -> - CryptoCurrency = map_to_dictionary_id(crypto_currency_legacy, LegacyCryptoCurrency), - #{ - <<"type">> => <<"crypto_wallet">>, - <<"crypto_currency">> => CryptoCurrency + <<"crypto_currency">> => capi_handler_decoder_utils:decode_crypto_currency_ref(CryptoCurrency) }. decode_mobile_commerce(MobileCommerce) -> #domain_MobileCommerce{ - operator = NewMobileOperator, - operator_deprecated = LegacyOperator, + operator = MobileOperator, phone = #domain_MobilePhone{ cc = Cc, ctn = Ctn } } = MobileCommerce, - MobileOperator = map_to_dictionary_id(mobile_operator_legacy, LegacyOperator, NewMobileOperator), Phone = #{<<"cc">> => Cc, <<"ctn">> => Ctn}, #{ <<"type">> => <<"mobile_commerce">>, <<"phone">> => Phone, - <<"operator">> => MobileOperator + <<"operator">> => capi_handler_decoder_utils:decode_mobile_operator_ref(MobileOperator) }. -spec decode_payment_tool_details(capi_handler_encoder:encode_data()) -> capi_handler_decoder_utils:decode_data(). @@ -313,12 +296,6 @@ decode_payment_tool_details({crypto_currency, #domain_CryptoCurrencyRef{id = Cry <<"detailsType">> => <<"PaymentToolDetailsCryptoWallet">>, <<"cryptoCurrency">> => CryptoCurrency }; -decode_payment_tool_details({crypto_currency_deprecated, LegacyCryptoCurrency}) -> - CryptoCurrency = map_to_dictionary_id(crypto_currency_legacy, LegacyCryptoCurrency), - #{ - <<"detailsType">> => <<"PaymentToolDetailsCryptoWallet">>, - <<"cryptoCurrency">> => CryptoCurrency - }; decode_payment_tool_details({mobile_commerce, MobileCommerce}) -> #domain_MobileCommerce{ phone = Phone @@ -335,40 +312,30 @@ mask_phone_number(PhoneNumber) -> decode_bank_card_details(BankCard, V) -> LastDigits = capi_handler_decoder_utils:decode_last_digits(BankCard#domain_BankCard.last_digits), Bin = capi_handler_decoder_utils:decode_bank_card_bin(BankCard#domain_BankCard.bin), - PaymentSystem = - map_to_dictionary_id( - payment_system_legacy, - BankCard#domain_BankCard.payment_system_deprecated, - BankCard#domain_BankCard.payment_system - ), - - TokenProvider = - map_to_dictionary_id( - payment_token_legacy, - BankCard#domain_BankCard.token_provider_deprecated, - BankCard#domain_BankCard.payment_token - ), + PaymentSystem = BankCard#domain_BankCard.payment_system, + TokenProvider = BankCard#domain_BankCard.payment_token, capi_handler_utils:merge_and_compact(V, #{ <<"last4">> => LastDigits, <<"first6">> => Bin, <<"cardNumberMask">> => capi_handler_decoder_utils:decode_masked_pan(Bin, LastDigits), - <<"paymentSystem">> => PaymentSystem, - <<"tokenProvider">> => TokenProvider + <<"paymentSystem">> => capi_handler_decoder_utils:decode_payment_system_ref(PaymentSystem), + <<"tokenProvider">> => capi_utils:maybe( + TokenProvider, + fun capi_handler_decoder_utils:decode_bank_card_token_service_ref/1 + ) % TODO: Uncomment or delete this when we negotiate deploying non-breaking changes - % <<"tokenizationMethod">> => genlib:to_binary(BankCard#domain_BankCard.tokenization_method) + % <<"tokenization_method">> => TokenizationMethod }). decode_payment_terminal_details( #domain_PaymentTerminal{ - payment_service = PaymentService, - terminal_type_deprecated = LegacyTerminalType + payment_service = PaymentService }, V ) -> - Type = map_to_dictionary_id(terminal_provider_legacy, LegacyTerminalType, PaymentService), V#{ - <<"provider">> => Type + <<"provider">> => capi_handler_decoder_utils:decode_payment_service_ref(PaymentService) }. decode_digital_wallet_details(#domain_DigitalWallet{payment_service = Provider}, V) -> @@ -452,16 +419,6 @@ decode_mobile_phone(#domain_MobilePhone{cc = Cc, ctn = Ctn}) -> gen_phone_number(#{<<"cc">> := Cc, <<"ctn">> := Ctn}) -> <<"+", Cc/binary, Ctn/binary>>. -map_to_dictionary_id(_ObjectName, undefined) -> undefined; -map_to_dictionary_id(ObjectName, LegacyID) -> unwrap_ref(capi_domain:map_to_dictionary_id(ObjectName, LegacyID)). -map_to_dictionary_id(_ObjectName, undefined, undefined) -> - undefined; -map_to_dictionary_id(ObjectName, LegacyID, NewRef) -> - unwrap_ref(capi_domain:map_to_dictionary_id(ObjectName, LegacyID, NewRef)). - -unwrap_ref({Type, ID}) when is_atom(Type) -> - ID. - -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). diff --git a/apps/capi/src/capi_handler_decoder_utils.erl b/apps/capi/src/capi_handler_decoder_utils.erl index 45e3f96..b0e5cd0 100644 --- a/apps/capi/src/capi_handler_decoder_utils.erl +++ b/apps/capi/src/capi_handler_decoder_utils.erl @@ -4,6 +4,11 @@ -export([decode_map/2]). -export([decode_currency/1]). +-export([decode_payment_system_ref/1]). +-export([decode_payment_service_ref/1]). +-export([decode_crypto_currency_ref/1]). +-export([decode_bank_card_token_service_ref/1]). +-export([decode_mobile_operator_ref/1]). -export([decode_business_schedule_ref/1]). -export([decode_bank_card_bin/1]). -export([decode_last_digits/1]). @@ -21,6 +26,11 @@ -type decode_data() :: #{binary() => term()}. -type encoded_currency() :: dmsl_domain_thrift:'Currency'() | dmsl_domain_thrift:'CurrencyRef'(). +-type encoded_payment_system_ref() :: dmsl_domain_thrift:'PaymentSystemRef'(). +-type encoded_payment_service_ref() :: dmsl_domain_thrift:'PaymentServiceRef'(). +-type encoded_crypto_currency_ref() :: dmsl_domain_thrift:'CryptoCurrencyRef'(). +-type encoded_bank_card_token_service_ref() :: dmsl_domain_thrift:'BankCardTokenServiceRef'(). +-type encoded_mobile_operator_ref() :: dmsl_domain_thrift:'MobileOperatorRef'(). -spec decode_map(map(), fun((_) -> any())) -> [any()]. decode_map(Items, Fun) -> @@ -30,6 +40,21 @@ decode_map(Items, Fun) -> decode_currency(#domain_Currency{symbolic_code = SymbolicCode}) -> SymbolicCode; decode_currency(#domain_CurrencyRef{symbolic_code = SymbolicCode}) -> SymbolicCode. +-spec decode_payment_system_ref(encoded_payment_system_ref()) -> binary(). +decode_payment_system_ref(#domain_PaymentSystemRef{id = ID}) -> ID. + +-spec decode_payment_service_ref(encoded_payment_service_ref()) -> binary(). +decode_payment_service_ref(#domain_PaymentServiceRef{id = ID}) -> ID. + +-spec decode_crypto_currency_ref(encoded_crypto_currency_ref()) -> binary(). +decode_crypto_currency_ref(#domain_CryptoCurrencyRef{id = ID}) -> ID. + +-spec decode_bank_card_token_service_ref(encoded_bank_card_token_service_ref()) -> binary(). +decode_bank_card_token_service_ref(#domain_BankCardTokenServiceRef{id = ID}) -> ID. + +-spec decode_mobile_operator_ref(encoded_mobile_operator_ref()) -> binary(). +decode_mobile_operator_ref(#domain_MobileOperatorRef{id = ID}) -> ID. + -spec decode_business_schedule_ref(capi_handler_encoder:encode_data()) -> binary() | undefined. decode_business_schedule_ref(#domain_BusinessScheduleRef{id = ID}) when ID /= undefined -> ID; diff --git a/apps/capi/src/capi_handler_encoder.erl b/apps/capi/src/capi_handler_encoder.erl index 7ff70b9..242c183 100644 --- a/apps/capi/src/capi_handler_encoder.erl +++ b/apps/capi/src/capi_handler_encoder.erl @@ -5,7 +5,6 @@ -export([encode_contact_info/1]). -export([encode_client_info/1]). --export([encode_payment_tool/1]). -export([encode_cash/1]). -export([encode_cash/2]). -export([encode_currency/1]). @@ -39,59 +38,6 @@ encode_client_info(ClientInfo) -> ip_address = maps:get(<<"ip">>, ClientInfo) }. --spec encode_payment_tool(request_data()) -> encode_data(). -encode_payment_tool(PaymentTool) -> - case PaymentTool of - #{<<"type">> := <<"bank_card">>} = Encoded -> - encode_bank_card(Encoded); - #{<<"type">> := <<"payment_terminal">>} = Encoded -> - encode_payment_terminal(Encoded); - #{<<"type">> := <<"digital_wallet">>} = Encoded -> - encode_digital_wallet(Encoded); - #{<<"type">> := <<"crypto_wallet">>} = Encoded -> - encode_crypto_wallet(Encoded); - #{<<"type">> := <<"mobile_commerce">>} = Encoded -> - encode_mobile_commerce(Encoded) - end. - -encode_bank_card(BankCard) -> - {PaymentSystemDeprecated, PaymentSystem} = - infer_legacy_and_dictionary_ids( - payment_system_legacy, - maps:get(<<"payment_system">>, BankCard) - ), - - {PaymentTokenProvider, LegacyTokenProvider} = - infer_legacy_and_dictionary_ids( - payment_token_legacy, - genlib_map:get(<<"token_provider">>, BankCard) - ), - - {bank_card, #domain_BankCard{ - token = maps:get(<<"token">>, BankCard), - payment_system = PaymentSystem, - payment_system_deprecated = PaymentSystemDeprecated, - bin = maps:get(<<"bin">>, BankCard, <<>>), - last_digits = maps:get(<<"masked_pan">>, BankCard), - payment_token = PaymentTokenProvider, - token_provider_deprecated = LegacyTokenProvider, - issuer_country = encode_residence(genlib_map:get(<<"issuer_country">>, BankCard)), - bank_name = genlib_map:get(<<"bank_name">>, BankCard), - metadata = encode_bank_card_metadata(genlib_map:get(<<"metadata">>, BankCard)), - is_cvv_empty = encode_bank_card_cvv_flag(genlib_map:get(<<"is_cvv_empty">>, BankCard)), - tokenization_method = genlib_map:get(<<"tokenization_method">>, BankCard) - }}. - -encode_bank_card_cvv_flag(undefined) -> - undefined; -encode_bank_card_cvv_flag(Flag) when is_binary(Flag) -> - erlang:binary_to_existing_atom(Flag, utf8). - -encode_bank_card_metadata(undefined) -> - undefined; -encode_bank_card_metadata(Meta) -> - maps:map(fun(_, Data) -> capi_msgp_marshalling:marshal(Data) end, Meta). - -spec encode_residence(binary() | undefined) -> atom(). encode_residence(undefined) -> undefined; @@ -101,52 +47,6 @@ encode_residence(Residence) when is_binary(Residence) -> {error, _} -> throw({encode_residence, invalid_residence}) end. -encode_payment_terminal(#{<<"terminal_type">> := Type}) -> - {LegacyTerminalProvider, PaymentService} = - infer_legacy_and_dictionary_ids(terminal_provider_legacy, Type), - {payment_terminal, #domain_PaymentTerminal{ - payment_service = PaymentService, - terminal_type_deprecated = LegacyTerminalProvider - }}. - -encode_digital_wallet(#{<<"provider">> := Provider, <<"id">> := ID} = Wallet) -> - {LegacyDigitalWalletProvider, PaymentService} = - infer_legacy_and_dictionary_ids(payment_service_legacy, Provider), - {digital_wallet, #domain_DigitalWallet{ - payment_service = PaymentService, - provider_deprecated = LegacyDigitalWalletProvider, - id = ID, - token = maps:get(<<"token">>, Wallet, undefined) - }}. - -encode_crypto_wallet(#{<<"crypto_currency">> := CryptoCurrency0}) -> - CryptoCurrency = - convert_crypto_currency_from_swag(CryptoCurrency0), - - case infer_legacy_and_dictionary_ids(payment_service_legacy, CryptoCurrency) of - {LegacyCryptoCurrency, undefined} -> - {crypto_currency_deprecated, LegacyCryptoCurrency}; - {_, CryptoCurrencyRef} -> - {crypto_currency, CryptoCurrencyRef} - end. - -convert_crypto_currency_from_swag(<<"bitcoinCash">>) -> - <<"bitcoin_cash">>; -convert_crypto_currency_from_swag(CryptoCurrency) when is_binary(CryptoCurrency) -> - CryptoCurrency. - -encode_mobile_commerce(#{<<"phoneNumber">> := PhoneNumber, <<"operator">> := Operator}) -> - #{<<"cc">> := Cc, <<"ctn">> := Ctn} = PhoneNumber, - {LegacyOperator, OperatorRef} = infer_legacy_and_dictionary_ids(mobile_operator_legacy, Operator), - {mobile_commerce, #domain_MobileCommerce{ - operator = OperatorRef, - operator_deprecated = LegacyOperator, - phone = #domain_MobilePhone{ - cc = Cc, - ctn = Ctn - } - }}. - -spec encode_cash(request_data()) -> encode_data(). encode_cash(Params) -> Amount = genlib_map:get(<<"amount">>, Params), @@ -253,32 +153,3 @@ encode_stat_request(Dsl, ContinuationToken) when is_binary(Dsl) -> dsl = Dsl, continuation_token = ContinuationToken }. - -infer_legacy_and_dictionary_ids(ObjectVariant, ID) -> - {dmsl_domain_thrift, LegacyIDType} = - capi_domain:extract_type( - capi_domain:fetch_type_info( - 'DomainObject', - [ - {variant, ObjectVariant}, - {field, ref}, - {field, id} - ] - ) - ), - - case capi_domain:encode_enum(LegacyIDType, ID) of - {ok, LegacyID} -> - DictionaryID = map_to_dictionary_id(ObjectVariant, LegacyID), - {LegacyID, DictionaryID}; - {error, _} -> - DictionaryID = ID, - {undefined, DictionaryID} - end. - -map_to_dictionary_id(ObjectVariant, LegacyID) -> - try - capi_domain:map_to_dictionary_id(ObjectVariant, LegacyID) - catch - error:{no_mapping, _} -> undefined - end. diff --git a/apps/capi/src/capi_handler_search.erl b/apps/capi/src/capi_handler_search.erl index f52a14c..3a333eb 100644 --- a/apps/capi/src/capi_handler_search.erl +++ b/apps/capi/src/capi_handler_search.erl @@ -309,19 +309,22 @@ decode_stat_payment_tool_token({mobile_commerce, MobileCommerce}) -> decode_bank_card(#merchstat_BankCard{ 'token' = Token, - 'payment_system_deprecated' = PaymentSystem, + 'payment_system' = PaymentSystem, 'bin' = Bin, 'masked_pan' = MaskedPan, - 'token_provider_deprecated' = TokenProvider + 'payment_token' = BankCardTokenServiceRef }) -> capi_utils:map_to_base64url( genlib_map:compact(#{ <<"type">> => <<"bank_card">>, <<"token">> => Token, - <<"payment_system">> => PaymentSystem, + <<"payment_system">> => capi_handler_decoder_utils:decode_payment_system_ref(PaymentSystem), <<"bin">> => Bin, <<"masked_pan">> => MaskedPan, - <<"token_provider">> => TokenProvider, + <<"token_provider">> => capi_utils:maybe( + BankCardTokenServiceRef, + fun capi_handler_decoder_utils:decode_bank_card_token_service_ref/1 + ), <<"issuer_country">> => undefined, <<"bank_name">> => undefined, <<"metadata">> => undefined @@ -391,19 +394,19 @@ decode_stat_payment_tool_details({mobile_commerce, MobileCommerce}) -> decode_bank_card_details(BankCard, V) -> LastDigits = capi_handler_decoder_utils:decode_last_digits(BankCard#merchstat_BankCard.masked_pan), Bin = capi_handler_decoder_utils:decode_bank_card_bin(BankCard#merchstat_BankCard.bin), + PaymentSystem = capi_handler_decoder_utils:decode_payment_system_ref(BankCard#merchstat_BankCard.payment_system), + BankCardTokenServiceRef = capi_utils:maybe( + BankCard#merchstat_BankCard.payment_token, + fun capi_handler_decoder_utils:decode_bank_card_token_service_ref/1 + ), capi_handler_utils:merge_and_compact(V, #{ <<"last4">> => LastDigits, <<"first6">> => Bin, <<"cardNumberMask">> => capi_handler_decoder_utils:decode_masked_pan(Bin, LastDigits), - <<"paymentSystem">> => genlib:to_binary(BankCard#merchstat_BankCard.payment_system_deprecated), - <<"tokenProvider">> => decode_token_provider(BankCard#merchstat_BankCard.token_provider_deprecated) + <<"paymentSystem">> => PaymentSystem, + <<"tokenProvider">> => BankCardTokenServiceRef }). -decode_token_provider(Provider) when Provider /= undefined -> - genlib:to_binary(Provider); -decode_token_provider(undefined) -> - undefined. - decode_payment_terminal_details(#merchstat_PaymentTerminal{terminal_type = Type}, V) -> V#{ <<"provider">> => genlib:to_binary(Type) diff --git a/apps/capi/test/capi_base_api_token_tests_SUITE.erl b/apps/capi/test/capi_base_api_token_tests_SUITE.erl index 05170b9..8175231 100644 --- a/apps/capi/test/capi_base_api_token_tests_SUITE.erl +++ b/apps/capi/test/capi_base_api_token_tests_SUITE.erl @@ -134,8 +134,7 @@ get_countries_test/1, get_trade_bloc_by_id_test/1, get_trade_bloc_by_id_not_found_test/1, - get_trade_blocs_test/1, - check_support_decrypt_v2_test/1 + get_trade_blocs_test/1 ]). -type test_case_name() :: atom(). @@ -152,8 +151,7 @@ init([]) -> all() -> [ {group, operations_by_api_key_token}, - {group, operations_by_user_session_token}, - {group, payment_tool_token_support} + {group, operations_by_user_session_token} ]. -spec groups() -> [{group_name(), list(), [test_case_name()]}]. @@ -288,9 +286,6 @@ groups() -> download_report_file_ok_test, download_report_file_for_party_ok_test, download_report_file_not_found_test - ]}, - {payment_tool_token_support, [], [ - check_support_decrypt_v2_test ]} ]. @@ -724,7 +719,7 @@ create_payment_ok_test(Config) -> ?STRING, Config ), - PaymentTool = {bank_card, ?BANK_CARD(visa, ?EXP_DATE(2, 2020), <<"Degus">>)}, + PaymentTool = {bank_card, ?BANK_CARD(<<"visa">>, ?EXP_DATE(2, 2020), <<"Degus">>)}, PaymentToolToken = capi_crypto:encode_token(#{payment_tool => PaymentTool, valid_until => undefined}), Req = ?PAYMENT_PARAMS(ExternalID, PaymentToolToken), {ok, _} = capi_client_payments:create_payment(?config(context, Config), Req, ?STRING). @@ -2565,25 +2560,3 @@ get_trade_blocs_test(Config) -> ]}, capi_client_trade_blocs:get_trade_blocs(?config(context, Config)) ). - --spec check_support_decrypt_v2_test(config()) -> _. -check_support_decrypt_v2_test(_Config) -> - PaymentToolToken = << - "v2.eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTEyOEdDTSIsImVwayI6eyJhbGciOiJFQ0RILUVTIiwiY3J2IjoiUC0yNTYiLCJrdHkiOi" - "JFQyIsInVzZSI6ImVuYyIsIngiOiJRanFmNFVrOTJGNzd3WXlEUjNqY3NwR2dpYnJfdVRmSXpMUVplNzVQb1R3IiwieSI6InA5cjJGV3F" - "mU2xBTFJXYWhUSk8xY3VneVZJUXVvdzRwMGdHNzFKMFJkUVEifSwia2lkIjoia3hkRDBvclZQR29BeFdycUFNVGVRMFU1TVJvSzQ3dVp4" - "V2lTSmRnbzB0MCJ9..j3zEyCqyfQjpEtQM.JAc3kqJm6zbn0fMZGlK_t14Yt4PvgOuoVL2DtkEgIXIqrxxWFbykKBGxQvwYisJYIUJJwt" - "YbwvuGEODcK2uTC2quPD2Ejew66DLJF2xcAwE.MNVimzi8r-5uTATNalgoBQ" - >>, - {ok, #{payment_tool := PaymentTool, valid_until := ValidUntil}} = capi_crypto:decode_token(PaymentToolToken), - ?assertEqual( - {mobile_commerce, #domain_MobileCommerce{ - phone = #domain_MobilePhone{ - cc = <<"7">>, - ctn = <<"9210001122">> - }, - operator_deprecated = megafone - }}, - PaymentTool - ), - ?assertEqual(<<"2020-10-29T23:44:15.499Z">>, capi_utils:deadline_to_binary(ValidUntil)). diff --git a/apps/capi/test/capi_customer_access_token_tests_SUITE.erl b/apps/capi/test/capi_customer_access_token_tests_SUITE.erl index b288550..f09b119 100644 --- a/apps/capi/test/capi_customer_access_token_tests_SUITE.erl +++ b/apps/capi/test/capi_customer_access_token_tests_SUITE.erl @@ -20,6 +20,7 @@ -export([ get_customer_ok_test/1, create_binding_ok_test/1, + create_binding_fail_test/1, create_binding_expired_test/1, get_bindings_ok_test/1, get_binding_ok_test/1, @@ -48,6 +49,7 @@ customer_access_token_tests() -> [ get_customer_ok_test, create_binding_ok_test, + create_binding_fail_test, create_binding_expired_test, get_bindings_ok_test, get_binding_ok_test, @@ -162,7 +164,9 @@ create_binding_ok_test(Config) -> ], Config ), - PaymentToolToken = ?TEST_PAYMENT_TOKEN, + PaymentTool = {bank_card, ?BANK_CARD}, + ValidUntil = capi_utils:deadline_from_timeout(10000), + PaymentToolToken = capi_crypto:encode_token(#{payment_tool => PaymentTool, valid_until => ValidUntil}), Req2 = #{ <<"paymentResource">> => #{ <<"paymentSession">> => ?TEST_PAYMENT_SESSION, @@ -192,6 +196,24 @@ create_binding_expired_test(Config) -> Resp = capi_client_customers:create_binding(?config(context, Config), ?STRING, Req), {error, {400, #{<<"code">> := <<"invalidPaymentToolToken">>}}} = Resp. +-spec create_binding_fail_test(config()) -> _. +create_binding_fail_test(Config) -> + _ = capi_ct_helper:mock_services( + [ + {customer_management, fun('Get', _) -> {ok, ?CUSTOMER} end}, + {generator, fun('GenerateID', _) -> capi_ct_helper_bender:generate_id(<<"bender_key">>) end} + ], + Config + ), + Req = #{ + <<"paymentResource">> => #{ + <<"paymentSession">> => ?TEST_PAYMENT_SESSION, + <<"paymentToolToken">> => <<"wrongPaymentToolToken">> + } + }, + Resp = capi_client_customers:create_binding(?config(context, Config), ?STRING, Req), + {error, {400, #{<<"code">> := <<"invalidPaymentToolToken">>}}} = Resp. + -spec get_bindings_ok_test(config()) -> _. get_bindings_ok_test(Config) -> _ = capi_ct_helper:mock_services( diff --git a/apps/capi/test/capi_dummy_data.hrl b/apps/capi/test/capi_dummy_data.hrl index 526f37c..b10a266 100644 --- a/apps/capi/test/capi_dummy_data.hrl +++ b/apps/capi/test/capi_dummy_data.hrl @@ -189,17 +189,19 @@ invoice_lifetime = ?LIFETIME_INTERVAL }). --define(BANK_CARD, #domain_BankCard{ - token = ?STRING, - payment_system_deprecated = visa, +-define(BANK_CARD, ?BANK_CARD(<<"visa">>)). + +-define(BANK_CARD(PS), #domain_BankCard{ + token = PS, + payment_system = #domain_PaymentSystemRef{id = PS}, bin = <<"411111">>, last_digits = <<"411111******1111">> }). -define(BANK_CARD(PS, ExpDate, CardHolder), ?BANK_CARD(PS, ExpDate, CardHolder, undefined)). -define(BANK_CARD(PS, ExpDate, CardHolder, Category), #domain_BankCard{ - token = ?TEST_PAYMENT_TOKEN(PS), - payment_system_deprecated = PS, + token = PS, + payment_system = #domain_PaymentSystemRef{id = PS}, exp_date = ExpDate, cardholder_name = CardHolder, category = Category, @@ -1007,17 +1009,17 @@ -define(STAT_BANK_CARD, #merchstat_BankCard{ token = ?STRING, - payment_system_deprecated = visa, + payment_system = #domain_PaymentSystemRef{id = <<"visa">>}, bin = <<"411111">>, masked_pan = <<"411111******1111">> }). -define(STAT_BANK_CARD_WITH_TP, #merchstat_BankCard{ token = ?STRING, - payment_system_deprecated = visa, + payment_system = #domain_PaymentSystemRef{id = <<"visa">>}, bin = <<"411111">>, masked_pan = <<"411111******1111">>, - token_provider_deprecated = applepay + payment_token = #domain_BankCardTokenServiceRef{id = <<"APPLE PAY">>} }). -define(REPORT_TYPE, <<"paymentRegistry">>). @@ -1159,26 +1161,6 @@ }} } } - }}, - - {payment_system_legacy, #domain_LegacyBankCardPaymentSystemRef{id = visa}} => - {payment_system_legacy, #domain_LegacyBankCardPaymentSystemObject{ - ref = #domain_LegacyBankCardPaymentSystemRef{id = visa}, - data = #domain_PaymentSystemRef{id = <<"visa">>} - }}, - - {payment_system_legacy, #domain_LegacyBankCardPaymentSystemRef{id = mastercard}} => - {payment_system_legacy, #domain_LegacyBankCardPaymentSystemObject{ - ref = #domain_LegacyBankCardPaymentSystemRef{id = mastercard}, - data = #domain_PaymentSystemRef{id = <<"mastercard">>} - }}, - - {payment_service_legacy, #domain_LegacyDigitalWalletProviderRef{id = qiwi}} => - {payment_service_legacy, #domain_LegacyDigitalWalletProviderObject{ - ref = #domain_LegacyDigitalWalletProviderRef{id = qiwi}, - data = #domain_PaymentServiceRef{ - id = <<"qiwi">> - } }} } }). @@ -1225,68 +1207,62 @@ payment_methods = {value, ordsets:from_list([ - #domain_PaymentMethodRef{ - id = {bank_card_deprecated, mastercard} - }, - #domain_PaymentMethodRef{ - id = {bank_card_deprecated, visa} - }, - #domain_PaymentMethodRef{ - id = {crypto_currency_deprecated, bitcoin} - }, - #domain_PaymentMethodRef{ - id = {crypto_currency_deprecated, bitcoin_cash} - }, #domain_PaymentMethodRef{ id = - {tokenized_bank_card_deprecated, #domain_TokenizedBankCard{ - payment_system_deprecated = mastercard, - token_provider_deprecated = applepay - }} - }, - #domain_PaymentMethodRef{ - id = - {tokenized_bank_card_deprecated, #domain_TokenizedBankCard{ - payment_system_deprecated = visa, - token_provider_deprecated = applepay + {bank_card, #domain_BankCardPaymentMethod{ + payment_system = #domain_PaymentSystemRef{id = <<"mastercard">>} }} }, #domain_PaymentMethodRef{ id = {bank_card, #domain_BankCardPaymentMethod{ - payment_system_deprecated = mastercard, - token_provider_deprecated = applepay, + payment_system = #domain_PaymentSystemRef{id = <<"visa">>} + }} + }, + #domain_PaymentMethodRef{ + id = {crypto_currency, #domain_CryptoCurrencyRef{id = <<"bitcoin">>}} + }, + #domain_PaymentMethodRef{ + id = {crypto_currency, #domain_CryptoCurrencyRef{id = <<"bitcoin_cash">>}} + }, + #domain_PaymentMethodRef{ + id = + {bank_card, #domain_BankCardPaymentMethod{ + payment_system = #domain_PaymentSystemRef{id = <<"mastercard">>}, + payment_token = #domain_BankCardTokenServiceRef{id = <<"applepay">>} + }} + }, + #domain_PaymentMethodRef{ + id = + {bank_card, #domain_BankCardPaymentMethod{ + payment_system = #domain_PaymentSystemRef{id = <<"visa">>}, + payment_token = #domain_BankCardTokenServiceRef{id = <<"applepay">>} + }} + }, + #domain_PaymentMethodRef{ + id = + {bank_card, #domain_BankCardPaymentMethod{ + payment_system = #domain_PaymentSystemRef{id = <<"mastercard">>}, + payment_token = #domain_BankCardTokenServiceRef{id = <<"applepay">>}, tokenization_method = dpan }} }, #domain_PaymentMethodRef{ id = {bank_card, #domain_BankCardPaymentMethod{ - payment_system_deprecated = visa, - token_provider_deprecated = applepay, + payment_system = #domain_PaymentSystemRef{id = <<"visa">>}, + payment_token = #domain_BankCardTokenServiceRef{id = <<"applepay">>}, tokenization_method = dpan }} }, #domain_PaymentMethodRef{ - id = - {bank_card, #domain_BankCardPaymentMethod{ - payment_system_deprecated = mastercard - }} + id = {digital_wallet, #domain_PaymentServiceRef{id = <<"qiwi">>}} }, #domain_PaymentMethodRef{ - id = - {bank_card, #domain_BankCardPaymentMethod{ - payment_system_deprecated = visa - }} + id = {mobile, #domain_MobileOperatorRef{id = <<"tele2">>}} }, #domain_PaymentMethodRef{ - id = {digital_wallet_deprecated, qiwi} - }, - #domain_PaymentMethodRef{ - id = {mobile_deprecated, tele2} - }, - #domain_PaymentMethodRef{ - id = {payment_terminal_deprecated, euroset} + id = {payment_terminal, #domain_PaymentServiceRef{id = <<"euroset">>}} } ])} }). @@ -1334,21 +1310,14 @@ } }). --define(TEST_PAYMENT_TOKEN, ?TEST_PAYMENT_TOKEN(visa)). --define(TEST_PAYMENT_TOKEN(PaymentSystem), - ?TEST_PAYMENT_TOKEN(PaymentSystem, ?STRING) -). +-define(TEST_PAYMENT_TOKEN, ?STRING). --define(TEST_PAYMENT_TOKEN(PaymentSystem, Token), - capi_utils:map_to_base64url(?TEST_PAYMENT_TOOL(PaymentSystem, Token)) -). - --define(TEST_PAYMENT_TOOL, ?TEST_PAYMENT_TOOL(visa)). +-define(TEST_PAYMENT_TOOL, ?TEST_PAYMENT_TOOL(<<"visa">>)). -define(TEST_PAYMENT_TOOL(PaymentSystem), ?TEST_PAYMENT_TOOL(PaymentSystem, ?STRING)). -define(TEST_PAYMENT_TOOL(PaymentSystem, Token), #{ <<"type">> => <<"bank_card">>, <<"token">> => Token, - <<"payment_system">> => atom_to_binary(PaymentSystem, utf8), + <<"payment_system">> => PaymentSystem, <<"bin">> => <<"411111">>, <<"masked_pan">> => <<"1111">>, <<"exp_date">> => <<"12/2012">> diff --git a/apps/capi/test/capi_idempotency_tests_SUITE.erl b/apps/capi/test/capi_idempotency_tests_SUITE.erl index 121a739..9a654ea 100644 --- a/apps/capi/test/capi_idempotency_tests_SUITE.erl +++ b/apps/capi/test/capi_idempotency_tests_SUITE.erl @@ -202,8 +202,8 @@ create_payment_ok_test(Config) -> BenderKey = <<"bender_key">>, ExternalID = <<"merch_id">>, ContactInfo = #{}, - Jwe1 = get_encrypted_token(visa, ?EXP_DATE(2, 2020)), - Jwe2 = get_encrypted_token(visa, ?EXP_DATE(2, 2020)), + Jwe1 = get_encrypted_token(<<"visa">>, ?EXP_DATE(2, 2020)), + Jwe2 = get_encrypted_token(<<"visa">>, ?EXP_DATE(2, 2020)), Req1 = payment_params(ExternalID, Jwe1, ContactInfo, undefined), Req2 = payment_params(ExternalID, Jwe2, ContactInfo, false), [ @@ -231,8 +231,8 @@ create_payment_ok_test(Config) -> create_payment_fail_test(Config) -> BenderKey = <<"bender_key">>, ExternalID = <<"merch_id">>, - Jwe1 = get_encrypted_token(visa, ?EXP_DATE(1, 2020)), - Jwe2 = get_encrypted_token(visa, ?EXP_DATE(2, 2020)), + Jwe1 = get_encrypted_token(<<"visa">>, ?EXP_DATE(1, 2020)), + Jwe2 = get_encrypted_token(<<"visa">>, ?EXP_DATE(2, 2020)), Req1 = payment_params(ExternalID, Jwe1, #{}, undefined), Req2 = payment_params(ExternalID, Jwe2, #{}, false), [ @@ -246,7 +246,7 @@ different_payment_tools_test(Config) -> BenderKey = <<"bender_key">>, ExternalID = <<"merch_id">>, ContactInfo = #{}, - Jwe1 = encrypt_payment_tool({bank_card, ?BANK_CARD(visa, ?EXP_DATE(2, 2020), <<"Mr. Surname">>)}), + Jwe1 = encrypt_payment_tool({bank_card, ?BANK_CARD(<<"visa">>, ?EXP_DATE(2, 2020), <<"Mr. Surname">>)}), Jwe2 = encrypt_payment_tool({digital_wallet, ?DIGITAL_WALLET(<<"qiwi">>, <<"+79876543210">>, <<"token">>)}), Req1 = payment_params(ExternalID, Jwe1, ContactInfo, undefined), Req2 = payment_params(ExternalID, Jwe2, ContactInfo, false), @@ -272,8 +272,8 @@ second_request_without_idempotent_feature_test(Config) -> BenderKey = <<"bender_key">>, ExternalID = <<"merch_id">>, ContactInfo = #{}, - Jwe1 = encrypt_payment_tool({bank_card, ?BANK_CARD(visa, ?EXP_DATE(2, 2020), <<"Mr. Surname">>)}), - Jwe2 = encrypt_payment_tool({bank_card, ?BANK_CARD(visa, undefined, <<"Mr. Surname">>)}), + Jwe1 = encrypt_payment_tool({bank_card, ?BANK_CARD(<<"visa">>, ?EXP_DATE(2, 2020), <<"Mr. Surname">>)}), + Jwe2 = encrypt_payment_tool({bank_card, ?BANK_CARD(<<"visa">>, undefined, <<"Mr. Surname">>)}), Req1 = payment_params(ExternalID, Jwe1, ContactInfo, undefined), Req2 = payment_params(ExternalID, Jwe2, ContactInfo, undefined), [ @@ -286,8 +286,8 @@ second_request_without_idempotent_feature_test(Config) -> second_request_with_idempotent_feature_test(Config) -> BenderKey = <<"bender_key">>, ExternalID = <<"merch_id">>, - Jwe1 = encrypt_payment_tool({bank_card, ?BANK_CARD(visa, ?EXP_DATE(2, 2020), undefined)}), - Jwe2 = encrypt_payment_tool({bank_card, ?BANK_CARD(visa, ?EXP_DATE(2, 2020), <<"Mr. Surname">>)}), + Jwe1 = encrypt_payment_tool({bank_card, ?BANK_CARD(<<"visa">>, ?EXP_DATE(2, 2020), undefined)}), + Jwe2 = encrypt_payment_tool({bank_card, ?BANK_CARD(<<"visa">>, ?EXP_DATE(2, 2020), <<"Mr. Surname">>)}), Req1 = payment_params(ExternalID, Jwe1, #{}, undefined), Req2 = payment_params(ExternalID, Jwe2, #{}, undefined), [ @@ -687,11 +687,14 @@ create_customer_fail_test(Config) -> -spec create_customer_binding_ok_test(config()) -> _. create_customer_binding_ok_test(Config) -> BenderKey = <<"customer_binding_bender_key">>, + PaymentTool = {bank_card, ?BANK_CARD}, + ValidUntil = capi_utils:deadline_from_timeout(10000), + PaymentToolToken = capi_crypto:encode_token(#{payment_tool => PaymentTool, valid_until => ValidUntil}), Req1 = #{ <<"externalID">> => genlib:unique(), <<"paymentResource">> => #{ <<"paymentSession">> => ?TEST_PAYMENT_SESSION, - <<"paymentToolToken">> => ?TEST_PAYMENT_TOKEN + <<"paymentToolToken">> => PaymentToolToken } }, Req2 = Req1#{<<"externalID">> => genlib:unique()}, @@ -712,17 +715,23 @@ create_customer_binding_ok_test(Config) -> create_customer_binding_fail_test(Config) -> BenderKey = <<"customer_binding_bender_key">>, ExternalID = genlib:unique(), + PaymentTool1 = {bank_card, ?BANK_CARD}, + ValidUntil1 = capi_utils:deadline_from_timeout(10000), + PaymentToolToken1 = capi_crypto:encode_token(#{payment_tool => PaymentTool1, valid_until => ValidUntil1}), Req1 = #{ <<"externalID">> => ExternalID, <<"paymentResource">> => #{ <<"paymentSession">> => ?TEST_PAYMENT_SESSION, - <<"paymentToolToken">> => ?TEST_PAYMENT_TOKEN(visa, <<"TOKEN1">>) + <<"paymentToolToken">> => PaymentToolToken1 } }, + PaymentTool2 = {bank_card, ?BANK_CARD(<<"mastercard">>)}, + ValidUntil2 = capi_utils:deadline_from_timeout(10000), + PaymentToolToken2 = capi_crypto:encode_token(#{payment_tool => PaymentTool2, valid_until => ValidUntil2}), Req2 = Req1#{ <<"paymentResource">> => #{ <<"paymentSession">> => ?TEST_PAYMENT_SESSION, - <<"paymentToolToken">> => ?TEST_PAYMENT_TOKEN(mastercard, <<"TOKEN2">>) + <<"paymentToolToken">> => PaymentToolToken2 } }, @@ -855,8 +864,8 @@ get_encrypted_token(PS, ExpDate) -> get_encrypted_token(PS, ExpDate, IsCvvEmpty) -> encrypt_payment_tool( {bank_card, #domain_BankCard{ - token = ?TEST_PAYMENT_TOKEN(PS), - payment_system_deprecated = PS, + token = ?TEST_PAYMENT_TOKEN, + payment_system = #domain_PaymentSystemRef{id = PS}, bin = <<"411111">>, last_digits = <<"1111">>, exp_date = ExpDate, diff --git a/apps/capi/test/capi_invoice_access_token_tests_SUITE.erl b/apps/capi/test/capi_invoice_access_token_tests_SUITE.erl index c75d77b..1e15469 100644 --- a/apps/capi/test/capi_invoice_access_token_tests_SUITE.erl +++ b/apps/capi/test/capi_invoice_access_token_tests_SUITE.erl @@ -297,7 +297,7 @@ create_payment_ok_test(Config) -> ?STRING, Config ), - PaymentToolToken = get_encrypted_token(visa, ?EXP_DATE(2, 2020)), + PaymentToolToken = get_encrypted_token(<<"visa">>, ?EXP_DATE(2, 2020)), Req = ?PAYMENT_PARAMS(ExternalID, PaymentToolToken), {ok, #{ <<"id">> := BenderKey, @@ -383,7 +383,7 @@ create_payment_with_empty_cvv_ok_test(Config) -> ?STRING, Config ), - PaymentToolToken = get_encrypted_token(visa, ?EXP_DATE(1, 2020), true), + PaymentToolToken = get_encrypted_token(<<"visa">>, ?EXP_DATE(1, 2020), true), Req2 = #{ <<"flow">> => #{<<"type">> => <<"PaymentFlowInstant">>}, <<"payer">> => #{ @@ -464,8 +464,7 @@ create_payment_with_googlepay_encrypt_ok_test(Config) -> bank_card, #domain_BankCard{ is_cvv_empty = undefined, - token_provider_deprecated = undefined, - payment_system_deprecated = mastercard + payment_system = #domain_PaymentSystemRef{id = <<"mastercard">>} } } } @@ -486,7 +485,7 @@ create_payment_with_googlepay_encrypt_ok_test(Config) -> ?STRING, Config ), - PaymentToolToken = get_encrypted_token(mastercard, ?EXP_DATE(1, 2020)), + PaymentToolToken = get_encrypted_token(<<"mastercard">>, ?EXP_DATE(1, 2020)), Req2 = #{ <<"flow">> => #{<<"type">> => <<"PaymentFlowInstant">>}, <<"payer">> => #{ @@ -666,7 +665,7 @@ create_first_recurrent_payment_ok_test(Config) -> ], Config ), - PaymentToolToken = get_encrypted_token(visa, ?EXP_DATE(1, 2020)), + PaymentToolToken = get_encrypted_token(<<"visa">>, ?EXP_DATE(1, 2020)), Req2 = #{ <<"flow">> => #{<<"type">> => <<"PaymentFlowInstant">>}, <<"makeRecurrent">> => true, @@ -784,8 +783,8 @@ get_encrypted_token(PS, ExpDate) -> get_encrypted_token(PS, ExpDate, IsCvvEmpty) -> PaymentTool = {bank_card, #domain_BankCard{ - token = ?TEST_PAYMENT_TOKEN(PS), - payment_system_deprecated = PS, + token = ?TEST_PAYMENT_TOKEN, + payment_system = #domain_PaymentSystemRef{id = PS}, bin = <<"411111">>, last_digits = <<"1111">>, exp_date = ExpDate, diff --git a/rebar.config b/rebar.config index abc9eef..0bc63d3 100644 --- a/rebar.config +++ b/rebar.config @@ -48,7 +48,7 @@ {bouncer_proto, {git, "https://github.com/valitydev/bouncer-proto.git", {branch, master}}}, {bouncer_client, {git, "https://github.com/valitydev/bouncer-client-erlang.git", {branch, master}}}, {token_keeper_client, {git, "https://github.com/valitydev/token-keeper-client.git", {branch, master}}}, - {party_client, {git, "https://github.com/valitydev/party_client_erlang.git", {branch, master}}}, + {party_client, {git, "https://github.com/valitydev/party-client-erlang.git", {branch, master}}}, {payout_manager_proto, {git, "https://github.com/valitydev/payout-manager-proto.git", {branch, master}}}, {feat, {git, "https://github.com/valitydev/feat.git", {branch, master}}}, %% Libraries generated with swagger-codegen-erlang from valitydev/swag-payments diff --git a/rebar.lock b/rebar.lock index c3b1231..5975ea1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -92,8 +92,8 @@ 1}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.4.1">>},1}, {<<"party_client">>, - {git,"https://github.com/valitydev/party_client_erlang.git", - {ref,"8fc5595c4c61c0fe3d2dc29a61f48ba94e9bdef7"}}, + {git,"https://github.com/valitydev/party-client-erlang.git", + {ref,"602d4dc87b54d2bf899ae36462853f7d7eb014ae"}}, 0}, {<<"payout_manager_proto">>, {git,"https://github.com/valitydev/payout-manager-proto.git",