mirror of
https://github.com/valitydev/fistful-server.git
synced 2024-11-06 10:45:21 +00:00
FF-166: Auth data (#198)
* added auth data to resources * updated swag * added auth data * fixed linter * added migration * fixed * fixed * fixed
This commit is contained in:
parent
08e1437565
commit
22edaa0b4f
@ -123,7 +123,17 @@ marshal(account, #{
|
||||
accounter_account_id = marshal(event_id, AAID)
|
||||
};
|
||||
|
||||
marshal(resource, {bank_card, BankCard = #{token := Token}}) ->
|
||||
marshal(resource, {bank_card, #{bank_card := BankCard} = ResourceBankCard}) ->
|
||||
{bank_card, #'ResourceBankCard'{
|
||||
bank_card = marshal(bank_card, BankCard),
|
||||
auth_data = maybe_marshal(bank_card_auth_data, maps:get(auth_data, ResourceBankCard, undefined))
|
||||
}};
|
||||
marshal(resource, {crypto_wallet, #{crypto_wallet := CryptoWallet}}) ->
|
||||
{crypto_wallet, #'ResourceCryptoWallet'{
|
||||
crypto_wallet = marshal(crypto_wallet, CryptoWallet)
|
||||
}};
|
||||
|
||||
marshal(bank_card, BankCard = #{token := Token}) ->
|
||||
Bin = maps:get(bin, BankCard, undefined),
|
||||
PaymentSystem = maps:get(payment_system, BankCard, undefined),
|
||||
MaskedPan = maps:get(masked_pan, BankCard, undefined),
|
||||
@ -132,7 +142,7 @@ marshal(resource, {bank_card, BankCard = #{token := Token}}) ->
|
||||
CardType = maps:get(card_type, BankCard, undefined),
|
||||
ExpDate = maps:get(exp_date, BankCard, undefined),
|
||||
BinDataID = maps:get(bin_data_id, BankCard, undefined),
|
||||
{bank_card, #'BankCard'{
|
||||
#'BankCard'{
|
||||
token = marshal(string, Token),
|
||||
bin = marshal(string, Bin),
|
||||
masked_pan = marshal(string, MaskedPan),
|
||||
@ -142,13 +152,19 @@ marshal(resource, {bank_card, BankCard = #{token := Token}}) ->
|
||||
card_type = CardType,
|
||||
exp_date = maybe_marshal(exp_date, ExpDate),
|
||||
bin_data_id = marshal_msgpack(BinDataID)
|
||||
};
|
||||
|
||||
marshal(bank_card_auth_data, {session, #{session_id := ID}}) ->
|
||||
{session_data, #'SessionAuthData'{
|
||||
id = marshal(string, ID)
|
||||
}};
|
||||
marshal(resource, {crypto_wallet, #{id := ID, currency := Currency}}) ->
|
||||
{crypto_wallet, #'CryptoWallet'{
|
||||
|
||||
marshal(crypto_wallet, #{id := ID, currency := Currency}) ->
|
||||
#'CryptoWallet'{
|
||||
id = marshal(string, ID),
|
||||
currency = marshal(crypto_currency, Currency),
|
||||
data = marshal(crypto_data, Currency)
|
||||
}};
|
||||
};
|
||||
|
||||
marshal(exp_date, {Month, Year}) ->
|
||||
#'BankCardExpDate'{
|
||||
@ -343,10 +359,23 @@ unmarshal(account, #'account_Account'{
|
||||
unmarshal(accounter_account_id, V) ->
|
||||
unmarshal(integer, V);
|
||||
|
||||
unmarshal(resource, {bank_card, BankCard}) ->
|
||||
{bank_card, unmarshal(bank_card, BankCard)};
|
||||
unmarshal(resource, {crypto_wallet, CryptoWallet}) ->
|
||||
{crypto_wallet, unmarshal(crypto_wallet, CryptoWallet)};
|
||||
unmarshal(resource, {bank_card, #'ResourceBankCard'{
|
||||
bank_card = BankCard,
|
||||
auth_data = AuthData
|
||||
}}) ->
|
||||
{bank_card, genlib_map:compact(#{
|
||||
bank_card => unmarshal(bank_card, BankCard),
|
||||
auth_data => maybe_unmarshal(bank_card_auth_data, AuthData)
|
||||
})};
|
||||
unmarshal(resource, {crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = CryptoWallet}}) ->
|
||||
{crypto_wallet, #{
|
||||
crypto_wallet => unmarshal(crypto_wallet, CryptoWallet)
|
||||
}};
|
||||
|
||||
unmarshal(bank_card_auth_data, {session_data, #'SessionAuthData'{id = ID}}) ->
|
||||
#{
|
||||
session_id => unmarshal(string, ID)
|
||||
};
|
||||
|
||||
unmarshal(bank_card, #'BankCard'{
|
||||
token = Token,
|
||||
|
@ -129,9 +129,9 @@ maybe_unmarshal(Type, Value) ->
|
||||
|
||||
-spec destination_test() -> _.
|
||||
destination_test() ->
|
||||
Resource = {bank_card, #{
|
||||
Resource = {bank_card, #{bank_card => #{
|
||||
token => <<"token auth">>
|
||||
}},
|
||||
}}},
|
||||
AAID = 12345,
|
||||
AccountID = genlib:unique(),
|
||||
In = #{
|
||||
@ -152,10 +152,10 @@ destination_test() ->
|
||||
|
||||
-spec crypto_wallet_resource_test() -> _.
|
||||
crypto_wallet_resource_test() ->
|
||||
Resource = {crypto_wallet, #{
|
||||
Resource = {crypto_wallet, #{crypto_wallet => #{
|
||||
id => <<"9e6245a7a6e15f75769a4d87183b090a">>,
|
||||
currency => {bitcoin, #{}}
|
||||
}},
|
||||
}}},
|
||||
?assertEqual(Resource, unmarshal(resource, marshal(resource, Resource))).
|
||||
|
||||
-endif.
|
||||
|
@ -309,10 +309,10 @@ p2p_session_codec_test() ->
|
||||
extra => <<"Extra">>
|
||||
},
|
||||
|
||||
Resource = {bank_card, #{
|
||||
Resource = {bank_card, #{bank_card => #{
|
||||
token => <<"token">>,
|
||||
payment_system => visa
|
||||
}},
|
||||
}}},
|
||||
|
||||
TransferParams = #{
|
||||
id => genlib:unique(),
|
||||
|
@ -73,10 +73,10 @@ marshal(quote, #{}) ->
|
||||
marshal(status, Status) ->
|
||||
ff_p2p_transfer_status_codec:marshal(status, Status);
|
||||
|
||||
marshal(participant, {raw, #{resource_params := Resource} = Raw}) ->
|
||||
marshal(participant, {raw, #{resource_params := ResourceParams} = Raw}) ->
|
||||
ContactInfo = maps:get(contact_info, Raw, undefined),
|
||||
{resource, #p2p_transfer_RawResource{
|
||||
resource = marshal(resource, Resource),
|
||||
resource = marshal(resource, ResourceParams),
|
||||
contact_info = marshal(contact_info, ContactInfo)
|
||||
}};
|
||||
|
||||
@ -314,10 +314,10 @@ p2p_transfer_codec_test() ->
|
||||
external_id => genlib:unique()
|
||||
},
|
||||
|
||||
Resource = {bank_card, #{
|
||||
Resource = {bank_card, #{bank_card => #{
|
||||
token => genlib:unique(),
|
||||
bin_data_id => {binary, genlib:unique()}
|
||||
}},
|
||||
}}},
|
||||
|
||||
Participant = {raw, #{
|
||||
resource_params => Resource,
|
||||
|
@ -77,29 +77,29 @@ end_per_testcase(_Name, _C) ->
|
||||
-spec create_bank_card_destination_ok(config()) -> test_return().
|
||||
|
||||
create_bank_card_destination_ok(C) ->
|
||||
Resource = {bank_card, #'BankCard'{
|
||||
Resource = {bank_card, #'ResourceBankCard'{bank_card = #'BankCard'{
|
||||
token = <<"TOKEN shmOKEN">>
|
||||
}},
|
||||
}}},
|
||||
create_destination_ok(Resource, C).
|
||||
|
||||
-spec create_crypto_wallet_destination_ok(config()) -> test_return().
|
||||
|
||||
create_crypto_wallet_destination_ok(C) ->
|
||||
Resource = {crypto_wallet, #'CryptoWallet'{
|
||||
Resource = {crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{
|
||||
id = <<"f195298af836f41d072cb390ee62bee8">>,
|
||||
currency = bitcoin_cash,
|
||||
data = {bitcoin_cash, #'CryptoDataBitcoinCash'{}}
|
||||
}},
|
||||
}}},
|
||||
create_destination_ok(Resource, C).
|
||||
|
||||
-spec create_ripple_wallet_destination_ok(config()) -> test_return().
|
||||
|
||||
create_ripple_wallet_destination_ok(C) ->
|
||||
Resource = {crypto_wallet, #'CryptoWallet'{
|
||||
Resource = {crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{
|
||||
id = <<"ab843336bf7738dc697522fbb90508de">>,
|
||||
currency = ripple,
|
||||
data = {ripple, #'CryptoDataRipple'{tag = undefined}}
|
||||
}},
|
||||
}}},
|
||||
create_destination_ok(Resource, C).
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
|
@ -275,11 +275,11 @@ get_create_p2p_transfer_events_ok(C) ->
|
||||
Sink = p2p_transfer_event_sink,
|
||||
LastEvent = ct_eventsink:last_id(Sink),
|
||||
|
||||
Resource = {bank_card, #{
|
||||
Resource = {bank_card, #{bank_card => #{
|
||||
token => genlib:unique(),
|
||||
bin => <<"some bin">>,
|
||||
masked_pan => <<"some masked_pan">>
|
||||
}},
|
||||
}}},
|
||||
|
||||
Participant = {raw, #{
|
||||
resource_params => Resource,
|
||||
@ -411,7 +411,7 @@ process_deposit(SrcID, WalID) ->
|
||||
DepID.
|
||||
|
||||
create_destination(IID, C) ->
|
||||
DestResource = {bank_card, ct_cardstore:bank_card(<<"4150399999000900">>, {12, 2025}, C)},
|
||||
DestResource = {bank_card, #{bank_card => ct_cardstore:bank_card(<<"4150399999000900">>, {12, 2025}, C)}},
|
||||
DestID = create_instrument(destination, IID, <<"XDesination">>, <<"RUB">>, DestResource, C),
|
||||
authorized = ct_helper:await(
|
||||
authorized,
|
||||
|
@ -537,7 +537,7 @@ create_destination(IID, Currency, Token, C) ->
|
||||
Token ->
|
||||
StoreSource#{token => Token}
|
||||
end,
|
||||
Resource = {bank_card, NewStoreResource},
|
||||
Resource = {bank_card, #{bank_card => NewStoreResource}},
|
||||
Params = #{id => ID, identity => IID, name => <<"XDesination">>, currency => Currency, resource => Resource},
|
||||
ok = ff_destination:create(Params, ff_entity_context:new()),
|
||||
authorized = ct_helper:await(
|
||||
|
@ -139,7 +139,7 @@ create_identity(Party, ProviderID, ClassID, _C) ->
|
||||
ID.
|
||||
|
||||
create_destination(IID, C) ->
|
||||
DestResource = {bank_card, ct_cardstore:bank_card(<<"4150399999000900">>, {12, 2025}, C)},
|
||||
DestResource = {bank_card, #{bank_card => ct_cardstore:bank_card(<<"4150399999000900">>, {12, 2025}, C)}},
|
||||
DestID = create_instrument(destination, IID, <<"XDesination">>, <<"RUB">>, DestResource, C),
|
||||
authorized = ct_helper:await(
|
||||
authorized,
|
||||
|
@ -199,12 +199,12 @@ encode_currency(#{
|
||||
|
||||
-spec encode_resource(resource()) -> domain_destination().
|
||||
encode_resource(
|
||||
{bank_card, #{
|
||||
{bank_card, #{bank_card := #{
|
||||
token := Token,
|
||||
payment_system := PaymentSystem,
|
||||
bin := BIN,
|
||||
masked_pan := LastDigits
|
||||
} = BankCard}
|
||||
} = BankCard}}
|
||||
) ->
|
||||
CardHolderName = genlib_map:get(cardholder_name, BankCard),
|
||||
ExpDate = genlib_map:get(exp_date, BankCard),
|
||||
@ -217,10 +217,10 @@ encode_resource(
|
||||
exp_date = encode_exp_date(ExpDate)
|
||||
}};
|
||||
encode_resource(
|
||||
{crypto_wallet, #{
|
||||
{crypto_wallet, #{crypto_wallet := #{
|
||||
id := CryptoWalletID,
|
||||
currency := {Currency, Data}
|
||||
}}
|
||||
}}}
|
||||
) ->
|
||||
{crypto_wallet, #domain_CryptoWallet{
|
||||
id = CryptoWalletID,
|
||||
|
@ -22,7 +22,7 @@
|
||||
{bank_card, resource_bank_card()} |
|
||||
{crypto_wallet, resource_crypto_wallet()}.
|
||||
|
||||
-type resource_full_id() ::
|
||||
-type full_bank_card_id() ::
|
||||
#{binary() => ff_bin_data:bin_data_id()}.
|
||||
|
||||
-type resource_full() ::
|
||||
@ -30,6 +30,11 @@
|
||||
{crypto_wallet, resource_crypto_wallet()}.
|
||||
|
||||
-type resource_full_bank_card() :: #{
|
||||
bank_card := full_bank_card(),
|
||||
auth_data => bank_card_auth_data()
|
||||
}.
|
||||
|
||||
-type full_bank_card() :: #{
|
||||
token := binary(),
|
||||
bin => binary(),
|
||||
payment_system := atom(), % TODO
|
||||
@ -43,16 +48,32 @@
|
||||
}.
|
||||
|
||||
-type resource_bank_card() :: #{
|
||||
token := binary(),
|
||||
bin => binary(),
|
||||
masked_pan => binary(),
|
||||
bank_card := bank_card(),
|
||||
auth_data => bank_card_auth_data()
|
||||
}.
|
||||
|
||||
-type bank_card() :: #{
|
||||
token := binary(),
|
||||
bin => binary(),
|
||||
masked_pan => binary(),
|
||||
cardholder_name => binary(),
|
||||
exp_date => exp_date()
|
||||
exp_date => exp_date()
|
||||
}.
|
||||
|
||||
-type bank_card_auth_data() ::
|
||||
{session, session_auth_data()}.
|
||||
|
||||
-type session_auth_data() :: #{
|
||||
session_id := binary()
|
||||
}.
|
||||
|
||||
-type exp_date() :: {integer(), integer()}.
|
||||
|
||||
-type resource_crypto_wallet() :: #{
|
||||
crypto_wallet := crypto_wallet()
|
||||
}.
|
||||
|
||||
-type crypto_wallet() :: #{
|
||||
id := binary(),
|
||||
currency := crypto_currency()
|
||||
}.
|
||||
@ -80,7 +101,7 @@
|
||||
-export_type([resource/0]).
|
||||
-export_type([resource_type/0]).
|
||||
-export_type([resource_full/0]).
|
||||
-export_type([resource_full_id/0]).
|
||||
-export_type([full_bank_card_id/0]).
|
||||
-export_type([event/0]).
|
||||
-export_type([params/0]).
|
||||
-export_type([exp_date/0]).
|
||||
@ -97,7 +118,7 @@
|
||||
-export([external_id/1]).
|
||||
-export([resource_full/1]).
|
||||
-export([resource_full/2]).
|
||||
-export([resource_full_id/1]).
|
||||
-export([full_bank_card_id/1]).
|
||||
|
||||
%% API
|
||||
|
||||
@ -145,7 +166,7 @@ external_id(T) -> ff_instrument:external_id(T).
|
||||
resource_full(Destination) ->
|
||||
resource_full(Destination, undefined).
|
||||
|
||||
-spec resource_full(destination(), resource_full_id() | undefined) ->
|
||||
-spec resource_full(destination(), full_bank_card_id() | undefined) ->
|
||||
{ok, resource_full()} |
|
||||
{error,
|
||||
{bin_data, not_found}
|
||||
@ -154,23 +175,25 @@ resource_full(Destination) ->
|
||||
resource_full(Destination, ResourceID) ->
|
||||
do(fun() ->
|
||||
case resource(Destination) of
|
||||
{bank_card, #{token := Token} = BankCard} ->
|
||||
{bank_card, #{bank_card := #{token := Token} = BankCard} = Resource} ->
|
||||
UnwrappedResourceID = unwrap_resource_id(ResourceID),
|
||||
BinData = unwrap(bin_data, ff_bin_data:get(Token, UnwrappedResourceID)),
|
||||
KeyList = [payment_system, bank_name, iso_country_code, card_type],
|
||||
ExtendData = maps:with(KeyList, BinData),
|
||||
{bank_card, maps:merge(BankCard, ExtendData#{bin_data_id => ff_bin_data:id(BinData)})};
|
||||
{bank_card, Resource#{
|
||||
bank_card => maps:merge(BankCard, ExtendData#{bin_data_id => ff_bin_data:id(BinData)})
|
||||
}};
|
||||
{crypto_wallet, _CryptoWallet} = Resource ->
|
||||
Resource
|
||||
end
|
||||
end).
|
||||
|
||||
-spec resource_full_id(resource_full() | undefined) ->
|
||||
resource_full_id() | undefined.
|
||||
-spec full_bank_card_id(resource_full() | undefined) ->
|
||||
full_bank_card_id() | undefined.
|
||||
|
||||
resource_full_id({bank_card, #{bin_data_id := ID}}) ->
|
||||
full_bank_card_id({bank_card, #{bank_card := #{bin_data_id := ID}}}) ->
|
||||
#{<<"bank_card">> => ID};
|
||||
resource_full_id(_) ->
|
||||
full_bank_card_id(_) ->
|
||||
undefined.
|
||||
|
||||
unwrap_resource_id(undefined) ->
|
||||
|
@ -59,6 +59,7 @@
|
||||
|
||||
-export([apply_event/2]).
|
||||
-export([maybe_migrate/1]).
|
||||
-export([maybe_migrate_resource/1]).
|
||||
|
||||
%% Pipeline
|
||||
|
||||
@ -198,9 +199,18 @@ maybe_migrate({created, Instrument = #{
|
||||
maybe_migrate(Event) ->
|
||||
Event.
|
||||
|
||||
-spec maybe_migrate_resource(any()) ->
|
||||
any().
|
||||
|
||||
maybe_migrate_resource({crypto_wallet, #{id := ID, currency := ripple, tag := Tag}}) ->
|
||||
{crypto_wallet, #{id => ID, currency => {ripple, #{tag => Tag}}}};
|
||||
maybe_migrate_resource({crypto_wallet, #{id => ID, currency => {ripple, #{tag => Tag}}}});
|
||||
maybe_migrate_resource({crypto_wallet, #{id := ID, currency := Currency}}) when is_atom(Currency) ->
|
||||
{crypto_wallet, #{id => ID, currency => {Currency, #{}}}};
|
||||
maybe_migrate_resource({crypto_wallet, #{id => ID, currency => {Currency, #{}}}});
|
||||
|
||||
maybe_migrate_resource({crypto_wallet, #{id := _ID} = CryptoWallet}) ->
|
||||
maybe_migrate_resource({crypto_wallet, #{crypto_wallet => CryptoWallet}});
|
||||
maybe_migrate_resource({bank_card, #{token := _Token} = BankCard}) ->
|
||||
maybe_migrate_resource({bank_card, #{bank_card => BankCard}});
|
||||
|
||||
maybe_migrate_resource(Resource) ->
|
||||
Resource.
|
||||
|
@ -35,8 +35,7 @@
|
||||
destination_id := ff_destination:id(),
|
||||
body := body(),
|
||||
external_id => id(),
|
||||
quote => quote(),
|
||||
destination_resource => destination_resource()
|
||||
quote => quote()
|
||||
}.
|
||||
|
||||
-type status() ::
|
||||
@ -980,7 +979,7 @@ build_party_varset(#{body := Body, wallet_id := WalletID, party_id := PartyID} =
|
||||
|
||||
-spec construct_payment_tool(ff_destination:resource_full() | ff_destination:resource()) ->
|
||||
dmsl_domain_thrift:'PaymentTool'().
|
||||
construct_payment_tool({bank_card, ResourceBankCard}) ->
|
||||
construct_payment_tool({bank_card, #{bank_card := ResourceBankCard}}) ->
|
||||
{bank_card, #domain_BankCard{
|
||||
token = maps:get(token, ResourceBankCard),
|
||||
bin = maps:get(bin, ResourceBankCard),
|
||||
@ -990,7 +989,7 @@ construct_payment_tool({bank_card, ResourceBankCard}) ->
|
||||
bank_name = maps:get(bank_name, ResourceBankCard, undefined)
|
||||
}};
|
||||
|
||||
construct_payment_tool({crypto_wallet, #{currency := {Currency, _}}}) ->
|
||||
construct_payment_tool({crypto_wallet, #{crypto_wallet := #{currency := {Currency, _}}}}) ->
|
||||
{crypto_currency, Currency}.
|
||||
|
||||
%% Quote helpers
|
||||
@ -1058,7 +1057,7 @@ get_quote_(Params, Destination, Resource) ->
|
||||
Quote :: ff_adapter_withdrawal:quote().
|
||||
wrap_quote(DomainRevision, PartyRevision, Timestamp, Resource, ProviderID, Quote) ->
|
||||
#{quote_data := QuoteData} = Quote,
|
||||
ResourceID = ff_destination:resource_full_id(Resource),
|
||||
ResourceID = ff_destination:full_bank_card_id(Resource),
|
||||
Quote#{quote_data := genlib_map:compact(#{
|
||||
<<"version">> => 1,
|
||||
<<"quote_data">> => QuoteData,
|
||||
@ -1485,6 +1484,9 @@ maybe_migrate({p_transfer, PEvent}) ->
|
||||
{p_transfer, ff_postings_transfer:maybe_migrate(PEvent, withdrawal)};
|
||||
maybe_migrate({adjustment, _Payload} = Event) ->
|
||||
ff_adjustment_utils:maybe_migrate(Event);
|
||||
maybe_migrate({resource_got, Resource}) ->
|
||||
{resource_got, ff_instrument:maybe_migrate_resource(Resource)};
|
||||
|
||||
% Old events
|
||||
maybe_migrate({limit_check, {wallet, Details}}) ->
|
||||
maybe_migrate({limit_check, {wallet_sender, Details}});
|
||||
|
@ -460,7 +460,7 @@ process_deposit(SrcID, WalID) ->
|
||||
ok = await_wallet_balance({10000, <<"RUB">>}, WalID).
|
||||
|
||||
create_destination(IID, C) ->
|
||||
DestResource = {bank_card, ct_cardstore:bank_card(<<"4150399999000900">>, {12, 2025}, C)},
|
||||
DestResource = {bank_card, #{bank_card => ct_cardstore:bank_card(<<"4150399999000900">>, {12, 2025}, C)}},
|
||||
DestID = create_instrument(destination, IID, <<"XDesination">>, <<"RUB">>, DestResource, C),
|
||||
authorized = ct_helper:await(
|
||||
authorized,
|
||||
@ -472,10 +472,10 @@ create_destination(IID, C) ->
|
||||
DestID.
|
||||
|
||||
create_crypto_destination(IID, C) ->
|
||||
Resource = {crypto_wallet, #{
|
||||
Resource = {crypto_wallet, #{crypto_wallet => #{
|
||||
id => <<"a30e277c07400c9940628828949efd48">>,
|
||||
currency => {litecoin, #{}}
|
||||
}},
|
||||
}}},
|
||||
DestID = create_instrument(destination, IID, <<"CryptoDestination">>, <<"RUB">>, Resource, C),
|
||||
authorized = ct_helper:await(
|
||||
authorized,
|
||||
|
@ -599,7 +599,7 @@ create_destination(IID, Currency, Token, C) ->
|
||||
Token ->
|
||||
StoreSource#{token => Token}
|
||||
end,
|
||||
Resource = {bank_card, NewStoreResource},
|
||||
Resource = {bank_card, #{bank_card => NewStoreResource}},
|
||||
Params = #{id => ID, identity => IID, name => <<"XDesination">>, currency => Currency, resource => Resource},
|
||||
ok = ff_destination:create(Params, ff_entity_context:new()),
|
||||
authorized = ct_helper:await(
|
||||
@ -613,10 +613,10 @@ create_destination(IID, Currency, Token, C) ->
|
||||
|
||||
create_crypto_destination(IID, _C) ->
|
||||
ID = generate_id(),
|
||||
Resource = {crypto_wallet, #{
|
||||
Resource = {crypto_wallet, #{crypto_wallet => #{
|
||||
id => <<"a30e277c07400c9940628828949efd48">>,
|
||||
currency => {litecoin, #{}}
|
||||
}},
|
||||
}}},
|
||||
Params = #{id => ID, identity => IID, name => <<"CryptoDestination">>, currency => <<"RUB">>, resource => Resource},
|
||||
ok = ff_destination:create(Params, ff_entity_context:new()),
|
||||
authorized = ct_helper:await(
|
||||
|
@ -440,7 +440,7 @@ generate_id() ->
|
||||
|
||||
create_destination(IID, C) ->
|
||||
ID = generate_id(),
|
||||
Resource = {bank_card, ct_cardstore:bank_card(<<"4150399999000900">>, {12, 2025}, C)},
|
||||
Resource = {bank_card, #{bank_card => ct_cardstore:bank_card(<<"4150399999000900">>, {12, 2025}, C)}},
|
||||
Params = #{id => ID, identity => IID, name => <<"XDesination">>, currency => <<"RUB">>, resource => Resource},
|
||||
ok = ff_destination:create(Params, ff_entity_context:new()),
|
||||
authorized = ct_helper:await(
|
||||
|
@ -151,14 +151,24 @@ unmarshal(resource, {disposable, #domain_DisposablePaymentResource{
|
||||
payment_system = PaymentSystem,
|
||||
bin = Bin,
|
||||
last_digits = LastDigits
|
||||
}}
|
||||
}},
|
||||
payment_session_id = ID
|
||||
}}) ->
|
||||
{bank_card, #{
|
||||
token => Token,
|
||||
payment_system => PaymentSystem,
|
||||
bin => Bin,
|
||||
masked_pan => LastDigits
|
||||
}};
|
||||
AuthData = case ID of
|
||||
undefined ->
|
||||
undefined;
|
||||
ID ->
|
||||
{session, #{session_id => unmarshal(string, ID)}}
|
||||
end,
|
||||
{bank_card, genlib_map:compact(#{
|
||||
bank_card => #{
|
||||
token => Token,
|
||||
payment_system => PaymentSystem,
|
||||
bin => Bin,
|
||||
masked_pan => LastDigits
|
||||
},
|
||||
auth_data => AuthData
|
||||
})};
|
||||
|
||||
unmarshal(amount, V) ->
|
||||
unmarshal(integer, V);
|
||||
@ -207,21 +217,30 @@ marshal(payment_resource_payer, Payer = #{resource := Resource}) ->
|
||||
ClientInfo = maps:get(client_info, Payer, undefined),
|
||||
ContactInfo = maps:get(contact_info, Payer, undefined),
|
||||
#domain_PaymentResourcePayer{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = marshal(resource, Resource),
|
||||
client_info = maybe_marshal(client_info, ClientInfo)
|
||||
},
|
||||
resource = marshal(disposable_payment_resource, {Resource, ClientInfo}),
|
||||
contact_info = marshal(contact_info, ContactInfo)
|
||||
};
|
||||
marshal(resource, {bank_card, BankCard}) ->
|
||||
{bank_card, #domain_BankCard{
|
||||
|
||||
marshal(disposable_payment_resource, {Resource, ClientInfo}) ->
|
||||
#domain_DisposablePaymentResource{
|
||||
payment_tool = marshal(payment_tool, Resource),
|
||||
payment_session_id = try_get_session_auth_data(Resource),
|
||||
client_info = maybe_marshal(client_info, ClientInfo)
|
||||
};
|
||||
|
||||
marshal(payment_tool, {bank_card, #{bank_card := BankCard}}) ->
|
||||
{bank_card, marshal(bank_card, BankCard)};
|
||||
|
||||
marshal(bank_card, BankCard) ->
|
||||
#domain_BankCard{
|
||||
token = ff_resource:token(BankCard),
|
||||
bin = ff_resource:bin(BankCard),
|
||||
last_digits = ff_resource:masked_pan(BankCard),
|
||||
payment_system = ff_resource:payment_system(BankCard),
|
||||
issuer_country = ff_resource:country_code(BankCard),
|
||||
bank_name = ff_resource:bank_name(BankCard)
|
||||
}};
|
||||
};
|
||||
|
||||
marshal(contact_info, undefined) ->
|
||||
#domain_ContactInfo{};
|
||||
marshal(contact_info, ContactInfo) ->
|
||||
@ -240,8 +259,8 @@ marshal(client_info, ClientInfo) ->
|
||||
|
||||
marshal(p2p_tool, {Sender, Receiver}) ->
|
||||
#domain_P2PTool{
|
||||
sender = marshal(resource, Sender),
|
||||
receiver = marshal(resource, Receiver)
|
||||
sender = marshal(payment_tool, Sender),
|
||||
receiver = marshal(payment_tool, Receiver)
|
||||
};
|
||||
|
||||
marshal(risk_score, low) ->
|
||||
@ -264,4 +283,9 @@ marshal(_, Other) ->
|
||||
maybe_marshal(_Type, undefined) ->
|
||||
undefined;
|
||||
maybe_marshal(Type, Value) ->
|
||||
marshal(Type, Value).
|
||||
marshal(Type, Value).
|
||||
|
||||
try_get_session_auth_data({bank_card, #{auth_data := {session, #{session_id := ID}}}}) ->
|
||||
marshal(string, ID);
|
||||
try_get_session_auth_data(_) ->
|
||||
undefined.
|
||||
|
@ -15,6 +15,15 @@
|
||||
bin_data_id => bin_data_id()
|
||||
}.
|
||||
|
||||
-type resource_bank_card_params() :: #{
|
||||
bank_card := bank_card_params(),
|
||||
auth_data => bank_card_auth_data()
|
||||
}.
|
||||
|
||||
-type resource_crypto_wallet_params() :: #{
|
||||
crypto_wallet := crypto_wallet_params()
|
||||
}.
|
||||
|
||||
-type bank_card_params() :: #{
|
||||
token := binary(),
|
||||
bin => binary(),
|
||||
@ -24,19 +33,47 @@
|
||||
}.
|
||||
|
||||
-type exp_date() :: {binary(), binary()}.
|
||||
-type bank_card_auth_data() ::
|
||||
{session, session_auth_data()}.
|
||||
|
||||
-type session_auth_data() :: #{
|
||||
session_id := binary()
|
||||
}.
|
||||
|
||||
-type crypto_wallet_params() :: #{
|
||||
id := binary(),
|
||||
currency := atom(),
|
||||
tag => binary()
|
||||
currency := crypto_currency()
|
||||
}.
|
||||
|
||||
-type resource_id() :: {bank_card, bin_data_id()}.
|
||||
-type resource_params() :: {bank_card, bank_card_params()} |
|
||||
{crypto_wallet, crypto_wallet_params()}.
|
||||
-type resource() :: {bank_card, bank_card()} |
|
||||
{crypto_wallet, crypto_wallet()}.
|
||||
-type crypto_wallet() :: crypto_wallet_params().
|
||||
-type resource_params() :: {bank_card, resource_bank_card_params()} |
|
||||
{crypto_wallet, resource_crypto_wallet_params()}.
|
||||
-type resource() :: {bank_card, resource_bank_card()} |
|
||||
{crypto_wallet, resource_crypto_wallet()}.
|
||||
|
||||
-type resource_bank_card() :: #{
|
||||
bank_card := bank_card(),
|
||||
auth_data => bank_card_auth_data()
|
||||
}.
|
||||
|
||||
-type resource_crypto_wallet() :: #{
|
||||
crypto_wallet := crypto_wallet()
|
||||
}.
|
||||
|
||||
-type crypto_wallet() :: #{
|
||||
id := binary(),
|
||||
currency := crypto_currency()
|
||||
}.
|
||||
|
||||
-type crypto_currency()
|
||||
:: {bitcoin, #{}}
|
||||
| {bitcoin_cash, #{}}
|
||||
| {litecoin, #{}}
|
||||
| {ethereum, #{}}
|
||||
| {zcash, #{}}
|
||||
| {usdt, #{}}
|
||||
| {ripple, #{tag => binary()}}
|
||||
.
|
||||
|
||||
-type token() :: binary().
|
||||
-type bin() :: binary().
|
||||
@ -110,7 +147,7 @@ country_code(BankCard) ->
|
||||
bank_name(BankCard) ->
|
||||
maps:get(bank_name, BankCard, undefined).
|
||||
|
||||
-spec create_resource(resource()) ->
|
||||
-spec create_resource(resource_params()) ->
|
||||
{ok, resource()} |
|
||||
{error, {bin_data, not_found}}.
|
||||
|
||||
@ -121,15 +158,26 @@ create_resource(Resource) ->
|
||||
{ok, resource()} |
|
||||
{error, {bin_data, not_found}}.
|
||||
|
||||
create_resource({bank_card, #{token := Token} = BankCard}, ResourceID) ->
|
||||
create_resource({bank_card, #{bank_card := #{token := Token} = BankCardParams} = Params}, ResourceID) ->
|
||||
do(fun() ->
|
||||
BinData = unwrap(bin_data, get_bin_data(Token, ResourceID)),
|
||||
KeyList = [payment_system, bank_name, iso_country_code, card_type],
|
||||
ExtendData = maps:with(KeyList, BinData),
|
||||
{bank_card, maps:merge(BankCard, ExtendData#{bin_data_id => ff_bin_data:id(BinData)})}
|
||||
{bank_card, genlib_map:compact(#{
|
||||
bank_card => maps:merge(BankCardParams, ExtendData#{bin_data_id => ff_bin_data:id(BinData)}),
|
||||
auth_data => maps:get(auth_data, Params, undefined)
|
||||
})}
|
||||
end);
|
||||
create_resource({crypto_wallet, CryptoWallet}, _ResourceID) ->
|
||||
{ok, CryptoWallet}.
|
||||
create_resource({crypto_wallet, #{crypto_wallet := #{
|
||||
id := ID,
|
||||
currency := Currency
|
||||
}}}, _ResourceID) ->
|
||||
{ok, {crypto_wallet, #{
|
||||
crypto_wallet => #{
|
||||
id => ID,
|
||||
currency => Currency
|
||||
}
|
||||
}}}.
|
||||
|
||||
get_bin_data(Token, undefined) ->
|
||||
ff_bin_data:get(Token, undefined);
|
||||
|
@ -134,9 +134,7 @@ marshal(operation_info, OperationInfo = #{
|
||||
}};
|
||||
|
||||
marshal(resource, Resource) ->
|
||||
{disposable, #domain_DisposablePaymentResource{
|
||||
payment_tool = ff_dmsl_codec:marshal(resource, Resource)
|
||||
}};
|
||||
{disposable, ff_dmsl_codec:marshal(disposable_payment_resource, {Resource, undefined})};
|
||||
|
||||
marshal(cash, {Amount, Currency}) ->
|
||||
#p2p_adapter_Cash{
|
||||
|
@ -117,7 +117,7 @@ receiver_id(#{receiver := {bank_card, #{bin_data_id := BinDataID}}}) ->
|
||||
|
||||
-spec compact(ff_resource:resource()) ->
|
||||
compact_resource().
|
||||
compact({bank_card, BankCard}) ->
|
||||
compact({bank_card, #{bank_card := BankCard}}) ->
|
||||
{bank_card, #{
|
||||
token => ff_resource:token(BankCard),
|
||||
bin_data_id => ff_resource:bin_data_id(BankCard)
|
||||
|
@ -38,7 +38,7 @@
|
||||
%%
|
||||
%% Types
|
||||
%%
|
||||
-define(ACTUAL_FORMAT_VERSION, 1).
|
||||
-define(ACTUAL_FORMAT_VERSION, 2).
|
||||
|
||||
-opaque session() :: #{
|
||||
version := ?ACTUAL_FORMAT_VERSION,
|
||||
@ -430,10 +430,33 @@ set_session_status(SessionState, Session) ->
|
||||
|
||||
-spec maybe_migrate(event() | legacy_event()) ->
|
||||
event().
|
||||
|
||||
maybe_migrate({created, #{version := 1} = Session}) ->
|
||||
#{
|
||||
version := 1,
|
||||
transfer_params := #{
|
||||
sender := Sender,
|
||||
receiver := Receiver
|
||||
} = Params
|
||||
} = Session,
|
||||
maybe_migrate({created, genlib_map:compact(Session#{
|
||||
version => 2,
|
||||
transfer_params => Params#{
|
||||
sender => maybe_migrate_resource(Sender),
|
||||
receiver => maybe_migrate_resource(Receiver)
|
||||
}
|
||||
})});
|
||||
% Other events
|
||||
maybe_migrate(Ev) ->
|
||||
Ev.
|
||||
|
||||
maybe_migrate_resource({crypto_wallet, #{id := _ID} = CryptoWallet}) ->
|
||||
maybe_migrate_resource({crypto_wallet, #{crypto_wallet => CryptoWallet}});
|
||||
maybe_migrate_resource({bank_card, #{token := _Token} = BankCard}) ->
|
||||
maybe_migrate_resource({bank_card, #{bank_card => BankCard}});
|
||||
maybe_migrate_resource(Resource) ->
|
||||
Resource.
|
||||
|
||||
-spec init(session(), action()) ->
|
||||
{list(event()), action() | undefined}.
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
-type id() :: binary().
|
||||
|
||||
-define(ACTUAL_FORMAT_VERSION, 1).
|
||||
-define(ACTUAL_FORMAT_VERSION, 2).
|
||||
|
||||
-opaque p2p_transfer() :: #{
|
||||
version := ?ACTUAL_FORMAT_VERSION,
|
||||
@ -1111,7 +1111,33 @@ apply_event_({adjustment, _Ev} = Event, T) ->
|
||||
|
||||
-spec maybe_migrate(event() | legacy_event()) ->
|
||||
event().
|
||||
% Actual events
|
||||
|
||||
maybe_migrate({resource_got, Sender, Receiver}) ->
|
||||
{resource_got, maybe_migrate_resource(Sender), maybe_migrate_resource(Receiver)};
|
||||
maybe_migrate({created, #{version := 1} = Transfer}) ->
|
||||
#{
|
||||
version := 1,
|
||||
sender := Sender,
|
||||
receiver := Receiver
|
||||
} = Transfer,
|
||||
maybe_migrate({created, genlib_map:compact(Transfer#{
|
||||
version => 2,
|
||||
sender => maybe_migrate_participant(Sender),
|
||||
receiver => maybe_migrate_participant(Receiver)
|
||||
})});
|
||||
% Other events
|
||||
maybe_migrate(Ev) ->
|
||||
Ev.
|
||||
|
||||
maybe_migrate_resource({crypto_wallet, #{id := _ID} = CryptoWallet}) ->
|
||||
maybe_migrate_resource({crypto_wallet, #{crypto_wallet => CryptoWallet}});
|
||||
maybe_migrate_resource({bank_card, #{token := _Token} = BankCard}) ->
|
||||
maybe_migrate_resource({bank_card, #{bank_card => BankCard}});
|
||||
maybe_migrate_resource(Resource) ->
|
||||
Resource.
|
||||
|
||||
maybe_migrate_participant({raw, #{resource_params := Resource} = Participant}) ->
|
||||
maybe_migrate_participant({raw, Participant#{resource_params => maybe_migrate_resource(Resource)}});
|
||||
|
||||
maybe_migrate_participant(Resource) ->
|
||||
Resource.
|
||||
|
@ -91,8 +91,13 @@ construct_operation_info(ID) ->
|
||||
|
||||
construct_resource() ->
|
||||
{bank_card, #{
|
||||
token => <<"token">>,
|
||||
bin => <<"bin">>,
|
||||
payment_system => visa,
|
||||
masked_pan => <<"masked_pan">>
|
||||
bank_card => #{
|
||||
token => <<"token">>,
|
||||
bin => <<"bin">>,
|
||||
payment_system => visa,
|
||||
masked_pan => <<"masked_pan">>
|
||||
},
|
||||
auth_data => {session, #{
|
||||
session_id => <<"ID">>
|
||||
}}
|
||||
}}.
|
||||
|
@ -13,6 +13,20 @@
|
||||
}
|
||||
}}
|
||||
}).
|
||||
|
||||
-define(ADAPTER_CONTEXT(Amount, Token, SessionID, State), #p2p_adapter_Context{
|
||||
operation = {process, #p2p_adapter_ProcessOperationInfo{
|
||||
body = #p2p_adapter_Cash{amount = Amount},
|
||||
sender = {disposable, #domain_DisposablePaymentResource{
|
||||
payment_tool = {bank_card, #domain_BankCard{
|
||||
token = Token
|
||||
}},
|
||||
payment_session_id = SessionID
|
||||
}}
|
||||
}},
|
||||
session = #p2p_adapter_Session{state = State}
|
||||
}).
|
||||
|
||||
-define(ADAPTER_CONTEXT(Amount, Token, State), #p2p_adapter_Context{
|
||||
operation = {process, #p2p_adapter_ProcessOperationInfo{
|
||||
body = #p2p_adapter_Cash{amount = Amount},
|
||||
@ -76,6 +90,11 @@ handle_function(Func, Args, Ctx, Opts) ->
|
||||
end
|
||||
).
|
||||
|
||||
handle_function_('Process', [?ADAPTER_CONTEXT(_Amount, _Token, undefined, _State)], _Ctx, _Opts) ->
|
||||
{ok, ?ADAPTER_PROCESS_RESULT(
|
||||
?ADAPTER_FINISH_INTENT({failure, #domain_Failure{code = <<"unknown session id">>}}),
|
||||
undefined
|
||||
)};
|
||||
handle_function_('Process', [?ADAPTER_CONTEXT(101, _Token, State)], _Ctx, _Opts) ->
|
||||
case State of
|
||||
undefined ->
|
||||
|
@ -75,7 +75,7 @@ get_fee_ok_test(C) ->
|
||||
identity_id := Identity,
|
||||
sender := CardSender
|
||||
} = prepare_standard_environment(C),
|
||||
Sender = {bank_card, CardSender},
|
||||
Sender = {bank_card, #{bank_card => CardSender}},
|
||||
{ok, {Fee, CashVolume, _}} = p2p_quote:get_quote(Cash, Identity, Sender, Sender),
|
||||
?assertEqual({share, {{65, 10000}, operation_amount, default}}, CashVolume),
|
||||
?assertEqual({146, <<"RUB">>}, Fee).
|
||||
@ -88,12 +88,12 @@ visa_to_nspkmir_not_allow_test(C) ->
|
||||
identity_id := Identity,
|
||||
sender := CardSender
|
||||
} = prepare_standard_environment(C),
|
||||
Sender = {bank_card, CardSender},
|
||||
Receiver = {bank_card, #{
|
||||
Sender = {bank_card, #{bank_card => CardSender}},
|
||||
Receiver = {bank_card, #{bank_card => #{
|
||||
bin => Bin,
|
||||
masked_pan => Pan,
|
||||
token => <<"NSPK MIR">>
|
||||
}},
|
||||
}}},
|
||||
Result = p2p_quote:get_quote(Cash, Identity, Sender, Receiver),
|
||||
?assertEqual({error, {terms, {terms_violation, p2p_forbidden}}}, Result).
|
||||
|
||||
|
@ -241,7 +241,12 @@ prepare_resource(#{token := Token} = RawBankCard) ->
|
||||
{ok, BinData} = ff_bin_data:get(Token, undefined),
|
||||
KeyList = [payment_system, bank_name, iso_country_code, card_type],
|
||||
ExtendData = maps:with(KeyList, BinData),
|
||||
{bank_card, maps:merge(RawBankCard, ExtendData#{bin_data_id => ff_bin_data:id(BinData)})}.
|
||||
{bank_card, #{
|
||||
bank_card => maps:merge(RawBankCard, ExtendData#{bin_data_id => ff_bin_data:id(BinData)}),
|
||||
auth_data => {session, #{
|
||||
session_id => <<"ID">>
|
||||
}}
|
||||
}}.
|
||||
|
||||
get_p2p_session(SessionID) ->
|
||||
{ok, Machine} = p2p_session_machine:get(SessionID),
|
||||
|
@ -63,7 +63,12 @@ create_resource_raw(Token, C) ->
|
||||
Token ->
|
||||
StoreSource#{token => Token}
|
||||
end,
|
||||
p2p_participant:create(raw, {bank_card, NewStoreResource}).
|
||||
p2p_participant:create(raw, {bank_card, #{
|
||||
bank_card => NewStoreResource,
|
||||
auth_data => {session, #{
|
||||
session_id => <<"ID">>
|
||||
}}
|
||||
}}).
|
||||
|
||||
create_person_identity(Party, C, ProviderID) ->
|
||||
create_identity(Party, ProviderID, <<"person">>, C).
|
||||
|
@ -216,7 +216,7 @@ session_callback_ok_test(C) ->
|
||||
ip_address => <<"some ip_address">>,
|
||||
fingerprint => <<"some fingerprint">>
|
||||
},
|
||||
{raw, #{resource_params := {bank_card, #{token := Token}}}} = ResourceSender,
|
||||
{raw, #{resource_params := {bank_card, #{bank_card := #{token := Token}}}}} = ResourceSender,
|
||||
Callback = ?CALLBACK(Token, <<"payload">>),
|
||||
P2PTransferParams = #{
|
||||
id => P2PTransferID,
|
||||
|
@ -387,7 +387,12 @@ generate_id() ->
|
||||
|
||||
create_resource_raw(C) ->
|
||||
StoreSource = ct_cardstore:bank_card(<<"4150399999000900">>, {12, 2025}, C),
|
||||
p2p_participant:create(raw, {bank_card, StoreSource}).
|
||||
p2p_participant:create(raw, {bank_card, #{
|
||||
bank_card => StoreSource,
|
||||
auth_data => {session, #{
|
||||
session_id => <<"ID">>
|
||||
}}
|
||||
}}).
|
||||
|
||||
await_final_adjustment_status(P2PTransferID, AdjustmentID) ->
|
||||
finished = ct_helper:await(
|
||||
|
@ -118,13 +118,13 @@ when Type =:= <<"BankCardDestinationResource">> ->
|
||||
month = Month,
|
||||
year = Year
|
||||
} = BankCard#'BankCard'.exp_date,
|
||||
CostructedResource = {bank_card, #{
|
||||
CostructedResource = {bank_card, #{bank_card => #{
|
||||
token => BankCard#'BankCard'.token,
|
||||
bin => BankCard#'BankCard'.bin,
|
||||
masked_pan => BankCard#'BankCard'.masked_pan,
|
||||
cardholder_name => BankCard#'BankCard'.cardholder_name,
|
||||
exp_date => {Month, Year}
|
||||
}},
|
||||
}}},
|
||||
{ok, ff_codec:marshal(resource, CostructedResource)};
|
||||
{error, {decryption_failed, _} = Error} ->
|
||||
logger:warning("Resource token decryption failed: ~p", [Error]),
|
||||
@ -135,10 +135,10 @@ when Type =:= <<"CryptoWalletDestinationResource">> ->
|
||||
#{
|
||||
<<"id">> := CryptoWalletID
|
||||
} = Resource,
|
||||
CostructedResource = {crypto_wallet, genlib_map:compact(#{
|
||||
CostructedResource = {crypto_wallet, #{crypto_wallet => genlib_map:compact(#{
|
||||
id => CryptoWalletID,
|
||||
currency => marshal_crypto_currency_data(Resource)
|
||||
})},
|
||||
})}},
|
||||
{ok, ff_codec:marshal(resource, CostructedResource)}.
|
||||
|
||||
service_call(Params, Context) ->
|
||||
@ -170,12 +170,12 @@ marshal(resource, #{
|
||||
<<"token">> := Token
|
||||
}) ->
|
||||
BankCard = wapi_utils:base64url_to_map(Token),
|
||||
Resource = {bank_card, #{
|
||||
Resource = {bank_card, #{bank_card => #{
|
||||
token => maps:get(<<"token">>, BankCard),
|
||||
payment_system => erlang:binary_to_existing_atom(maps:get(<<"paymentSystem">>, BankCard), latin1),
|
||||
bin => maps:get(<<"bin">>, BankCard),
|
||||
masked_pan => maps:get(<<"lastDigits">>, BankCard)
|
||||
}},
|
||||
}}},
|
||||
ff_codec:marshal(resource, Resource);
|
||||
|
||||
marshal(context, Context) ->
|
||||
@ -228,21 +228,21 @@ unmarshal(status, {authorized, #dst_Authorized{}}) ->
|
||||
unmarshal(status, {unauthorized, #dst_Unauthorized{}}) ->
|
||||
<<"Unauthorized">>;
|
||||
|
||||
unmarshal(resource, {bank_card, #'BankCard'{
|
||||
unmarshal(resource, {bank_card, #'ResourceBankCard'{bank_card = #'BankCard'{
|
||||
token = Token,
|
||||
bin = Bin,
|
||||
masked_pan = MaskedPan
|
||||
}}) ->
|
||||
}}}) ->
|
||||
genlib_map:compact(#{
|
||||
<<"type">> => <<"BankCardDestinationResource">>,
|
||||
<<"token">> => unmarshal(string, Token),
|
||||
<<"bin">> => unmarshal(string, Bin),
|
||||
<<"lastDigits">> => wapi_utils:get_last_pan_digits(MaskedPan)
|
||||
});
|
||||
unmarshal(resource, {crypto_wallet, #'CryptoWallet'{
|
||||
unmarshal(resource, {crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{
|
||||
id = CryptoWalletID,
|
||||
data = Data
|
||||
}}) ->
|
||||
}}}) ->
|
||||
{Currency, Params} = unmarshal_crypto_currency_data(Data),
|
||||
genlib_map:compact(#{
|
||||
<<"type">> => <<"CryptoWalletDestinationResource">>,
|
||||
|
@ -801,17 +801,30 @@ when Type =:= <<"BankCardDestinationResource">> ->
|
||||
unrecognized ->
|
||||
{ok, from_swag(destination_resource, Resource)};
|
||||
{ok, BankCard} ->
|
||||
{ok, encode_bank_card(BankCard)};
|
||||
{ok, {bank_card, encode_bank_card(BankCard)}};
|
||||
{error, {decryption_failed, _} = Error} ->
|
||||
logger:warning("~s token decryption failed: ~p", [Type, Error]),
|
||||
{error, {invalid_resource_token, Type}}
|
||||
end;
|
||||
construct_resource(#{<<"type">> := Type, <<"token">> := Token, <<"authData">> := AuthData})
|
||||
when Type =:= <<"BankCardSenderResourceParams">> ->
|
||||
case wapi_crypto:decrypt_bankcard_token(Token) of
|
||||
{ok, BankCard} ->
|
||||
{ok, encode_resource_bank_card(BankCard, AuthData)};
|
||||
unrecognized ->
|
||||
logger:warning("~s token unrecognized", [Type]),
|
||||
{error, {invalid_resource_token, Type}};
|
||||
{error, {decryption_failed, _} = Error} ->
|
||||
logger:warning("~s token decryption failed: ~p", [Type, Error]),
|
||||
{error, {invalid_resource_token, Type}}
|
||||
end;
|
||||
construct_resource(#{<<"type">> := Type, <<"token">> := Token})
|
||||
when Type =:= <<"BankCardSenderResource">>
|
||||
orelse Type =:= <<"BankCardReceiverResource">> ->
|
||||
orelse Type =:= <<"BankCardReceiverResource">>
|
||||
orelse Type =:= <<"BankCardReceiverResourceParams">> ->
|
||||
case wapi_crypto:decrypt_bankcard_token(Token) of
|
||||
{ok, BankCard} ->
|
||||
{ok, encode_bank_card(BankCard)};
|
||||
{ok, {bank_card, encode_bank_card(BankCard)}};
|
||||
unrecognized ->
|
||||
logger:warning("~s token unrecognized", [Type]),
|
||||
{error, {invalid_resource_token, Type}};
|
||||
@ -821,21 +834,27 @@ orelse Type =:= <<"BankCardReceiverResource">> ->
|
||||
end;
|
||||
construct_resource(#{<<"type">> := Type, <<"id">> := CryptoWalletID} = Resource)
|
||||
when Type =:= <<"CryptoWalletDestinationResource">> ->
|
||||
{ok, {crypto_wallet, genlib_map:compact(#{
|
||||
{ok, {crypto_wallet, #{crypto_wallet => genlib_map:compact(#{
|
||||
id => CryptoWalletID,
|
||||
currency => from_swag(crypto_wallet_currency, Resource)
|
||||
})}}.
|
||||
})}}}.
|
||||
|
||||
encode_resource_bank_card(BankCard, AuthData) ->
|
||||
EncodedBankCard = encode_bank_card(BankCard),
|
||||
{bank_card, EncodedBankCard#{auth_data => {session, #{session_id => AuthData}}}}.
|
||||
|
||||
encode_bank_card(BankCard) ->
|
||||
{bank_card, genlib_map:compact(#{
|
||||
token => BankCard#'BankCard'.token,
|
||||
bin => BankCard#'BankCard'.bin,
|
||||
masked_pan => BankCard#'BankCard'.masked_pan,
|
||||
cardholder_name => BankCard#'BankCard'.cardholder_name,
|
||||
%% ExpDate is optional in swag_wallets 'StoreBankCard'. But some adapters waiting exp_date.
|
||||
%% Add error, somethink like BankCardReject.exp_date_required
|
||||
exp_date => encode_exp_date(BankCard#'BankCard'.exp_date)
|
||||
})}.
|
||||
#{
|
||||
bank_card => genlib_map:compact(#{
|
||||
token => BankCard#'BankCard'.token,
|
||||
bin => BankCard#'BankCard'.bin,
|
||||
masked_pan => BankCard#'BankCard'.masked_pan,
|
||||
cardholder_name => BankCard#'BankCard'.cardholder_name,
|
||||
%% ExpDate is optional in swag_wallets 'StoreBankCard'. But some adapters waiting exp_date.
|
||||
%% Add error, somethink like BankCardReject.exp_date_required
|
||||
exp_date => encode_exp_date(BankCard#'BankCard'.exp_date)
|
||||
})
|
||||
}.
|
||||
|
||||
encode_exp_date(undefined) ->
|
||||
undefined;
|
||||
@ -1510,23 +1529,23 @@ from_swag(destination_resource, #{
|
||||
<<"token">> := WapiToken
|
||||
}) ->
|
||||
BankCard = wapi_utils:base64url_to_map(WapiToken),
|
||||
{bank_card, #{
|
||||
{bank_card, #{bank_card => #{
|
||||
token => maps:get(<<"token">>, BankCard),
|
||||
payment_system => erlang:binary_to_existing_atom(maps:get(<<"paymentSystem">>, BankCard), latin1),
|
||||
bin => maps:get(<<"bin">>, BankCard),
|
||||
masked_pan => maps:get(<<"lastDigits">>, BankCard)
|
||||
}};
|
||||
}}};
|
||||
from_swag(destination_resource, Resource = #{
|
||||
<<"type">> := <<"CryptoWalletDestinationResource">>,
|
||||
<<"id">> := CryptoWalletID,
|
||||
<<"currency">> := CryptoWalletCurrency
|
||||
}) ->
|
||||
Tag = maps:get(<<"tag">>, Resource, undefined),
|
||||
{crypto_wallet, genlib_map:compact(#{
|
||||
{crypto_wallet, #{crypto_wallet => genlib_map:compact(#{
|
||||
id => CryptoWalletID,
|
||||
currency => from_swag(crypto_wallet_currency, CryptoWalletCurrency),
|
||||
tag => Tag
|
||||
})};
|
||||
})}};
|
||||
from_swag(quote_p2p_params, Params) ->
|
||||
add_external_id(#{
|
||||
sender => maps:get(<<"sender">>, Params),
|
||||
@ -1870,19 +1889,19 @@ to_swag(destination_status, authorized) ->
|
||||
#{<<"status">> => <<"Authorized">>};
|
||||
to_swag(destination_status, unauthorized) ->
|
||||
#{<<"status">> => <<"Unauthorized">>};
|
||||
to_swag(destination_resource, {bank_card, BankCard}) ->
|
||||
to_swag(destination_resource, {bank_card, #{bank_card := BankCard}}) ->
|
||||
to_swag(map, #{
|
||||
<<"type">> => <<"BankCardDestinationResource">>,
|
||||
<<"token">> => maps:get(token, BankCard),
|
||||
<<"bin">> => genlib_map:get(bin, BankCard),
|
||||
<<"lastDigits">> => to_swag(pan_last_digits, genlib_map:get(masked_pan, BankCard))
|
||||
});
|
||||
to_swag(destination_resource, {crypto_wallet, CryptoWallet}) ->
|
||||
to_swag(destination_resource, {crypto_wallet, #{crypto_wallet := CryptoWallet}}) ->
|
||||
to_swag(map, maps:merge(#{
|
||||
<<"type">> => <<"CryptoWalletDestinationResource">>,
|
||||
<<"id">> => maps:get(id, CryptoWallet)
|
||||
}, to_swag(crypto_wallet_currency, maps:get(currency, CryptoWallet))));
|
||||
to_swag(sender_resource, {bank_card, BankCard}) ->
|
||||
to_swag(sender_resource, {bank_card, #{bank_card := BankCard}}) ->
|
||||
to_swag(map, #{
|
||||
<<"type">> => <<"BankCardSenderResource">>,
|
||||
<<"token">> => maps:get(token, BankCard),
|
||||
@ -1890,7 +1909,7 @@ to_swag(sender_resource, {bank_card, BankCard}) ->
|
||||
<<"bin">> => genlib_map:get(bin, BankCard),
|
||||
<<"lastDigits">> => to_swag(pan_last_digits, genlib_map:get(masked_pan, BankCard))
|
||||
});
|
||||
to_swag(receiver_resource, {bank_card, BankCard}) ->
|
||||
to_swag(receiver_resource, {bank_card, #{bank_card := BankCard}}) ->
|
||||
to_swag(map, #{
|
||||
<<"type">> => <<"BankCardReceiverResource">>,
|
||||
<<"token">> => maps:get(token, BankCard),
|
||||
@ -2041,7 +2060,7 @@ to_swag(p2p_transfer_quote, {Cash, Token, ExpiresOn}) ->
|
||||
|
||||
to_swag(p2p_transfer, P2PTransferState) ->
|
||||
#{
|
||||
version := 1,
|
||||
version := 2,
|
||||
id := Id,
|
||||
body := Cash,
|
||||
created_at := CreatedAt,
|
||||
|
@ -117,7 +117,7 @@ end_per_testcase(_Name, C) ->
|
||||
-spec bank_card_resource_test(config()) -> _.
|
||||
bank_card_resource_test(C) ->
|
||||
{ok, Resource, SwagResource} = do_destination_lifecycle(bank_card, C),
|
||||
{bank_card, R} = Resource,
|
||||
{bank_card, #'ResourceBankCard'{bank_card = R}} = Resource,
|
||||
?assertEqual(<<"BankCardDestinationResource">>, maps:get(<<"type">>, SwagResource)),
|
||||
?assertEqual(R#'BankCard'.token, maps:get(<<"token">>, SwagResource)),
|
||||
?assertEqual(R#'BankCard'.bin, maps:get(<<"bin">>, SwagResource)),
|
||||
@ -128,7 +128,7 @@ bitcoin_resource_test(C) ->
|
||||
{ok, Resource, SwagResource} = do_destination_lifecycle(bitcoin, C),
|
||||
?assertEqual(<<"CryptoWalletDestinationResource">>, maps:get(<<"type">>, SwagResource)),
|
||||
?assertEqual(<<"Bitcoin">>, maps:get(<<"currency">>, SwagResource)),
|
||||
{crypto_wallet, #'CryptoWallet'{id = ID}} = Resource,
|
||||
{crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{id = ID}}} = Resource,
|
||||
?assertEqual(ID, maps:get(<<"id">>, SwagResource)).
|
||||
|
||||
-spec litecoin_resource_test(config()) -> _.
|
||||
@ -136,7 +136,7 @@ litecoin_resource_test(C) ->
|
||||
{ok, Resource, SwagResource} = do_destination_lifecycle(litecoin, C),
|
||||
?assertEqual(<<"CryptoWalletDestinationResource">>, maps:get(<<"type">>, SwagResource)),
|
||||
?assertEqual(<<"Litecoin">>, maps:get(<<"currency">>, SwagResource)),
|
||||
{crypto_wallet, #'CryptoWallet'{id = ID}} = Resource,
|
||||
{crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{id = ID}}} = Resource,
|
||||
?assertEqual(ID, maps:get(<<"id">>, SwagResource)).
|
||||
|
||||
-spec bitcoin_cash_resource_test(config()) -> _.
|
||||
@ -144,7 +144,7 @@ bitcoin_cash_resource_test(C) ->
|
||||
{ok, Resource, SwagResource} = do_destination_lifecycle(bitcoin_cash, C),
|
||||
?assertEqual(<<"CryptoWalletDestinationResource">>, maps:get(<<"type">>, SwagResource)),
|
||||
?assertEqual(<<"BitcoinCash">>, maps:get(<<"currency">>, SwagResource)),
|
||||
{crypto_wallet, #'CryptoWallet'{id = ID}} = Resource,
|
||||
{crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{id = ID}}} = Resource,
|
||||
?assertEqual(ID, maps:get(<<"id">>, SwagResource)).
|
||||
|
||||
-spec ripple_resource_test(config()) -> _.
|
||||
@ -152,12 +152,12 @@ ripple_resource_test(C) ->
|
||||
{ok, Resource, SwagResource} = do_destination_lifecycle(ripple, C),
|
||||
?assertEqual(<<"CryptoWalletDestinationResource">>, maps:get(<<"type">>, SwagResource)),
|
||||
?assertEqual(<<"Ripple">>, maps:get(<<"currency">>, SwagResource)),
|
||||
{crypto_wallet, #'CryptoWallet'{
|
||||
{crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{
|
||||
id = ID,
|
||||
data = {ripple, #'CryptoDataRipple'{
|
||||
tag = Tag
|
||||
}}
|
||||
}} = Resource,
|
||||
}}} = Resource,
|
||||
?assertEqual(ID, maps:get(<<"id">>, SwagResource)),
|
||||
?assertEqual(Tag, maps:get(<<"tag">>, SwagResource)).
|
||||
|
||||
@ -166,7 +166,7 @@ ethereum_resource_test(C) ->
|
||||
{ok, Resource, SwagResource} = do_destination_lifecycle(ethereum, C),
|
||||
?assertEqual(<<"CryptoWalletDestinationResource">>, maps:get(<<"type">>, SwagResource)),
|
||||
?assertEqual(<<"Ethereum">>, maps:get(<<"currency">>, SwagResource)),
|
||||
{crypto_wallet, #'CryptoWallet'{id = ID}} = Resource,
|
||||
{crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{id = ID}}} = Resource,
|
||||
?assertEqual(ID, maps:get(<<"id">>, SwagResource)).
|
||||
|
||||
-spec usdt_resource_test(config()) -> _.
|
||||
@ -174,7 +174,7 @@ usdt_resource_test(C) ->
|
||||
{ok, Resource, SwagResource} = do_destination_lifecycle(usdt, C),
|
||||
?assertEqual(<<"CryptoWalletDestinationResource">>, maps:get(<<"type">>, SwagResource)),
|
||||
?assertEqual(<<"USDT">>, maps:get(<<"currency">>, SwagResource)),
|
||||
{crypto_wallet, #'CryptoWallet'{id = ID}} = Resource,
|
||||
{crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{id = ID}}} = Resource,
|
||||
?assertEqual(ID, maps:get(<<"id">>, SwagResource)).
|
||||
|
||||
-spec zcash_resource_test(config()) -> _.
|
||||
@ -182,7 +182,7 @@ zcash_resource_test(C) ->
|
||||
{ok, Resource, SwagResource} = do_destination_lifecycle(zcash, C),
|
||||
?assertEqual(<<"CryptoWalletDestinationResource">>, maps:get(<<"type">>, SwagResource)),
|
||||
?assertEqual(<<"Zcash">>, maps:get(<<"currency">>, SwagResource)),
|
||||
{crypto_wallet, #'CryptoWallet'{id = ID}} = Resource,
|
||||
{crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{id = ID}}} = Resource,
|
||||
?assertEqual(ID, maps:get(<<"id">>, SwagResource)).
|
||||
|
||||
%%
|
||||
@ -266,19 +266,19 @@ build_destination_spec(D) ->
|
||||
<<"identity">> => (D#dst_Destination.account)#account_Account.identity,
|
||||
<<"currency">> => ((D#dst_Destination.account)#account_Account.currency)#'CurrencyRef'.symbolic_code,
|
||||
<<"externalID">> => D#dst_Destination.external_id,
|
||||
<<"resource">> => build_resorce_spec(D#dst_Destination.resource)
|
||||
<<"resource">> => build_resource_spec(D#dst_Destination.resource)
|
||||
}.
|
||||
|
||||
build_resorce_spec({bank_card, R}) ->
|
||||
build_resource_spec({bank_card, R}) ->
|
||||
#{
|
||||
<<"type">> => <<"BankCardDestinationResource">>,
|
||||
<<"token">> => wapi_crypto:encrypt_bankcard_token(R)
|
||||
<<"token">> => wapi_crypto:encrypt_bankcard_token(R#'ResourceBankCard'.bank_card)
|
||||
};
|
||||
build_resorce_spec({crypto_wallet, R}) ->
|
||||
Spec = build_crypto_cyrrency_spec(R#'CryptoWallet'.data),
|
||||
build_resource_spec({crypto_wallet, R}) ->
|
||||
Spec = build_crypto_cyrrency_spec((R#'ResourceCryptoWallet'.crypto_wallet)#'CryptoWallet'.data),
|
||||
Spec#{
|
||||
<<"type">> => <<"CryptoWalletDestinationResource">>,
|
||||
<<"id">> => R#'CryptoWallet'.id
|
||||
<<"id">> => (R#'ResourceCryptoWallet'.crypto_wallet)#'CryptoWallet'.id
|
||||
}.
|
||||
|
||||
build_crypto_cyrrency_spec({bitcoin, #'CryptoDataBitcoin'{}}) ->
|
||||
@ -342,7 +342,7 @@ generate_destination(IdentityID, Resource, Context) ->
|
||||
}.
|
||||
|
||||
generate_resource(bank_card) ->
|
||||
{bank_card, #'BankCard'{
|
||||
{bank_card, #'ResourceBankCard'{bank_card = #'BankCard'{
|
||||
token = uniq(),
|
||||
bin = <<"424242">>,
|
||||
masked_pan = <<"4242">>,
|
||||
@ -354,14 +354,14 @@ generate_resource(bank_card) ->
|
||||
month = 12,
|
||||
year = 2200
|
||||
}
|
||||
}};
|
||||
}}};
|
||||
generate_resource(ResourceType) ->
|
||||
{Currency, Params} = generate_wallet_data(ResourceType),
|
||||
{crypto_wallet, #'CryptoWallet'{
|
||||
{crypto_wallet, #'ResourceCryptoWallet'{crypto_wallet = #'CryptoWallet'{
|
||||
id = uniq(),
|
||||
data = {Currency, Params},
|
||||
currency = Currency
|
||||
}}.
|
||||
}}}.
|
||||
|
||||
generate_wallet_data(bitcoin) ->
|
||||
{bitcoin, #'CryptoDataBitcoin'{}};
|
||||
|
@ -175,11 +175,12 @@ create_p2p_transfer_ok_test(C) ->
|
||||
<<"currency">> => ?RUB
|
||||
},
|
||||
<<"sender">> => #{
|
||||
<<"type">> => <<"BankCardSenderResource">>,
|
||||
<<"token">> => SenderToken
|
||||
<<"type">> => <<"BankCardSenderResourceParams">>,
|
||||
<<"token">> => SenderToken,
|
||||
<<"authData">> => <<"session id">>
|
||||
},
|
||||
<<"receiver">> => #{
|
||||
<<"type">> => <<"BankCardReceiverResource">>,
|
||||
<<"type">> => <<"BankCardReceiverResourceParams">>,
|
||||
<<"token">> => ReceiverToken
|
||||
}
|
||||
}
|
||||
@ -195,7 +196,7 @@ create_p2p_transfer_fail_test(C) ->
|
||||
#{
|
||||
identity_id := IdentityID
|
||||
} = p2p_tests_utils:prepare_standard_environment({?INTEGER, ?RUB}, C),
|
||||
{error, {400, #{<<"name">> := <<"BankCardReceiverResource">>}}} = call_api(
|
||||
{error, {400, #{<<"name">> := <<"BankCardReceiverResourceParams">>}}} = call_api(
|
||||
fun swag_client_wallet_p2_p_api:create_p2_p_transfer/3,
|
||||
#{
|
||||
body => #{
|
||||
@ -205,11 +206,12 @@ create_p2p_transfer_fail_test(C) ->
|
||||
<<"currency">> => ?RUB
|
||||
},
|
||||
<<"sender">> => #{
|
||||
<<"type">> => <<"BankCardSenderResource">>,
|
||||
<<"token">> => SenderToken
|
||||
<<"type">> => <<"BankCardSenderResourceParams">>,
|
||||
<<"token">> => SenderToken,
|
||||
<<"authData">> => <<"session id">>
|
||||
},
|
||||
<<"receiver">> => #{
|
||||
<<"type">> => <<"BankCardReceiverResource">>,
|
||||
<<"type">> => <<"BankCardReceiverResourceParams">>,
|
||||
<<"token">> => ReceiverToken
|
||||
}
|
||||
}
|
||||
@ -256,11 +258,12 @@ create_p2p_transfer_with_token_ok_test(C) ->
|
||||
<<"currency">> => ?RUB
|
||||
},
|
||||
<<"sender">> => #{
|
||||
<<"type">> => <<"BankCardSenderResource">>,
|
||||
<<"token">> => SenderToken
|
||||
<<"type">> => <<"BankCardSenderResourceParams">>,
|
||||
<<"token">> => SenderToken,
|
||||
<<"authData">> => <<"session id">>
|
||||
},
|
||||
<<"receiver">> => #{
|
||||
<<"type">> => <<"BankCardReceiverResource">>,
|
||||
<<"type">> => <<"BankCardReceiverResourceParams">>,
|
||||
<<"token">> => ReceiverToken
|
||||
},
|
||||
<<"quoteToken">> => Token
|
||||
@ -287,11 +290,12 @@ get_p2p_transfer_ok_test(C) ->
|
||||
<<"currency">> => ?RUB
|
||||
},
|
||||
<<"sender">> => #{
|
||||
<<"type">> => <<"BankCardSenderResource">>,
|
||||
<<"token">> => SenderToken
|
||||
<<"type">> => <<"BankCardSenderResourceParams">>,
|
||||
<<"token">> => SenderToken,
|
||||
<<"authData">> => <<"session id">>
|
||||
},
|
||||
<<"receiver">> => #{
|
||||
<<"type">> => <<"BankCardReceiverResource">>,
|
||||
<<"type">> => <<"BankCardReceiverResourceParams">>,
|
||||
<<"token">> => ReceiverToken
|
||||
}
|
||||
}
|
||||
@ -339,11 +343,12 @@ get_p2p_transfer_events_ok_test(C) ->
|
||||
<<"currency">> => ?RUB
|
||||
},
|
||||
<<"sender">> => #{
|
||||
<<"type">> => <<"BankCardSenderResource">>,
|
||||
<<"token">> => SenderToken
|
||||
<<"type">> => <<"BankCardSenderResourceParams">>,
|
||||
<<"token">> => SenderToken,
|
||||
<<"authData">> => <<"session id">>
|
||||
},
|
||||
<<"receiver">> => #{
|
||||
<<"type">> => <<"BankCardReceiverResource">>,
|
||||
<<"type">> => <<"BankCardReceiverResourceParams">>,
|
||||
<<"token">> => ReceiverToken
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@
|
||||
0},
|
||||
{<<"fistful_proto">>,
|
||||
{git,"git@github.com:rbkmoney/fistful-proto.git",
|
||||
{ref,"45bfd9edfdc9a58699e1bd77a4150002c5335146"}},
|
||||
{ref,"509c8d3bccc40de9e3151e2869801adfd7b91a47"}},
|
||||
0},
|
||||
{<<"fistful_reporter_proto">>,
|
||||
{git,"git@github.com:rbkmoney/fistful-reporter-proto.git",
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 47ebaa35181acac3ab4f6dd326132c2ddd24e1a1
|
||||
Subproject commit 832a525b871bc37c1a34a5eba230ca6259c6b68e
|
Loading…
Reference in New Issue
Block a user