TD-367: Drop retired APIs as of valitydev/swag-payments@37e6f46 (#20)

* Steamline test fixtures
* Drop unused utility functions
* Resurrect SearchInvoices / SearchRefunds
This commit is contained in:
Andrew Mayorov 2022-09-05 13:22:16 +03:00 committed by GitHub
parent 987bfc9863
commit dec70d64d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 711 additions and 2397 deletions

View File

@ -14,7 +14,6 @@
capi_woody_client,
damsel,
lechiffre,
reporter_proto,
bender_proto,
bender_client,
dmt_client,

View File

@ -6,7 +6,6 @@
-include_lib("damsel/include/dmsl_payproc_thrift.hrl").
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("damsel/include/dmsl_webhooker_thrift.hrl").
-include_lib("reporter_proto/include/reporter_reports_thrift.hrl").
-include_lib("payout_manager_proto/include/payouts_payout_manager_thrift.hrl").
-type fragment() :: bouncer_client:context_fragment().
@ -22,7 +21,6 @@
{operation, prototype_operation()}
| {payproc, prototype_payproc()}
| {payouts, prototype_payouts()}
| {reports, prototype_reports()}
| {webhooks, prototype_webhooks()}
].
@ -37,10 +35,8 @@
invoice_template => entity_id(),
customer => entity_id(),
binding => entity_id(),
report => report_id(),
file => entity_id(),
webhook => entity_id(),
claim => entity_id(),
payout => entity_id()
}.
@ -59,10 +55,6 @@
webhook => webhook_id() | webhook() | undefined
}.
-type prototype_reports() :: #{
report => report_id() | report() | undefined
}.
-type invoice_id() :: dmsl_domain_thrift:'InvoiceID'().
-type invoice() :: dmsl_domain_thrift:'Invoice'().
@ -75,9 +67,6 @@
-type webhook_id() :: dmsl_webhooker_thrift:'WebhookID'().
-type webhook() :: dmsl_webhooker_thrift:'Webhook'().
-type report_id() :: reporter_reports_thrift:'ReportID'().
-type report() :: reporter_reports_thrift:'Report'().
-type payout_id() :: payouts_payout_manager_thrift:'PayoutID'().
-type payout() :: payouts_payout_manager_thrift:'Payout'().
@ -88,7 +77,6 @@
-export_type([prototype_payproc/0]).
-export_type([prototype_payouts/0]).
-export_type([prototype_webhooks/0]).
-export_type([prototype_reports/0]).
-export([new/0]).
-export([build/3]).
@ -124,10 +112,8 @@ build(operation, Params = #{id := OperationID}, Acc, _WoodyCtx) ->
invoice_template = maybe_entity(invoice_template, Params),
customer = maybe_entity(customer, Params),
binding = maybe_entity(binding, Params),
report = maybe_entity(report, Params),
file = maybe_entity(file, Params),
webhook = maybe_entity(webhook, Params),
claim = maybe_entity(claim, Params),
payout = maybe_entity(payout, Params)
}
}
@ -162,16 +148,6 @@ build(webhooks, Params = #{}, Acc, WoodyCtx) ->
)
}
};
build(reports, Params = #{}, Acc, WoodyCtx) ->
Acc#ctx_v1_ContextFragment{
reports = #ctx_v1_ContextReports{
report = maybe_with(
report,
Params,
fun(V) -> build_report_ctx(V, WoodyCtx) end
)
}
};
build(payouts, Params = #{}, Acc, WoodyCtx) ->
Payout0 = maybe_with(payout, Params, fun(V) ->
build_payout_ctx(V, WoodyCtx)
@ -306,24 +282,6 @@ build_webhook_filter_details(#webhooker_WalletEventFilter{}, Ctx) ->
%%
build_report_ctx(ID, WoodyCtx) when is_integer(ID) ->
maybe_with_woody_result(reporting, 'GetReport', {ID}, WoodyCtx, fun build_report_ctx/1);
build_report_ctx(Report, _WoodyCtx) ->
build_report_ctx(Report).
build_report_ctx(#reports_Report{report_id = ID, party_id = PartyID, shop_id = ShopID, files = Files}) ->
#ctx_v1_Report{
id = integer_to_binary(ID),
party = build_entity(PartyID),
shop = maybe(ShopID, fun build_entity/1),
files = build_set(lists:map(fun build_report_file_ctx/1, Files))
}.
build_report_file_ctx(#reports_FileMeta{file_id = ID}) ->
build_entity(ID).
%%
maybe(undefined, _Then) ->
undefined;
maybe(V, Then) ->

View File

@ -98,7 +98,6 @@ map_error(validation_error, Error) ->
get_handlers() ->
[
capi_handler_categories,
capi_handler_claims,
capi_handler_contracts,
capi_handler_countries,
capi_handler_customers,
@ -108,7 +107,6 @@ get_handlers() ->
capi_handler_payment_institutions,
capi_handler_payments,
capi_handler_payouts,
capi_handler_reports,
capi_handler_search,
capi_handler_shops,
capi_handler_trade_blocs,
@ -301,7 +299,6 @@ set_request_meta(OperationID, Req) ->
'invoiceTemplateID',
'contractID',
'webhookID',
'reportID',
'shopID',
'customerID'
],

View File

@ -1,587 +0,0 @@
-module(capi_handler_claims).
-include_lib("damsel/include/dmsl_payproc_thrift.hrl").
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("damsel/include/dmsl_base_thrift.hrl").
-behaviour(capi_handler).
-export([prepare/3]).
-import(capi_handler_utils, [general_error/2, logic_error/2]).
-spec prepare(
OperationID :: capi_handler:operation_id(),
Req :: capi_handler:request_data(),
Context :: capi_handler:processing_context()
) -> {ok, capi_handler:request_state()} | {error, noimpl}.
prepare(OperationID = 'GetClaims', Req, Context) ->
PartyID = capi_handler_utils:get_party_id(Context),
Authorize = fun() ->
Prototypes = [
{operation, #{party => PartyID, id => OperationID}}
],
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() ->
Claims = capi_utils:unwrap(capi_party:get_claims(PartyID, Context)),
{ok, {200, #{}, decode_claims(filter_claims(maps:get('claimStatus', Req), Claims))}}
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetClaimByID', Req, Context) ->
PartyID = capi_handler_utils:get_party_id(Context),
ClaimID = maps:get('claimID', Req),
Authorize = fun() ->
Prototypes = [
{operation, #{party => PartyID, claim => ClaimID, id => OperationID}}
],
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() ->
case capi_party:get_claim(PartyID, genlib:to_int(ClaimID), Context) of
{ok, Claim} ->
%% filter this out
_ = is_wallet_claim(Claim) andalso capi_handler:respond(general_error(404, <<"Claim not found">>)),
{ok, {200, #{}, decode_claim(Claim)}};
{error, #payproc_ClaimNotFound{}} ->
{ok, general_error(404, <<"Claim not found">>)}
end
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'CreateClaim', Req, Context) ->
PartyID = capi_handler_utils:get_party_id(Context),
try
Changeset = encode_claim_changeset(maps:get('ClaimChangeset', Req)),
Authorize = fun() ->
Prototypes = [
{operation, #{party => PartyID, id => OperationID}}
],
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() ->
case capi_party:create_claim(PartyID, Changeset, Context) of
{ok, Claim} ->
{ok, {201, #{}, decode_claim(Claim)}};
{error, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
{error, #payproc_ChangesetConflict{}} ->
{ok, logic_error('changesetConflict', <<"Changeset conflict">>)};
{error, #payproc_InvalidChangeset{}} ->
{ok, logic_error('invalidChangeset', <<"Invalid changeset">>)};
{error, #base_InvalidRequest{errors = Errors}} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error('invalidRequest', FormattedErrors)}
end
end,
{ok, #{authorize => Authorize, process => Process}}
catch
throw:{encode_contract_modification, adjustment_creation_not_supported} ->
ErrorResp = logic_error(
'invalidChangeset',
<<"Contract adjustment creation not supported">>
),
capi_handler:respond(ErrorResp);
throw:{encode_residence, invalid_residence} ->
capi_handler:respond(logic_error('invalidRequest', <<"Invalid residence">>))
end;
% TODO disabled temporary, exception handling must be fixed befor enabling
% prepare(OperationID = 'UpdateClaimByID', Req, Context) ->
% PartyID = capi_handler_utils:get_party_id(Context),
% ClaimID = maps:get('claimID', Req),
% Authorize = fun() ->
% Prototypes = [
% {operation, #{party => PartyID, claim => ClaimID, id => OperationID}}
% ],
% {ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
% end,
% Process = fun() ->
% Party = capi_utils:unwrap(
% capi_party:update_claim(
% PartyID,
% genlib:to_int(ClaimID),
% genlib:to_int(maps:get('claimRevision', Req)),
% encode_claim_changeset(maps:get('claimChangeset', Req)), Context)
% ),
% {ok, {200, #{}, capi_handler_decoder_party:decode_party(Party)}}
% end,
% {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'RevokeClaimByID', Req, Context) ->
PartyID = capi_handler_utils:get_party_id(Context),
ClaimID = maps:get('claimID', Req),
Authorize = fun() ->
Prototypes = [
{operation, #{party => PartyID, claim => ClaimID, id => OperationID}}
],
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() ->
Result = capi_party:revoke_claim(
PartyID,
genlib:to_int(ClaimID),
genlib:to_int(maps:get('claimRevision', Req)),
encode_reason(maps:get('Reason', Req)),
Context
),
case Result of
ok ->
{ok, {204, #{}, undefined}};
{error, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
{error, #payproc_ClaimNotFound{}} ->
{ok, general_error(404, <<"Claim not found">>)};
{error, #payproc_InvalidClaimStatus{}} ->
{ok, logic_error('invalidClaimStatus', <<"Invalid claim status">>)};
{error, #payproc_InvalidClaimRevision{}} ->
{ok, logic_error('invalidClaimRevision', <<"Invalid claim revision">>)}
end
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(_OperationID, _Req, _Context) ->
{error, noimpl}.
%%
filter_claims(ClaimStatus, Claims) ->
lists:filter(
fun(C) ->
is_claim_status_equals(ClaimStatus, C) andalso
(not is_wallet_claim(C))
end,
Claims
).
is_claim_status_equals(undefined, _) ->
true;
is_claim_status_equals(ClaimStatus, #payproc_Claim{status = {Status, _}}) ->
Status =:= ClaimStatus.
encode_claim_changeset(Changeset) when is_list(Changeset) ->
lists:map(fun encode_party_modification/1, Changeset).
encode_party_modification(#{<<"partyModificationType">> := Type} = Modification) ->
case Type of
<<"ContractModification">> ->
{contract_modification, encode_contract_modification(Modification)};
<<"ShopModification">> ->
{shop_modification, encode_shop_modification(Modification)}
end.
encode_contract_modification(#{<<"contractID">> := ContractID} = Modification) ->
EncodedMod =
case maps:get(<<"contractModificationType">>, Modification) of
<<"ContractCreation">> ->
{creation, #payproc_ContractParams{
contractor = encode_contractor(maps:get(<<"contractor">>, Modification)),
payment_institution = encode_payment_institution_ref(
maps:get(<<"paymentInstitutionID">>, Modification)
)
}};
<<"ContractTermination">> ->
{termination, #payproc_ContractTermination{
reason = encode_reason(maps:get(<<"reason">>, Modification))
}};
<<"ContractLegalAgreementBinding">> ->
{legal_agreement_binding, encode_legal_agreement(maps:get(<<"legalAgreement">>, Modification))};
<<"ContractAdjustmentCreation">> ->
% FIXME need swag supprot for template ref
% {adjustment_modification, #payproc_ContractAdjustmentModificationUnit{
% adjustment_id = maps:get(<<"adjustmentID">>, Modification),
% modification = {creation, #payproc_ContractAdjustmentParams{
% template = NOT_SUPPORTED
% }}
% }};
erlang:throw({encode_contract_modification, adjustment_creation_not_supported});
<<"ContractPayoutToolCreation">> ->
{payout_tool_modification, #payproc_PayoutToolModificationUnit{
payout_tool_id = maps:get(<<"payoutToolID">>, Modification),
modification = {creation, encode_payout_tool_params(Modification)}
}};
<<"ContractPayoutToolInfoModification">> ->
{payout_tool_modification, #payproc_PayoutToolModificationUnit{
payout_tool_id = maps:get(<<"payoutToolID">>, Modification),
modification = {info_modification, encode_payout_tool_info(maps:get(<<"details">>, Modification))}
}};
<<"ContractReportingPreferencesChange">> ->
{report_preferences_modification, encode_report_preferences(Modification)}
end,
#payproc_ContractModificationUnit{
id = ContractID,
modification = EncodedMod
}.
encode_shop_modification(#{<<"shopID">> := ShopID} = Modification) ->
EncodedMod =
case maps:get(<<"shopModificationType">>, Modification) of
<<"ShopCreation">> ->
{creation, encode_shop_params(Modification)};
<<"ShopAccountCreation">> ->
{shop_account_creation, #payproc_ShopAccountParams{
currency = capi_handler_encoder:encode_currency(maps:get(<<"currency">>, Modification))
}};
<<"ShopCategoryChange">> ->
{category_modification, encode_category_ref(maps:get(<<"categoryID">>, Modification))};
<<"ShopLocationChange">> ->
{location_modification, encode_shop_location(maps:get(<<"location">>, Modification))};
<<"ShopDetailsChange">> ->
{details_modification, encode_shop_details(maps:get(<<"details">>, Modification))};
<<"ShopContractBinding">> ->
{contract_modification, #payproc_ShopContractModification{
contract_id = maps:get(<<"contractID">>, Modification),
payout_tool_id = maps:get(<<"payoutToolID">>, Modification)
}};
<<"ShopPayoutToolChange">> ->
{payout_tool_modification, maps:get(<<"payoutToolID">>, Modification)};
<<"ShopPayoutScheduleChange">> ->
{payout_schedule_modification, #payproc_ScheduleModification{
schedule = encode_schedule_ref(genlib_map:get(<<"scheduleID">>, Modification))
}}
end,
#payproc_ShopModificationUnit{
id = ShopID,
modification = EncodedMod
}.
encode_reason(undefined) -> undefined;
encode_reason(#{<<"reason">> := Reason}) -> Reason.
encode_legal_agreement(LegalAgreement) ->
#domain_LegalAgreement{
signed_at = maps:get(<<"signedAt">>, LegalAgreement),
legal_agreement_id = maps:get(<<"id">>, LegalAgreement),
valid_until = genlib_map:get(<<"validUntil">>, LegalAgreement)
}.
encode_payout_tool_params(#{<<"currency">> := Currency, <<"details">> := Details}) ->
#payproc_PayoutToolParams{
currency = capi_handler_encoder:encode_currency(Currency),
tool_info = encode_payout_tool_info(Details)
}.
encode_payout_tool_info(#{<<"detailsType">> := <<"PayoutToolDetailsBankAccount">>} = Tool) ->
{russian_bank_account, encode_russian_bank_account(Tool)};
encode_payout_tool_info(#{<<"detailsType">> := <<"PayoutToolDetailsInternationalBankAccount">>} = Tool) ->
{international_bank_account, encode_international_bank_account(Tool)};
encode_payout_tool_info(#{<<"detailsType">> := <<"PayoutToolDetailsWalletInfo">>} = Tool) ->
{wallet_info, #domain_WalletInfo{wallet_id = maps:get(<<"walletID">>, Tool)}}.
encode_russian_bank_account(BankAccount) ->
#domain_RussianBankAccount{
account = maps:get(<<"account">>, BankAccount),
bank_name = maps:get(<<"bankName">>, BankAccount),
bank_post_account = maps:get(<<"bankPostAccount">>, BankAccount),
bank_bik = maps:get(<<"bankBik">>, BankAccount)
}.
encode_international_bank_account(undefined) ->
undefined;
encode_international_bank_account(Acc) ->
#domain_InternationalBankAccount{
iban = genlib_map:get(<<"iban">>, Acc),
number = genlib_map:get(<<"number">>, Acc),
bank = encode_international_bank_details(genlib_map:get(<<"bankDetails">>, Acc)),
correspondent_account = encode_international_bank_account(genlib_map:get(<<"correspondentBankAccount">>, Acc))
}.
encode_international_bank_details(undefined) ->
undefined;
encode_international_bank_details(Acc) ->
#domain_InternationalBankDetails{
bic = genlib_map:get(<<"bic">>, Acc),
country = capi_handler_encoder:encode_residence(genlib_map:get(<<"countryCode">>, Acc)),
name = genlib_map:get(<<"name">>, Acc),
address = genlib_map:get(<<"address">>, Acc),
aba_rtn = genlib_map:get(<<"abartn">>, Acc)
}.
encode_contractor(#{<<"contractorType">> := <<"PrivateEntity">>} = Contractor) ->
{private_entity, encode_private_entity(Contractor)};
encode_contractor(#{<<"contractorType">> := <<"LegalEntity">>} = Contractor) ->
{legal_entity, encode_legal_entity(Contractor)};
encode_contractor(#{<<"contractorType">> := <<"RegisteredUser">>} = Contractor) ->
{registered_user, encode_registered_user(Contractor)}.
encode_private_entity(#{<<"entityType">> := <<"RussianPrivateEntity">>} = Entity) ->
{russian_private_entity, #domain_RussianPrivateEntity{
first_name = maps:get(<<"firstName">>, Entity),
second_name = maps:get(<<"secondName">>, Entity),
middle_name = maps:get(<<"middleName">>, Entity),
contact_info = capi_handler_encoder:encode_contact_info(maps:get(<<"contactInfo">>, Entity))
}}.
encode_legal_entity(#{<<"entityType">> := <<"RussianLegalEntity">>} = Entity) ->
{russian_legal_entity, #domain_RussianLegalEntity{
registered_name = maps:get(<<"registeredName">>, Entity),
registered_number = maps:get(<<"registeredNumber">>, Entity),
inn = maps:get(<<"inn">>, Entity),
actual_address = maps:get(<<"actualAddress">>, Entity),
post_address = maps:get(<<"postAddress">>, Entity),
representative_position = maps:get(<<"representativePosition">>, Entity),
representative_full_name = maps:get(<<"representativeFullName">>, Entity),
representative_document = maps:get(<<"representativeDocument">>, Entity),
russian_bank_account = encode_russian_bank_account(maps:get(<<"bankAccount">>, Entity))
}};
encode_legal_entity(#{<<"entityType">> := <<"InternationalLegalEntity">>} = Entity) ->
{international_legal_entity, #domain_InternationalLegalEntity{
legal_name = genlib_map:get(<<"legalName">>, Entity),
trading_name = genlib_map:get(<<"tradingName">>, Entity),
registered_address = genlib_map:get(<<"registeredOffice">>, Entity),
actual_address = genlib_map:get(<<"principalPlaceOfBusiness">>, Entity),
registered_number = genlib_map:get(<<"registeredNumber">>, Entity)
}}.
encode_registered_user(#{<<"email">> := Email}) ->
#domain_RegisteredUser{email = Email}.
encode_payment_institution_ref(Ref) ->
#domain_PaymentInstitutionRef{id = Ref}.
encode_report_preferences(#{
<<"serviceAcceptanceActPreferences">> := #{
<<"scheduleID">> := ScheduleID,
<<"signer">> := Signer
}
}) ->
#domain_ReportPreferences{
service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{
schedule = encode_schedule_ref(ScheduleID),
signer = encode_representative(Signer)
}
};
encode_report_preferences(_) ->
#domain_ReportPreferences{}.
encode_representative(Representative) ->
#domain_Representative{
position = maps:get(<<"position">>, Representative),
full_name = maps:get(<<"fullName">>, Representative),
document = encode_representative_document(maps:get(<<"document">>, Representative))
}.
encode_representative_document(#{<<"representativeDocumentType">> := <<"ArticlesOfAssociation">>}) ->
{articles_of_association, #domain_ArticlesOfAssociation{}};
encode_representative_document(#{<<"representativeDocumentType">> := <<"PowerOfAttorney">>} = Document) ->
{power_of_attorney, encode_legal_agreement(Document)}.
encode_shop_params(Params) ->
#payproc_ShopParams{
location = encode_shop_location(genlib_map:get(<<"location">>, Params)),
details = encode_shop_details(genlib_map:get(<<"details">>, Params)),
contract_id = genlib_map:get(<<"contractID">>, Params),
payout_tool_id = genlib_map:get(<<"payoutToolID">>, Params)
}.
encode_shop_details(undefined) ->
undefined;
encode_shop_details(Details = #{<<"name">> := Name}) ->
#domain_ShopDetails{
name = Name,
description = genlib_map:get(<<"description">>, Details)
}.
encode_shop_location(#{
<<"locationType">> := <<"ShopLocationUrl">>,
<<"url">> := Url
}) ->
{url, Url}.
encode_category_ref(undefined) ->
undefined;
encode_category_ref(Ref) ->
#domain_CategoryRef{id = Ref}.
encode_schedule_ref(ID) when ID /= undefined ->
#domain_BusinessScheduleRef{id = ID};
encode_schedule_ref(undefined) ->
undefined.
%%
decode_claims(Claims) ->
lists:map(fun decode_claim/1, Claims).
decode_claim(Claim) ->
capi_handler_utils:merge_and_compact(
#{
<<"id">> => Claim#payproc_Claim.id,
<<"revision">> => Claim#payproc_Claim.revision,
<<"createdAt">> => Claim#payproc_Claim.created_at,
<<"updatedAt">> => Claim#payproc_Claim.updated_at,
<<"changeset">> => decode_party_changeset(Claim#payproc_Claim.changeset)
},
decode_claim_status(Claim#payproc_Claim.status)
).
is_wallet_claim(#payproc_Claim{changeset = Changeset}) ->
lists:any(fun is_wallet_change/1, Changeset).
is_wallet_change({contractor_modification, _}) ->
true;
is_wallet_change({wallet_modification, _}) ->
true;
is_wallet_change(
{contract_modification, #payproc_ContractModificationUnit{
modification =
{creation, #payproc_ContractParams{
contractor = undefined
}}
}}
) ->
true;
is_wallet_change(
{contract_modification, #payproc_ContractModificationUnit{
modification = {contractor_modification, _}
}}
) ->
true;
is_wallet_change(_) ->
false.
decode_claim_status({'pending', _}) ->
#{<<"status">> => <<"ClaimPending">>};
decode_claim_status({'accepted', #payproc_ClaimAccepted{}}) ->
#{<<"status">> => <<"ClaimAccepted">>};
decode_claim_status({'denied', #payproc_ClaimDenied{reason = Reason}}) ->
#{<<"status">> => <<"ClaimDenied">>, <<"reason">> => Reason};
decode_claim_status({'revoked', #payproc_ClaimRevoked{reason = Reason}}) ->
#{<<"status">> => <<"ClaimRevoked">>, <<"reason">> => Reason}.
decode_party_changeset(PartyChangeset) ->
lists:filtermap(fun decode_party_modification/1, PartyChangeset).
decode_party_modification({contract_modification, ContractModification}) ->
{true,
maps:merge(
#{
<<"partyModificationType">> => <<"ContractModification">>,
<<"contractID">> => ContractModification#payproc_ContractModificationUnit.id
},
decode_contract_modification(ContractModification#payproc_ContractModificationUnit.modification)
)};
decode_party_modification({shop_modification, ShopModification}) ->
{true,
maps:merge(
#{
<<"partyModificationType">> => <<"ShopModification">>,
<<"shopID">> => ShopModification#payproc_ShopModificationUnit.id
},
decode_shop_modification(ShopModification#payproc_ShopModificationUnit.modification)
)}.
decode_contract_modification({creation, ContractParams}) ->
#{
<<"contractModificationType">> => <<"ContractCreation">>,
<<"contractor">> =>
capi_handler_decoder_party:decode_contractor(ContractParams#payproc_ContractParams.contractor),
<<"paymentInstitutionID">> =>
capi_handler_decoder_party:decode_payment_institution_ref(
ContractParams#payproc_ContractParams.payment_institution
)
};
decode_contract_modification({legal_agreement_binding, LegalAgreement}) ->
#{
<<"contractModificationType">> => <<"ContractLegalAgreementBinding">>,
<<"legalAgreement">> => capi_handler_decoder_party:decode_legal_agreement(LegalAgreement)
};
decode_contract_modification({adjustment_modification, AdjustmentModification}) ->
#payproc_ContractAdjustmentModificationUnit{
adjustment_id = AdjustmentID,
modification =
{creation, #payproc_ContractAdjustmentParams{
% FIXME need swag support for this
template = _Template
}}
} = AdjustmentModification,
#{
<<"contractModificationType">> => <<"ContractAdjustmentCreation">>,
<<"adjustmentID">> => AdjustmentID
};
decode_contract_modification({termination, #payproc_ContractTermination{reason = Reason}}) ->
genlib_map:compact(#{
<<"contractModificationType">> => <<"ContractTermination">>,
<<"reason">> => Reason
});
decode_contract_modification(
{payout_tool_modification, #payproc_PayoutToolModificationUnit{
payout_tool_id = PayoutToolID,
modification = {creation, PayoutToolParams}
}}
) ->
maps:merge(
#{
<<"contractModificationType">> => <<"ContractPayoutToolCreation">>,
<<"payoutToolID">> => PayoutToolID
},
decode_payout_tool_params(PayoutToolParams)
);
decode_contract_modification(
{payout_tool_modification, #payproc_PayoutToolModificationUnit{
payout_tool_id = PayoutToolID,
modification = {info_modification, ToolInfo}
}}
) ->
#{
<<"contractModificationType">> => <<"ContractPayoutToolInfoModification">>,
<<"payoutToolID">> => PayoutToolID,
<<"details">> => capi_handler_decoder_party:decode_payout_tool_details(ToolInfo)
};
decode_contract_modification({report_preferences_modification, ReportPreferences}) ->
maps:merge(
#{<<"contractModificationType">> => <<"ContractReportingPreferencesChange">>},
capi_handler_decoder_party:decode_reporting_preferences(ReportPreferences)
).
decode_shop_modification({creation, ShopParams}) ->
maps:merge(
#{<<"shopModificationType">> => <<"ShopCreation">>},
decode_shop_params(ShopParams)
);
decode_shop_modification({shop_account_creation, #payproc_ShopAccountParams{currency = Currency}}) ->
#{
<<"shopModificationType">> => <<"ShopAccountCreation">>,
<<"currency">> => capi_handler_decoder_utils:decode_currency(Currency)
};
decode_shop_modification({category_modification, CategoryRef}) ->
#{
<<"shopModificationType">> => <<"ShopCategoryChange">>,
<<"categoryID">> => capi_handler_decoder_utils:decode_category_ref(CategoryRef)
};
decode_shop_modification({location_modification, Location}) ->
#{
<<"shopModificationType">> => <<"ShopLocationChange">>,
<<"location">> => capi_handler_decoder_party:decode_shop_location(Location)
};
decode_shop_modification({details_modification, Details}) ->
#{
<<"shopModificationType">> => <<"ShopDetailsChange">>,
<<"details">> => capi_handler_decoder_party:decode_shop_details(Details)
};
decode_shop_modification({contract_modification, ContractMod}) ->
#{
<<"shopModificationType">> => <<"ShopContractBinding">>,
<<"contractID">> => ContractMod#payproc_ShopContractModification.contract_id,
<<"payoutToolID">> => ContractMod#payproc_ShopContractModification.payout_tool_id
};
decode_shop_modification({payout_tool_modification, PayoutToolID}) ->
#{
<<"shopModificationType">> => <<"ShopPayoutToolChange">>,
<<"payoutToolID">> => PayoutToolID
};
decode_shop_modification({payout_schedule_modification, #payproc_ScheduleModification{schedule = ScheduleRef}}) ->
genlib_map:compact(#{
<<"shopModificationType">> => <<"ShopPayoutScheduleChange">>,
<<"scheduleID">> => capi_handler_decoder_utils:decode_business_schedule_ref(ScheduleRef)
}).
decode_payout_tool_params(#payproc_PayoutToolParams{currency = Currency, tool_info = Info}) ->
#{
<<"currency">> => capi_handler_decoder_utils:decode_currency(Currency),
<<"details">> => capi_handler_decoder_party:decode_payout_tool_details(Info)
}.
decode_shop_params(ShopParams) ->
#{
<<"location">> => capi_handler_decoder_party:decode_shop_location(ShopParams#payproc_ShopParams.location),
<<"details">> => capi_handler_decoder_party:decode_shop_details(ShopParams#payproc_ShopParams.details),
<<"contractID">> => ShopParams#payproc_ShopParams.contract_id,
<<"payoutToolID">> => ShopParams#payproc_ShopParams.payout_tool_id
}.

View File

@ -309,7 +309,7 @@ generate_binding_ids(OperationID, CustomerBindingParams, Context = #{woody_conte
PaymentResource = maps:get(<<"paymentResource">>, CustomerBindingParams),
PaymentToolToken = maps:get(<<"paymentToolToken">>, PaymentResource),
PaymentTool = capi_handler_decoder_party:decode_payment_tool(encode_payment_tool_token(PaymentToolToken)),
PaymentTool = capi_handler_decoder_invoicing:decode_payment_tool(encode_payment_tool_token(PaymentToolToken)),
CustomerBindingParamsEncrypted =
maps:put(
<<"paymentResource">>,
@ -405,7 +405,7 @@ decode_customer_binding(CustomerBinding) ->
#{
<<"id">> => CustomerBinding#payproc_CustomerBinding.id,
<<"paymentResource">> =>
capi_handler_decoder_party:decode_disposable_payment_resource(
capi_handler_decoder_invoicing:decode_disposable_payment_resource(
CustomerBinding#payproc_CustomerBinding.payment_resource
)
},

View File

@ -12,9 +12,12 @@
-export([decode_chargeback/2]).
-export([decode_refund/1]).
-export([decode_invoice/1]).
-export([decode_invoice_status/1]).
-export([decode_invoice_cart/1]).
-export([decode_invoice_bank_account/1]).
-export([decode_invoice_line_tax_mode/1]).
-export([decode_payment_tool/1]).
-export([decode_disposable_payment_resource/1]).
-export([decode_payment_methods/1]).
-export([decode_payment_status/2]).
-export([decode_payment_operation_failure/2]).
@ -191,7 +194,7 @@ decode_payer(
#{
<<"payerType">> => <<"CustomerPayer">>,
<<"customerID">> => ID,
<<"paymentToolDetails">> => capi_handler_decoder_party:decode_payment_tool_details(PaymentTool)
<<"paymentToolDetails">> => decode_payment_tool_details(PaymentTool)
};
decode_payer(
{recurrent, #domain_RecurrentPayer{
@ -202,7 +205,7 @@ decode_payer(
) ->
#{
<<"payerType">> => <<"RecurrentPayer">>,
<<"paymentToolDetails">> => capi_handler_decoder_party:decode_payment_tool_details(PaymentTool),
<<"paymentToolDetails">> => decode_payment_tool_details(PaymentTool),
<<"contactInfo">> => capi_handler_decoder_party:decode_contact_info(ContactInfo),
<<"recurrentParentPayment">> => decode_recurrent_parent(RecurrentParent)
};
@ -217,9 +220,91 @@ decode_payer(
<<"payerType">> => <<"PaymentResourcePayer">>,
<<"contactInfo">> => capi_handler_decoder_party:decode_contact_info(ContactInfo)
},
capi_handler_decoder_party:decode_disposable_payment_resource(Resource)
decode_disposable_payment_resource(Resource)
).
-spec decode_payment_tool(capi_handler_encoder:encode_data()) -> capi_handler_decoder_utils:decode_data().
decode_payment_tool({bank_card, BankCard}) ->
decode_bank_card(BankCard);
decode_payment_tool({payment_terminal, PaymentTerminal}) ->
decode_payment_terminal(PaymentTerminal);
decode_payment_tool({digital_wallet, DigitalWallet}) ->
decode_digital_wallet(DigitalWallet);
decode_payment_tool({mobile_commerce, MobileCommerce}) ->
decode_mobile_commerce(MobileCommerce);
decode_payment_tool({crypto_currency, CryptoCurrency}) ->
decode_crypto_wallet(CryptoCurrency).
decode_bank_card(#domain_BankCard{
'token' = Token,
'payment_system' = PaymentSystem,
'exp_date' = ExpDate
}) ->
genlib_map:compact(#{
<<"type">> => <<"bank_card">>,
<<"token">> => Token,
<<"payment_system">> => capi_handler_decoder_utils:decode_payment_system_ref(PaymentSystem),
<<"exp_date">> => ExpDate
}).
decode_payment_terminal(#domain_PaymentTerminal{payment_service = PaymentService}) ->
#{
<<"type">> => <<"payment_terminal">>,
<<"terminal_type">> => capi_handler_decoder_utils:decode_payment_service_ref(PaymentService)
}.
decode_digital_wallet(#domain_DigitalWallet{
payment_service = PaymentService,
id = ID,
token = Token
}) ->
genlib_map:compact(#{
<<"type">> => <<"digital_wallet">>,
<<"provider">> => capi_handler_decoder_utils:decode_payment_service_ref(PaymentService),
<<"id">> => ID,
<<"token">> => Token
}).
decode_crypto_wallet(CryptoCurrency) ->
#{
<<"type">> => <<"crypto_wallet">>,
<<"crypto_currency">> => capi_handler_decoder_utils:decode_crypto_currency_ref(CryptoCurrency)
}.
decode_mobile_commerce(MobileCommerce) ->
#domain_MobileCommerce{
operator = MobileOperator,
phone = #domain_MobilePhone{
cc = Cc,
ctn = Ctn
}
} = MobileCommerce,
Phone = #{<<"cc">> => Cc, <<"ctn">> => Ctn},
#{
<<"type">> => <<"mobile_commerce">>,
<<"phone">> => Phone,
<<"operator">> => capi_handler_decoder_utils:decode_mobile_operator_ref(MobileOperator)
}.
-spec decode_disposable_payment_resource(capi_handler_encoder:encode_data()) ->
capi_handler_decoder_utils:decode_data().
decode_disposable_payment_resource(#domain_DisposablePaymentResource{
payment_tool = PaymentTool,
client_info = ClientInfo
}) ->
#{
<<"paymentToolDetails">> => decode_payment_tool_details(PaymentTool),
<<"clientInfo">> => decode_client_info(ClientInfo)
}.
decode_client_info(undefined) ->
undefined;
decode_client_info(ClientInfo) ->
#{
<<"fingerprint">> => ClientInfo#domain_ClientInfo.fingerprint,
<<"ip">> => ClientInfo#domain_ClientInfo.ip_address
}.
decode_payer_session_info(#domain_PayerSessionInfo{
redirect_url = RedirectURL
}) ->
@ -313,8 +398,7 @@ payment_error_client_maping({authorization_failed, {insufficient_funds, _}}) ->
payment_error_client_maping(_) ->
<<"PaymentRejected">>.
-spec decode_refund(capi_handler_encoder:encode_data()) ->
decode_data().
-spec decode_refund(dmsl_domain_thrift:'InvoicePaymentRefund'()) -> decode_data().
decode_refund(Refund) ->
#domain_Cash{amount = Amount, currency = Currency} = Refund#domain_InvoicePaymentRefund.cash,
capi_handler_utils:merge_and_compact(
@ -325,12 +409,13 @@ decode_refund(Refund) ->
<<"amount">> => Amount,
<<"currency">> => capi_handler_decoder_utils:decode_currency(Currency),
<<"externalID">> => Refund#domain_InvoicePaymentRefund.external_id,
<<"cart">> => decode_invoice_cart(Refund#domain_InvoicePaymentRefund.cart),
<<"allocation">> => capi_allocation:decode(Refund#domain_InvoicePaymentRefund.allocation)
},
decode_refund_status(Refund#domain_InvoicePaymentRefund.status)
).
-spec decode_refund_status({atom(), _}) -> decode_data().
-spec decode_refund_status(dmsl_domain_thrift:'InvoicePaymentRefundStatus'()) -> decode_data().
decode_refund_status({Status, StatusInfo}) ->
Error =
case StatusInfo of
@ -383,7 +468,7 @@ decode_chargeback_stage({arbitration, _StageDetails}) ->
decode_chargeback_reason_code(#domain_InvoicePaymentChargebackReason{code = Code}) ->
#{<<"reasonCode">> => Code}.
-spec decode_invoice(capi_handler_encoder:encode_data()) -> decode_data().
-spec decode_invoice(dmsl_domain_thrift:'Invoice'()) -> decode_data().
decode_invoice(Invoice) ->
#domain_Cash{amount = Amount, currency = Currency} = Invoice#domain_Invoice.cost,
Details = Invoice#domain_Invoice.details,
@ -407,6 +492,7 @@ decode_invoice(Invoice) ->
decode_invoice_status(Invoice#domain_Invoice.status)
).
-spec decode_invoice_status(dmsl_domain_thrift:'InvoiceStatus'()) -> decode_data().
decode_invoice_status({Status, StatusInfo}) ->
Reason =
case StatusInfo of
@ -476,7 +562,10 @@ decode_payment_method(bank_card, Cards) ->
Cards
),
[
#{<<"method">> => <<"BankCard">>, <<"paymentSystems">> => lists:map(fun decode_bank_card/1, Regular)}
#{
<<"method">> => <<"BankCard">>,
<<"paymentSystems">> => lists:map(fun decode_bank_card_method/1, Regular)
}
| decode_tokenized_bank_cards(Tokenized)
];
decode_payment_method(payment_terminal, Providers) ->
@ -520,7 +609,7 @@ decode_payment_method(mobile, MobileOperators) ->
}
].
decode_bank_card(#domain_BankCardPaymentMethod{payment_system = PS}) ->
decode_bank_card_method(#domain_BankCardPaymentMethod{payment_system = PS}) ->
capi_handler_decoder_utils:decode_payment_system_ref(PS).
decode_tokenized_bank_cards([#domain_BankCardPaymentMethod{} | _] = TokenizedBankCards) ->
@ -551,6 +640,70 @@ decode_tokenized_bank_card(TokenProvider, PaymentSystems) ->
[capi_handler_decoder_utils:decode_bank_card_token_service_ref(TokenProvider)]
}.
-spec decode_payment_tool_details(capi_handler_encoder:encode_data()) -> capi_handler_decoder_utils:decode_data().
decode_payment_tool_details({bank_card, V}) ->
decode_bank_card_details(V, #{<<"detailsType">> => <<"PaymentToolDetailsBankCard">>});
decode_payment_tool_details({payment_terminal, V}) ->
decode_payment_terminal_details(V, #{<<"detailsType">> => <<"PaymentToolDetailsPaymentTerminal">>});
decode_payment_tool_details({digital_wallet, V}) ->
decode_digital_wallet_details(V, #{<<"detailsType">> => <<"PaymentToolDetailsDigitalWallet">>});
decode_payment_tool_details({crypto_currency, #domain_CryptoCurrencyRef{id = CryptoCurrency}}) ->
#{
<<"detailsType">> => <<"PaymentToolDetailsCryptoWallet">>,
<<"cryptoCurrency">> => CryptoCurrency
};
decode_payment_tool_details({mobile_commerce, MobileCommerce}) ->
#domain_MobileCommerce{
phone = Phone
} = MobileCommerce,
PhoneNumber = gen_phone_number(decode_mobile_phone(Phone)),
#{
<<"detailsType">> => <<"PaymentToolDetailsMobileCommerce">>,
<<"phoneNumber">> => mask_phone_number(PhoneNumber)
}.
mask_phone_number(PhoneNumber) ->
capi_utils:redact(PhoneNumber, <<"^\\+\\d(\\d{1,10}?)\\d{2,4}$">>).
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 = 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">> => 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
% <<"tokenization_method">> => TokenizationMethod
}).
decode_payment_terminal_details(
#domain_PaymentTerminal{
payment_service = PaymentService
},
V
) ->
V#{
<<"provider">> => capi_handler_decoder_utils:decode_payment_service_ref(PaymentService)
}.
decode_digital_wallet_details(#domain_DigitalWallet{payment_service = Provider}, V) ->
V#{
<<"provider">> => Provider#domain_PaymentServiceRef.id
}.
decode_mobile_phone(#domain_MobilePhone{cc = Cc, ctn = Ctn}) ->
#{<<"cc">> => Cc, <<"ctn">> => Ctn}.
gen_phone_number(#{<<"cc">> := Cc, <<"ctn">> := Ctn}) ->
<<"+", Cc/binary, Ctn/binary>>.
-spec make_invoice_and_token(capi_handler_encoder:encode_data(), processing_context()) ->
capi_handler_decoder_utils:decode_data().
make_invoice_and_token(Invoice, ProcessingContext) ->
@ -568,7 +721,6 @@ make_invoice_and_token(Invoice, ProcessingContext) ->
-spec test() -> _.
-spec crypto_amount_decoder_test() -> _.
crypto_amount_decoder_test() ->
?assertError('expected a power of 10 denominator', decode_crypto_amount(build_request(1, 2))),
?assertEqual(<<"1100000007">>, decode_crypto_amount(build_request(1100000007, 1))),
@ -583,4 +735,12 @@ build_request(P, Q) ->
Cash = #'user_interaction_CryptoCash'{crypto_amount = Amount, crypto_symbolic_code = <<>>},
#'user_interaction_CryptoCurrencyTransferRequest'{crypto_address = <<>>, crypto_cash = Cash}.
-spec mask_phone_number_test_() -> [_TestCase].
mask_phone_number_test_() ->
[
?_assertEqual(<<"+7******7890">>, mask_phone_number(<<"+71234567890">>)),
?_assertEqual(<<"+7*23">>, mask_phone_number(<<"+7123">>)),
?_assertEqual(<<"+1NOTANUMBER">>, mask_phone_number(<<"+1NOTANUMBER">>))
].
-endif.

View File

@ -13,10 +13,7 @@
-export([decode_reporting_preferences/1]).
-export([decode_residence/1]).
-export([decode_payment_institution_ref/1]).
-export([decode_disposable_payment_resource/1]).
-export([decode_payout_tool_details/1]).
-export([decode_payment_tool/1]).
-export([decode_payment_tool_details/1]).
%%
@ -162,147 +159,6 @@ decode_residence(Residence) when is_atom(Residence) ->
decode_payment_institution_ref(#domain_PaymentInstitutionRef{id = Ref}) ->
Ref.
-spec decode_payment_tool(capi_handler_encoder:encode_data()) -> capi_handler_decoder_utils:decode_data().
decode_payment_tool({bank_card, BankCard}) ->
decode_bank_card(BankCard);
decode_payment_tool({payment_terminal, PaymentTerminal}) ->
decode_payment_terminal(PaymentTerminal);
decode_payment_tool({digital_wallet, DigitalWallet}) ->
decode_digital_wallet(DigitalWallet);
decode_payment_tool({mobile_commerce, MobileCommerce}) ->
decode_mobile_commerce(MobileCommerce);
decode_payment_tool({crypto_currency, CryptoCurrency}) ->
decode_crypto_wallet(CryptoCurrency).
decode_bank_card(#domain_BankCard{
'token' = Token,
'payment_system' = PaymentSystem,
'exp_date' = ExpDate
}) ->
genlib_map:compact(#{
<<"type">> => <<"bank_card">>,
<<"token">> => Token,
<<"payment_system">> => capi_handler_decoder_utils:decode_payment_system_ref(PaymentSystem),
<<"exp_date">> => ExpDate
}).
decode_payment_terminal(#domain_PaymentTerminal{payment_service = PaymentService}) ->
#{
<<"type">> => <<"payment_terminal">>,
<<"terminal_type">> => capi_handler_decoder_utils:decode_payment_service_ref(PaymentService)
}.
decode_digital_wallet(#domain_DigitalWallet{
payment_service = PaymentService,
id = ID,
token = Token
}) ->
genlib_map:compact(#{
<<"type">> => <<"digital_wallet">>,
<<"provider">> => capi_handler_decoder_utils:decode_payment_service_ref(PaymentService),
<<"id">> => ID,
<<"token">> => Token
}).
decode_crypto_wallet(CryptoCurrency) ->
#{
<<"type">> => <<"crypto_wallet">>,
<<"crypto_currency">> => capi_handler_decoder_utils:decode_crypto_currency_ref(CryptoCurrency)
}.
decode_mobile_commerce(MobileCommerce) ->
#domain_MobileCommerce{
operator = MobileOperator,
phone = #domain_MobilePhone{
cc = Cc,
ctn = Ctn
}
} = MobileCommerce,
Phone = #{<<"cc">> => Cc, <<"ctn">> => Ctn},
#{
<<"type">> => <<"mobile_commerce">>,
<<"phone">> => Phone,
<<"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().
decode_payment_tool_details({bank_card, V}) ->
decode_bank_card_details(V, #{<<"detailsType">> => <<"PaymentToolDetailsBankCard">>});
decode_payment_tool_details({payment_terminal, V}) ->
decode_payment_terminal_details(V, #{<<"detailsType">> => <<"PaymentToolDetailsPaymentTerminal">>});
decode_payment_tool_details({digital_wallet, V}) ->
decode_digital_wallet_details(V, #{<<"detailsType">> => <<"PaymentToolDetailsDigitalWallet">>});
decode_payment_tool_details({crypto_currency, #domain_CryptoCurrencyRef{id = CryptoCurrency}}) ->
#{
<<"detailsType">> => <<"PaymentToolDetailsCryptoWallet">>,
<<"cryptoCurrency">> => CryptoCurrency
};
decode_payment_tool_details({mobile_commerce, MobileCommerce}) ->
#domain_MobileCommerce{
phone = Phone
} = MobileCommerce,
PhoneNumber = gen_phone_number(decode_mobile_phone(Phone)),
#{
<<"detailsType">> => <<"PaymentToolDetailsMobileCommerce">>,
<<"phoneNumber">> => mask_phone_number(PhoneNumber)
}.
mask_phone_number(PhoneNumber) ->
capi_utils:redact(PhoneNumber, <<"^\\+\\d(\\d{1,10}?)\\d{2,4}$">>).
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 = 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">> => 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
% <<"tokenization_method">> => TokenizationMethod
}).
decode_payment_terminal_details(
#domain_PaymentTerminal{
payment_service = PaymentService
},
V
) ->
V#{
<<"provider">> => capi_handler_decoder_utils:decode_payment_service_ref(PaymentService)
}.
decode_digital_wallet_details(#domain_DigitalWallet{payment_service = Provider}, V) ->
V#{
<<"provider">> => Provider#domain_PaymentServiceRef.id
}.
-spec decode_disposable_payment_resource(capi_handler_encoder:encode_data()) ->
capi_handler_decoder_utils:decode_data().
decode_disposable_payment_resource(#domain_DisposablePaymentResource{
payment_tool = PaymentTool,
client_info = ClientInfo
}) ->
#{
<<"paymentToolDetails">> => decode_payment_tool_details(PaymentTool),
<<"clientInfo">> => decode_client_info(ClientInfo)
}.
decode_client_info(undefined) ->
undefined;
decode_client_info(ClientInfo) ->
#{
<<"fingerprint">> => ClientInfo#domain_ClientInfo.fingerprint,
<<"ip">> => ClientInfo#domain_ClientInfo.ip_address
}.
-spec decode_payout_tool_details({atom(), _}) -> capi_handler_decoder_utils:decode_data().
decode_payout_tool_details({russian_bank_account, V}) ->
decode_russian_bank_account(V, #{<<"detailsType">> => <<"PayoutToolDetailsBankAccount">>});
@ -351,24 +207,3 @@ decode_international_bank_details(Bank) ->
<<"countryCode">> => decode_residence(Bank#domain_InternationalBankDetails.country),
<<"address">> => Bank#domain_InternationalBankDetails.address
}).
decode_mobile_phone(#domain_MobilePhone{cc = Cc, ctn = Ctn}) ->
#{<<"cc">> => Cc, <<"ctn">> => Ctn}.
gen_phone_number(#{<<"cc">> := Cc, <<"ctn">> := Ctn}) ->
<<"+", Cc/binary, Ctn/binary>>.
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-spec test() -> _.
-spec mask_phone_number_test_() -> [_TestCase].
mask_phone_number_test_() ->
[
?_assertEqual(<<"+7******7890">>, mask_phone_number(<<"+71234567890">>)),
?_assertEqual(<<"+7*23">>, mask_phone_number(<<"+7123">>)),
?_assertEqual(<<"+1NOTANUMBER">>, mask_phone_number(<<"+1NOTANUMBER">>))
].
-endif.

View File

@ -481,8 +481,7 @@ create_payment_id(Invoice, PaymentParams0, Context, OperationID, PaymentToolThri
InvoiceID = Invoice#domain_Invoice.id,
PartyID = Invoice#domain_Invoice.owner_id,
Payer = maps:get(<<"payer">>, PaymentParams0),
PaymentTool = capi_utils:maybe(PaymentToolThrift, fun capi_handler_decoder_party:decode_payment_tool/1),
PaymentTool = capi_utils:maybe(PaymentToolThrift, fun capi_handler_decoder_invoicing:decode_payment_tool/1),
PaymentParams = PaymentParams0#{
% Требуется для последующей кодировки параметров плательщика
<<"invoiceID">> => InvoiceID,

View File

@ -1,325 +0,0 @@
-module(capi_handler_reports).
-include_lib("reporter_proto/include/reporter_base_thrift.hrl").
-include_lib("reporter_proto/include/reporter_reports_thrift.hrl").
-behaviour(capi_handler).
-export([prepare/3]).
-import(capi_handler_utils, [general_error/2, logic_error/2]).
% seconds
-define(DEFAULT_URL_LIFETIME, 60).
-spec prepare(
OperationID :: capi_handler:operation_id(),
Req :: capi_handler:request_data(),
Context :: capi_handler:processing_context()
) -> {ok, capi_handler:request_state()} | {error, noimpl}.
prepare(OperationID = 'GetReports', Req, Context) ->
Authorize = fun() ->
PartyID = capi_handler_utils:get_party_id(Context),
Prototypes = build_prototypes(OperationID, PartyID, undefined, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetReportsForParty', Req, Context) ->
Authorize = fun() ->
PartyID = maps:get('partyID', Req),
Prototypes = build_prototypes(OperationID, PartyID, undefined, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetReport', Req, Context) ->
ReportID = maps:get('reportID', Req),
Report =
case get_report_by_id(ReportID, Context) of
{ok, R} ->
R;
{exception, _} ->
undefined
end,
Authorize = fun() ->
PartyID = capi_handler_utils:get_party_id(Context),
Prototypes = build_prototypes(OperationID, PartyID, Report, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetReportForParty', Req, Context) ->
ReportID = maps:get('reportID', Req),
Report =
case get_report_by_id(ReportID, Context) of
{ok, R} ->
R;
{exception, _} ->
undefined
end,
Authorize = fun() ->
PartyID = maps:get('partyID', Req),
Prototypes = build_prototypes(OperationID, PartyID, Report, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'CreateReport', Req, Context) ->
Authorize = fun() ->
PartyID = capi_handler_utils:get_party_id(Context),
Prototypes = build_prototypes(OperationID, PartyID, undefined, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'CreateReportForParty', Req, Context) ->
Authorize = fun() ->
PartyID = maps:get('partyID', Req),
Prototypes = build_prototypes(OperationID, PartyID, undefined, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'DownloadFile', Req, Context) ->
ReportID = maps:get('reportID', Req),
Report =
case get_report_by_id(ReportID, Context) of
{ok, R} ->
R;
{exception, _} ->
undefined
end,
Authorize = fun() ->
PartyID = capi_handler_utils:get_party_id(Context),
Prototypes = build_prototypes(OperationID, PartyID, Report, Req),
{ok, capi_auth:authorize_operation([{reports, #{report => Report}} | Prototypes], Context)}
end,
Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'DownloadFileForParty', Req, Context) ->
ReportID = maps:get('reportID', Req),
Report =
case get_report_by_id(ReportID, Context) of
{ok, R} ->
R;
{exception, _} ->
undefined
end,
Authorize = fun() ->
PartyID = maps:get('partyID', Req),
Prototypes = build_prototypes(OperationID, PartyID, Report, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}};
prepare(_OperationID, _Req, _Context) ->
{error, noimpl}.
-spec process_request(
OperationID :: capi_handler:operation_id(),
Context :: capi_handler:processing_context(),
ReqState :: capi_handler:request_state()
) -> {ok, capi_handler:response()}.
process_request('GetReports', Context, Req) ->
PartyID = capi_handler_utils:get_party_id(Context),
get_reports(PartyID, Req, Context);
process_request('GetReportsForParty', Context, Req) ->
UserID = capi_handler_utils:get_user_id(Context),
PartyID = maps:get('partyID', Req),
capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() ->
get_reports(PartyID, Req, Context)
end);
process_request('GetReport', Context, Req) ->
PartyID = capi_handler_utils:get_party_id(Context),
get_report(PartyID, Req, Context);
process_request('GetReportForParty', Context, Req) ->
UserID = capi_handler_utils:get_user_id(Context),
PartyID = maps:get('partyID', Req),
capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() ->
get_report(PartyID, Req, Context)
end);
process_request('CreateReport', Context, Req) ->
PartyID = capi_handler_utils:get_party_id(Context),
create_report(PartyID, Req, Context);
process_request('CreateReportForParty', Context, Req) ->
UserID = capi_handler_utils:get_user_id(Context),
PartyID = maps:get('partyID', Req),
capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() ->
create_report(PartyID, Req, Context)
end);
process_request('DownloadFile', Context, Req) ->
PartyID = capi_handler_utils:get_party_id(Context),
download_file(PartyID, Req, Context);
process_request('DownloadFileForParty', Context, Req) ->
UserID = capi_handler_utils:get_user_id(Context),
PartyID = maps:get('partyID', Req),
capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() ->
download_file(PartyID, Req, Context)
end).
%%
create_report(PartyID, Req, Context) ->
ShopID = maps:get('shopID', Req),
ReportParams = maps:get('ReportParams', Req),
ReportRequest = #reports_ReportRequest{
party_id = PartyID,
shop_id = ShopID,
time_range = #reports_ReportTimeRange{
from_time = capi_handler_utils:get_time(<<"fromTime">>, ReportParams),
to_time = capi_handler_utils:get_time(<<"toTime">>, ReportParams)
}
},
ReportType = encode_report_type(maps:get(<<"reportType">>, ReportParams)),
case capi_handler_utils:service_call({reporting, 'CreateReport', {ReportRequest, ReportType}}, Context) of
{ok, ReportId} ->
{ok, Report} = capi_handler_utils:service_call(
{reporting, 'GetReport', {ReportId}},
Context
),
{ok, {201, #{}, decode_report(Report)}};
{exception, Exception} ->
case Exception of
#base_InvalidRequest{errors = Errors} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error('invalidRequest', FormattedErrors)};
#reports_ShopNotFound{} ->
{ok, logic_error('invalidShopID', <<"Shop not found">>)}
end
end.
get_report(PartyID, Req, Context) ->
ShopID = maps:get('shopID', Req),
ReportID = maps:get('reportID', Req),
Call = {reporting, 'GetReport', {ReportID}},
case capi_handler_utils:service_call(Call, Context) of
{ok, Report = #'reports_Report'{party_id = PartyID, shop_id = ShopID}} ->
{ok, {200, #{}, decode_report(Report)}};
{ok, _WrongReport} ->
{ok, general_error(404, <<"Report not found">>)};
{exception, #reports_ReportNotFound{}} ->
{ok, general_error(404, <<"Report not found">>)}
end.
get_reports(PartyID, Req, Context) ->
ShopID = maps:get('shopID', Req),
FromTime = capi_handler_utils:get_time('fromTime', Req),
ToTime = capi_handler_utils:get_time('toTime', Req),
ReportRequest = #reports_ReportRequest{
party_id = PartyID,
shop_id = ShopID,
time_range = #reports_ReportTimeRange{
from_time = FromTime,
to_time = ToTime
}
},
StatReportRequest = #reports_StatReportRequest{
request = ReportRequest
},
Call = {reporting, 'GetReports', {StatReportRequest}},
case capi_handler_utils:service_call(Call, Context) of
{ok, #reports_StatReportResponse{reports = Reports}} ->
{ok, {200, #{}, [decode_report(R) || R <- Reports]}};
{exception, Exception} ->
case Exception of
#base_InvalidRequest{errors = Errors} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error('invalidRequest', FormattedErrors)};
#reports_DatasetTooBig{limit = Limit} ->
{ok, logic_error('limitExceeded', io_lib:format("Max limit: ~p", [Limit]))}
end
end.
download_file(PartyID, Req, Context) ->
ShopID = maps:get('shopID', Req),
ReportID = maps:get('reportID', Req),
case get_report_by_id(ReportID, Context) of
{ok, #reports_Report{status = created, files = Files, party_id = PartyID, shop_id = ShopID}} ->
FileID = maps:get('fileID', Req),
case lists:keymember(FileID, #reports_FileMeta.file_id, Files) of
true ->
generate_report_presigned_url(FileID, Context);
false ->
{ok, general_error(404, <<"File not found">>)}
end;
{ok, _WrongReport} ->
{ok, general_error(404, <<"Report not found">>)};
{exception, #reports_ReportNotFound{}} ->
{ok, general_error(404, <<"Report not found">>)}
end.
get_report_by_id(ReportId, Context) ->
Call = {reporting, 'GetReport', {ReportId}},
capi_handler_utils:service_call(Call, Context).
generate_report_presigned_url(FileID, Context) ->
ExpiresAt = get_default_url_lifetime(),
Call = {reporting, 'GeneratePresignedUrl', {FileID, ExpiresAt}},
case capi_handler_utils:service_call(Call, Context) of
{ok, URL} ->
{ok, {200, #{}, #{<<"url">> => URL}}};
{exception, Exception} ->
case Exception of
#base_InvalidRequest{errors = Errors} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error('invalidRequest', FormattedErrors)};
#reports_FileNotFound{} ->
{ok, general_error(404, <<"File not found">>)}
end
end.
get_default_url_lifetime() ->
Now = erlang:system_time(second),
Lifetime = application:get_env(capi, reporter_url_lifetime, ?DEFAULT_URL_LIFETIME),
genlib_rfc3339:format_relaxed(Now + Lifetime, second).
%%
encode_report_type(<<"provisionOfService">>) -> <<"provision_of_service">>;
encode_report_type(<<"paymentRegistry">>) -> <<"payment_registry">>.
%%
decode_report(Report) ->
#reports_ReportTimeRange{from_time = FromTime, to_time = ToTime} = Report#reports_Report.time_range,
#{
<<"id">> => Report#reports_Report.report_id,
<<"createdAt">> => Report#reports_Report.created_at,
<<"fromTime">> => FromTime,
<<"toTime">> => ToTime,
<<"status">> => decode_report_status(Report#reports_Report.status),
<<"type">> => decode_report_type(Report#reports_Report.report_type),
<<"files">> => [decode_report_file(F) || F <- Report#reports_Report.files]
}.
decode_report_status(pending) -> <<"pending">>;
decode_report_status(created) -> <<"created">>.
decode_report_type(<<"provision_of_service">>) -> <<"provisionOfService">>;
decode_report_type(<<"payment_registry">>) -> <<"paymentRegistry">>.
decode_report_file(#reports_FileMeta{file_id = ID, filename = Filename, signature = Signature}) ->
#{
<<"id">> => ID,
<<"filename">> => Filename,
<<"signatures">> => decode_report_file_signature(Signature)
}.
decode_report_file_signature(#reports_Signature{md5 = MD5, sha256 = SHA256}) ->
#{<<"md5">> => MD5, <<"sha256">> => SHA256}.
build_prototypes(OperationID, PartyID, Report, Req) ->
ReportID = genlib_map:get('reportID', Req),
ShopID = genlib_map:get('shopID', Req),
FileID = genlib_map:get('fileID', Req),
[
{operation, #{
id => OperationID,
party => PartyID,
shop => ShopID,
report => ReportID,
file => FileID
}},
{reports, #{report => Report}}
].

View File

@ -15,16 +15,28 @@
Req :: capi_handler:request_data(),
Context :: capi_handler:processing_context()
) -> {ok, capi_handler:request_state()} | {error, noimpl}.
prepare(OperationID, Req, Context) when OperationID =:= 'SearchInvoices' ->
Prototypes = build_prototypes(OperationID, Context, Req),
Authorize = fun() -> {ok, capi_auth:authorize_operation(Prototypes, Context)} end,
Process = fun() ->
Query = make_invoices_search_query(Context, Req),
process_search_request('SearchInvoices', Query, Req, Context)
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID, Req, Context) when OperationID =:= 'SearchPayments' ->
Prototypes = build_prototypes(OperationID, Context, Req),
Authorize = fun() -> {ok, capi_auth:authorize_operation(Prototypes, Context)} end,
Process = fun() ->
Query = make_query(payments, Context, Req),
Opts = #{
thrift_fun => 'SearchPayments',
decode_fun => fun decode_stat_payment/2
},
process_search_request(payments, Query, Req, Context, Opts)
Query = make_payments_search_query(Context, Req),
process_search_request('SearchPayments', Query, Req, Context)
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID, Req, Context) when OperationID =:= 'SearchRefunds' ->
Prototypes = build_prototypes(OperationID, Context, Req),
Authorize = fun() -> {ok, capi_auth:authorize_operation(Prototypes, Context)} end,
Process = fun() ->
Query = make_refunds_search_query(Context, Req),
process_search_request('SearchRefunds', Query, Req, Context)
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(_OperationID, _Req, _Context) ->
@ -32,20 +44,48 @@ prepare(_OperationID, _Req, _Context) ->
%%
make_query(payments, Context, Req) ->
CommonSearchQueryParams = #magista_CommonSearchQueryParams{
make_invoices_search_query(Context, Req) ->
#magista_InvoiceSearchQuery{
common_search_query_params = make_common_query_params(Context, Req),
payment_params = make_payment_query_params(Req),
invoice_ids = encode_invoice_ids(genlib_map:get('invoiceID', Req)),
invoice_status = encode_invoice_status(genlib_map:get('invoiceStatus', Req)),
invoice_amount = genlib_map:get('invoiceAmount', Req)
}.
make_payments_search_query(Context, Req) ->
#magista_PaymentSearchQuery{
common_search_query_params = make_common_query_params(Context, Req),
payment_params = make_payment_query_params(Req),
invoice_ids = encode_invoice_ids(genlib_map:get('invoiceID', Req))
}.
make_refunds_search_query(Context, Req) ->
#magista_RefundSearchQuery{
common_search_query_params = make_common_query_params(Context, Req),
invoice_ids = encode_invoice_ids(genlib_map:get('invoiceID', Req)),
payment_id = genlib_map:get('paymentID', Req),
refund_id = genlib_map:get('refundID', Req),
refund_status = encode_refund_status(genlib_map:get('refundStatus', Req))
}.
make_common_query_params(Context, Req) ->
#magista_CommonSearchQueryParams{
to_time = capi_handler_utils:get_time('toTime', Req),
from_time = capi_handler_utils:get_time('fromTime', Req),
shop_ids = [genlib_map:get('shopID', Req)],
party_id = capi_handler_utils:get_party_id(Context),
continuation_token = genlib_map:get('continuationToken', Req),
limit = genlib_map:get('limit', Req)
},
PaymentParams = #magista_PaymentParams{
}.
make_payment_query_params(Req) ->
#magista_PaymentParams{
payment_id = genlib_map:get('paymentID', Req),
payment_status = encode_payment_status(genlib_map:get('paymentStatus', Req)),
payment_flow = encode_payment_flow(genlib_map:get('paymentFlow', Req)),
payment_tool = encode_payment_method(genlib_map:get('paymentMethod', Req)),
payment_terminal_provider = encode_terminal_provider(genlib_map:get('paymentTerminalProvider', Req)),
payment_email = genlib_map:get('payerEmail', Req),
payment_ip = genlib_map:get('payerIP', Req),
payment_fingerprint = genlib_map:get('payerFingerprint', Req),
@ -56,28 +96,20 @@ make_query(payments, Context, Req) ->
payment_amount = genlib_map:get('paymentAmount', Req),
payment_rrn = genlib_map:get('rrn', Req),
payment_approval_code = genlib_map:get('approvalCode', Req),
payment_token_provider = encode_payment_token_provider(genlib_map:get('BankCardTokenProvider', Req))
},
#magista_PaymentSearchQuery{
common_search_query_params = CommonSearchQueryParams,
payment_params = PaymentParams,
invoice_ids = encode_invoice_ids(genlib_map:get('invoiceID', Req))
payment_token_provider = encode_payment_token_provider(genlib_map:get('bankCardTokenProvider', Req))
}.
process_search_request(QueryType, Query, _Req, Context, Opts = #{thrift_fun := ThriftFun}) ->
Call = {magista, ThriftFun, {Query}},
process_search_request_result(QueryType, capi_handler_utils:service_call(Call, Context), Context, Opts).
process_search_request(Function, Query, _Req, Context) ->
Call = {magista, Function, {Query}},
process_search_request_result(Function, capi_handler_utils:service_call(Call, Context), Context).
process_search_request_result(payments, Result, Context, #{decode_fun := DecodeFun}) ->
process_search_request_result(Function, Result, Context) ->
case Result of
{ok, #magista_StatPaymentResponse{
payments = Payments,
continuation_token = ContinuationToken
}} ->
DecodedData = [DecodeFun(Payment, Context) || Payment <- Payments],
{ok, Response} ->
{Results, ContinuationToken} = decode_search_response(Function, Response, Context),
Resp = genlib_map:compact(#{
<<"result">> => DecodedData,
<<"totalCount">> => length(DecodedData),
<<"result">> => Results,
<<"totalCount">> => length(Results),
<<"continuationToken">> => ContinuationToken
}),
{ok, {200, #{}, Resp}};
@ -90,8 +122,48 @@ process_search_request_result(payments, Result, Context, #{decode_fun := DecodeF
{ok, logic_error('invalidRequest', <<"Invalid token">>)}
end.
decode_search_response(
'SearchInvoices',
#magista_StatInvoiceResponse{
invoices = Invoices,
continuation_token = ContinuationToken
},
_Context
) ->
{
[decode_stat_invoice(Invoice) || Invoice <- Invoices],
ContinuationToken
};
decode_search_response(
'SearchPayments',
#magista_StatPaymentResponse{
payments = Payments,
continuation_token = ContinuationToken
},
Context
) ->
{
[decode_stat_payment(Payment, Context) || Payment <- Payments],
ContinuationToken
};
decode_search_response(
'SearchRefunds',
#magista_StatRefundResponse{
refunds = Refunds,
continuation_token = ContinuationToken
},
_Context
) ->
{[decode_stat_refund(Refund) || Refund <- Refunds], ContinuationToken}.
%%
encode_invoice_status(unpaid) -> unpaid;
encode_invoice_status(cancelled) -> cancelled;
encode_invoice_status(paid) -> paid;
encode_invoice_status(fulfilled) -> fulfilled;
encode_invoice_status(undefined) -> undefined.
encode_payment_status(pending) -> pending;
encode_payment_status(processed) -> processed;
encode_payment_status(captured) -> captured;
@ -100,6 +172,11 @@ encode_payment_status(refunded) -> refunded;
encode_payment_status(failed) -> failed;
encode_payment_status(undefined) -> undefined.
encode_refund_status(pending) -> pending;
encode_refund_status(succeeded) -> succeeded;
encode_refund_status(failed) -> failed;
encode_refund_status(undefined) -> undefined.
encode_payment_flow(instant) -> instant;
encode_payment_flow(hold) -> hold;
encode_payment_flow(undefined) -> undefined.
@ -108,6 +185,11 @@ encode_payment_method('bankCard') -> bank_card;
encode_payment_method('paymentTerminal') -> payment_terminal;
encode_payment_method(undefined) -> undefined.
encode_terminal_provider(ID) -> encode_payment_service_ref(ID).
encode_payment_service_ref(ID) when is_binary(ID) -> #domain_PaymentServiceRef{id = ID};
encode_payment_service_ref(undefined) -> undefined.
encode_payment_system_ref(ID) when is_binary(ID) -> #domain_PaymentSystemRef{id = ID};
encode_payment_system_ref(undefined) -> undefined.
@ -119,6 +201,24 @@ encode_invoice_ids(undefined) -> undefined.
%%
decode_stat_invoice(Stat) ->
capi_handler_utils:merge_and_compact(
#{
<<"id">> => Stat#magista_StatInvoice.id,
<<"externalID">> => Stat#magista_StatInvoice.external_id,
<<"shopID">> => Stat#magista_StatInvoice.shop_id,
<<"createdAt">> => Stat#magista_StatInvoice.created_at,
<<"dueDate">> => Stat#magista_StatInvoice.due,
<<"amount">> => Stat#magista_StatInvoice.amount,
<<"currency">> => Stat#magista_StatInvoice.currency_symbolic_code,
<<"metadata">> => capi_handler_decoder_utils:decode_context(Stat#magista_StatInvoice.context),
<<"product">> => Stat#magista_StatInvoice.product,
<<"description">> => Stat#magista_StatInvoice.description,
<<"cart">> => capi_handler_decoder_invoicing:decode_invoice_cart(Stat#magista_StatInvoice.cart)
},
capi_handler_decoder_invoicing:decode_invoice_status(Stat#magista_StatInvoice.status)
).
decode_stat_payment(Stat, Context) ->
capi_handler_utils:merge_and_compact(
#{
@ -143,6 +243,23 @@ decode_stat_payment(Stat, Context) ->
decode_stat_payment_status(Stat#magista_StatPayment.status, Context)
).
decode_stat_refund(Stat) ->
Status = capi_handler_decoder_invoicing:decode_refund_status(Stat#magista_StatRefund.status),
capi_handler_utils:merge_and_compact(
#{
<<"id">> => Stat#magista_StatRefund.id,
<<"externalID">> => Stat#magista_StatRefund.external_id,
<<"invoiceID">> => Stat#magista_StatRefund.invoice_id,
<<"paymentID">> => Stat#magista_StatRefund.payment_id,
<<"createdAt">> => Stat#magista_StatRefund.created_at,
<<"reason">> => Stat#magista_StatRefund.reason,
<<"amount">> => Stat#magista_StatRefund.amount,
<<"currency">> => Stat#magista_StatRefund.currency_symbolic_code,
<<"cart">> => capi_handler_decoder_invoicing:decode_invoice_cart(Stat#magista_StatRefund.cart)
},
Status
).
decode_stat_tx_info(undefined) ->
undefined;
decode_stat_tx_info(TransactionInfo) ->
@ -317,5 +434,8 @@ build_prototypes(OperationID, Context, Req) ->
payout => genlib_map:get('payoutID', Req),
refund => genlib_map:get('refundID', Req)
}},
{payproc, #{invoice => InvoiceID, customer => CustomerID}}
{payproc, #{
invoice => InvoiceID,
customer => CustomerID
}}
].

View File

@ -25,12 +25,9 @@
-export([issue_access_token/2]).
-export([merge_and_compact/2]).
-export([get_time/2]).
-export([get_split_interval/2]).
-export([get_time_diff/2]).
-export([collect_events/4]).
-export([unwrap_payment_session/1]).
-export([wrap_payment_session/2]).
-export([get_invoice_by_id/2]).
-export([get_payment_by_id/3]).
@ -167,20 +164,6 @@ get_time(Key, Req) ->
undefined
end.
-spec get_split_interval(integer(), atom()) -> integer().
get_split_interval(SplitSize, minute) -> SplitSize * 60;
get_split_interval(SplitSize, hour) -> get_split_interval(SplitSize, minute) * 60;
get_split_interval(SplitSize, day) -> get_split_interval(SplitSize, hour) * 24;
get_split_interval(SplitSize, week) -> get_split_interval(SplitSize, day) * 7;
get_split_interval(SplitSize, month) -> get_split_interval(SplitSize, day) * 30;
get_split_interval(SplitSize, year) -> get_split_interval(SplitSize, day) * 365.
-spec get_time_diff(binary(), binary()) -> integer().
get_time_diff(From, To) ->
UnixFrom = genlib_rfc3339:parse(From, second),
UnixTo = genlib_rfc3339:parse(To, second),
UnixTo - UnixFrom.
-spec collect_events(
integer(),
integer(),
@ -254,13 +237,6 @@ unwrap_payment_session(Encoded) ->
end,
{ClientInfo, PaymentSession}.
-spec wrap_payment_session(map(), binary()) -> binary().
wrap_payment_session(ClientInfo, PaymentSession) ->
capi_utils:map_to_base64url(#{
<<"clientInfo">> => ClientInfo,
<<"paymentSession">> => PaymentSession
}).
-spec get_invoice_by_id(binary(), processing_context()) -> woody:result().
get_invoice_by_id(InvoiceID, Context) ->
EventRange = #payproc_EventRange{},

View File

@ -2,7 +2,6 @@
-export([create_party/3]).
-export([get_party/2]).
-export([checkout_party/3]).
-export([activate_party/2]).
-export([suspend_party/2]).
-export([get_contract/3]).
@ -11,25 +10,16 @@
-export([activate_shop/3]).
-export([suspend_shop/3]).
-export([compute_payment_institution_terms/3]).
-export([create_claim/3]).
-export([revoke_claim/5]).
-export([get_claim/3]).
-export([get_claims/2]).
-type result() :: ok | {ok, woody:result()} | {error, woody_error:business_error()}.
-type processing_context() :: capi_handler:processing_context().
-type party_id() :: party_client_thrift:party_id().
-type party_params() :: party_client_thrift:party_params().
-type party_revision_param() :: party_client_thrift:party_revision_param().
-type payment_institution_ref() :: party_client_thrift:payment_institution_ref().
-type varset() :: party_client_thrift:varset().
-type contract_id() :: party_client_thrift:contract_id().
-type shop_id() :: party_client_thrift:shop_id().
-type claim_id() :: party_client_thrift:claim_id().
-type claim_revision() :: party_client_thrift:claim_revision().
-type changeset() :: party_client_thrift:changeset().
-type revoke_reason() :: party_client_thrift:revoke_reason().
-spec create_party(party_id(), party_params(), processing_context()) -> result().
create_party(PartyID, PartyParams, Context) ->
@ -41,11 +31,6 @@ get_party(PartyID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:get(PartyID, Client, ClientContext).
-spec checkout_party(party_id(), party_revision_param(), processing_context()) -> result().
checkout_party(PartyID, PartyRevision, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:checkout(PartyID, PartyRevision, Client, ClientContext).
-spec activate_party(party_id(), processing_context()) -> result().
activate_party(PartyID, Context) ->
{Client, ClientContext} = client_context(Context),
@ -95,38 +80,5 @@ compute_payment_institution_terms(Ref, Varset, Context) ->
ClientContext
).
-spec create_claim(party_id(), changeset(), processing_context()) -> result().
create_claim(PartyID, Changeset, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:create_claim(PartyID, Changeset, Client, ClientContext).
-spec revoke_claim(
party_id(),
claim_id(),
claim_revision(),
revoke_reason(),
processing_context()
) -> result().
revoke_claim(PartyID, ClaimID, Revision, Reason, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:revoke_claim(
PartyID,
ClaimID,
Revision,
Reason,
Client,
ClientContext
).
-spec get_claim(party_id(), claim_id(), processing_context()) -> result().
get_claim(PartyID, ClaimID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:get_claim(PartyID, ClaimID, Client, ClientContext).
-spec get_claims(party_id(), processing_context()) -> result().
get_claims(PartyID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:get_claims(PartyID, Client, ClientContext).
client_context(#{party_client := Client, party_client_context := ClientContext}) ->
{Client, ClientContext}.

View File

@ -8,7 +8,6 @@
-include_lib("damsel/include/dmsl_webhooker_thrift.hrl").
-include_lib("damsel/include/dmsl_base_thrift.hrl").
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("reporter_proto/include/reporter_reports_thrift.hrl").
-include_lib("payout_manager_proto/include/payouts_payout_manager_thrift.hrl").
-include_lib("capi_dummy_data.hrl").
-include_lib("capi_bouncer_data.hrl").
@ -38,6 +37,7 @@
create_customer_access_token_ok_test/1,
rescind_invoice_ok_test/1,
fulfill_invoice_ok_test/1,
get_payment_status_preauthorization_failed_test/1,
get_payment_status_payment_tool_rejected_test/1,
get_payment_status_account_limit_exceeded_test/1,
@ -54,6 +54,7 @@
create_partial_refund_without_currency/1,
get_refund_by_id/1,
get_refunds/1,
get_chargebacks/1,
get_chargeback_by_id/1,
get_refund_by_external_id/1,
update_invoice_template_ok_test/1,
@ -78,12 +79,6 @@
get_shops_for_party_error_test/1,
suspend_shop_for_party_error_test/1,
activate_shop_for_party_error_test/1,
get_claim_by_id_ok_test/1,
get_claims_ok_test/1,
revoke_claim_ok_test/1,
create_claim_ok_test/1,
update_claim_by_id_test/1,
create_claim_invalid_residence_test/1,
get_contract_by_id_ok_test/1,
get_contract_by_id_for_party_ok_test/1,
get_contracts_ok_test/1,
@ -105,16 +100,6 @@
get_webhooks/1,
get_webhook_by_id/1,
delete_webhook_by_id/1,
get_reports_ok_test/1,
get_reports_for_party_ok_test/1,
get_report_ok_test/1,
get_report_for_party_ok_test/1,
get_report_not_found_test/1,
create_report_ok_test/1,
create_report_for_party_ok_test/1,
download_report_file_ok_test/1,
download_report_file_for_party_ok_test/1,
download_report_file_not_found_test/1,
get_categories_ok_test/1,
get_category_by_ref_ok_test/1,
get_schedule_by_ref_ok_test/1,
@ -196,12 +181,6 @@ groups() ->
get_categories_ok_test,
get_claim_by_id_ok_test,
get_claims_ok_test,
revoke_claim_ok_test,
create_claim_ok_test,
update_claim_by_id_test,
create_claim_invalid_residence_test,
get_contract_by_id_ok_test,
get_contract_by_id_for_party_ok_test,
get_contracts_ok_test,
@ -228,6 +207,7 @@ groups() ->
create_refund_expired_error,
create_partial_refund,
create_partial_refund_without_currency,
get_chargebacks,
get_chargeback_by_id,
get_refund_by_id,
get_refunds,
@ -270,18 +250,7 @@ groups() ->
create_payout,
create_payout_autorization_error,
get_payout,
get_payout_fail,
get_reports_ok_test,
get_reports_for_party_ok_test,
get_report_ok_test,
get_report_for_party_ok_test,
get_report_not_found_test,
create_report_ok_test,
create_report_for_party_ok_test,
download_report_file_ok_test,
download_report_file_for_party_ok_test,
download_report_file_not_found_test
get_payout_fail
]}
].
@ -773,7 +742,7 @@ create_payment_ok_test(Config) ->
context = ?CONTENT
} =
PaymentParams,
{ok, ?PAYPROC_PAYMENT(ID, EID)}
{ok, ?PAYPROC_PAYMENT(?PAYMENT_W_EXTERNAL_ID(ID, EID))}
end},
{party_management, fun('GetShop', _) ->
{ok, ?SHOP}
@ -896,7 +865,7 @@ create_partial_refund(Config) ->
_,
#payproc_InvoicePaymentRefundParams{
cash = ?CASH,
cart = ?THRIFT_INVOICE_CART
cart = ?INVOICE_CART(#{<<"TaxMode">> := {str, <<"10%">>}})
}
}
) ->
@ -910,7 +879,7 @@ create_partial_refund(Config) ->
<<"reason">> => ?STRING,
<<"currency">> => ?RUB,
<<"amount">> => ?INTEGER,
<<"cart">> => ?INVOICE_CART
<<"cart">> => ?SWAG_INVOICE_CART
},
_ = capi_ct_helper_bouncer:mock_assert_payment_op_ctx(
<<"CreateRefund">>,
@ -1033,8 +1002,8 @@ get_refund_by_external_id(Config) ->
%
-spec get_chargeback_by_id(config()) -> _.
get_chargeback_by_id(Config) ->
-spec get_chargebacks(config()) -> _.
get_chargebacks(Config) ->
_ = capi_ct_helper:mock_services(
[
{invoicing, fun('Get', _) ->
@ -1053,6 +1022,26 @@ get_chargeback_by_id(Config) ->
),
{ok, _} = capi_client_payments:get_chargebacks(?config(context, Config), ?STRING, ?STRING).
-spec get_chargeback_by_id(config()) -> _.
get_chargeback_by_id(Config) ->
_ = capi_ct_helper:mock_services(
[
{invoicing, fun('Get', _) ->
{ok, ?PAYPROC_INVOICE([?PAYPROC_PAYMENT])}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_payment_op_ctx(
<<"GetChargebackByID">>,
?STRING,
?STRING,
?STRING,
?STRING,
Config
),
{ok, _} = capi_client_payments:get_chargeback_by_id(?config(context, Config), ?STRING, ?STRING, ?STRING).
%
-spec update_invoice_template_ok_test(config()) -> _.
@ -1388,213 +1377,6 @@ suspend_shop_for_party_error_test(Config) ->
capi_client_shops:suspend_shop_for_party(?config(context, Config), <<"WrongPartyID">>, ?STRING)
).
-spec get_claim_by_id_ok_test(config()) -> _.
get_claim_by_id_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{party_management, fun('GetClaim', _) -> {ok, ?CLAIM(?CLAIM_CHANGESET)} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_claim_op_ctx(<<"GetClaimByID">>, ?STRING, ?INTEGER_BINARY, Config),
{ok, _} = capi_client_claims:get_claim_by_id(?config(context, Config), ?INTEGER).
-spec get_claims_ok_test(config()) -> _.
get_claims_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{party_management, fun('GetClaims', _) ->
{ok, [
?CLAIM(?CLAIM_CHANGESET),
?CLAIM(?CONTRACTOR_CLAIM_CHANGESET),
?CLAIM(?WALLET_CLAIM_CHANGESET)
]}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"GetClaims">>, ?STRING, Config),
{ok, [_OnlyOneClaim]} = capi_client_claims:get_claims(?config(context, Config)).
-spec revoke_claim_ok_test(config()) -> _.
revoke_claim_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('RevokeClaim', _) -> {ok, ok} end}], Config),
_ = capi_ct_helper_bouncer:mock_assert_claim_op_ctx(
<<"RevokeClaimByID">>,
?STRING,
?INTEGER_BINARY,
Config
),
ok = capi_client_claims:revoke_claim_by_id(?config(context, Config), ?STRING, ?INTEGER, ?INTEGER).
-spec create_claim_ok_test(config()) -> _.
create_claim_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{party_management, fun('CreateClaim', _) -> {ok, ?CLAIM(?CLAIM_CHANGESET)} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"CreateClaim">>, ?STRING, Config),
Changeset = [
#{
<<"partyModificationType">> => <<"ContractModification">>,
<<"contractID">> => ?STRING,
<<"contractModificationType">> => <<"ContractCreation">>,
<<"contractor">> => #{
<<"contractorType">> => <<"LegalEntity">>,
<<"entityType">> => <<"RussianLegalEntity">>,
<<"registeredName">> => <<"testRegisteredName">>,
<<"registeredNumber">> => <<"1234567890123">>,
<<"inn">> => <<"1234567890">>,
<<"actualAddress">> => <<"testActualAddress">>,
<<"postAddress">> => <<"testPostAddress">>,
<<"representativePosition">> => <<"testRepresentativePosition">>,
<<"representativeFullName">> => <<"testRepresentativeFullName">>,
<<"representativeDocument">> => <<"testRepresentativeDocument">>,
<<"bankAccount">> => #{
<<"account">> => <<"12345678901234567890">>,
<<"bankName">> => <<"testBankName">>,
<<"bankPostAccount">> => <<"12345678901234567890">>,
<<"bankBik">> => <<"123456789">>
}
},
<<"paymentInstitutionID">> => ?INTEGER
},
#{
<<"partyModificationType">> => <<"ContractModification">>,
<<"contractID">> => <<"PrivateEntityContract">>,
<<"contractModificationType">> => <<"ContractCreation">>,
<<"contractor">> => #{
<<"contractorType">> => <<"PrivateEntity">>,
<<"entityType">> => <<"RussianPrivateEntity">>,
<<"firstName">> => ?STRING,
<<"secondName">> => ?STRING,
<<"middleName">> => ?STRING,
<<"contactInfo">> => #{}
},
<<"paymentInstitutionID">> => ?INTEGER
},
#{
<<"partyModificationType">> => <<"ContractModification">>,
<<"contractID">> => ?STRING,
<<"contractModificationType">> => <<"ContractPayoutToolCreation">>,
<<"payoutToolID">> => ?STRING,
<<"currency">> => ?RUB,
<<"details">> => #{
<<"detailsType">> => <<"PayoutToolDetailsBankAccount">>,
<<"account">> => <<"12345678901234567890">>,
<<"bankName">> => <<"testBankName">>,
<<"bankPostAccount">> => <<"12345678901234567890">>,
<<"bankBik">> => <<"123456789">>
}
},
#{
<<"partyModificationType">> => <<"ContractModification">>,
<<"contractID">> => ?STRING,
<<"contractModificationType">> => <<"ContractPayoutToolCreation">>,
<<"payoutToolID">> => ?STRING,
<<"currency">> => ?USD,
<<"details">> => #{
<<"detailsType">> => <<"PayoutToolDetailsInternationalBankAccount">>,
<<"number">> => <<"12345678901234567890">>,
<<"iban">> => <<"GR1601101250000000012300695">>,
<<"bankDetails">> => #{
<<"bik">> => <<"123456789">>,
<<"countryCode">> => <<"USA">>,
<<"name">> => <<"testUsaBankName">>,
<<"address">> => ?STRING
},
<<"correspondentBankAccount">> => #{
<<"number">> => <<"00000000000000000000">>
}
}
},
#{
<<"partyModificationType">> => <<"ContractModification">>,
<<"contractID">> => ?STRING,
<<"contractModificationType">> => <<"ContractPayoutToolInfoModification">>,
<<"payoutToolID">> => ?STRING,
<<"details">> => #{
<<"detailsType">> => <<"PayoutToolDetailsInternationalBankAccount">>,
<<"number">> => <<"12345678901234567890">>,
<<"iban">> => <<"GR1601101250000000012300695">>,
<<"bankDetails">> => #{
<<"aba_rtn">> => <<"129131673">>,
<<"countryCode">> => <<"USA">>,
<<"name">> => <<"testUsaBankName">>,
<<"address">> => ?STRING
},
<<"correspondentBankAccount">> => #{
<<"number">> => <<"00000000000000000000">>
}
}
},
#{
<<"partyModificationType">> => <<"ContractModification">>,
<<"contractID">> => ?STRING,
<<"contractModificationType">> => <<"ContractLegalAgreementBinding">>,
<<"legalAgreement">> => #{
<<"id">> => ?STRING,
<<"signedAt">> => ?TIMESTAMP,
<<"validUntil">> => ?TIMESTAMP
}
},
#{
<<"partyModificationType">> => <<"ContractModification">>,
<<"contractID">> => ?STRING,
<<"contractModificationType">> => <<"ContractReportingPreferencesChange">>,
<<"serviceAcceptanceActPreferences">> => #{
<<"scheduleID">> => ?INTEGER,
<<"signer">> => #{
<<"position">> => ?STRING,
<<"fullName">> => ?STRING,
<<"document">> => #{<<"representativeDocumentType">> => <<"ArticlesOfAssociation">>}
}
}
}
],
{ok, _} = capi_client_claims:create_claim(?config(context, Config), Changeset).
-spec update_claim_by_id_test(config()) -> _.
update_claim_by_id_test(_) ->
% Not realised yet.
ok.
-spec create_claim_invalid_residence_test(config()) -> _.
create_claim_invalid_residence_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{party_management, fun('CreateClaim', _) -> {ok, ?CLAIM(?CLAIM_CHANGESET)} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"CreateClaim">>, ?STRING, Config),
Changeset = [
#{
<<"partyModificationType">> => <<"ContractModification">>,
<<"contractID">> => ?STRING,
<<"contractModificationType">> => <<"ContractPayoutToolCreation">>,
<<"payoutToolID">> => ?STRING,
<<"currency">> => ?USD,
<<"details">> => #{
<<"detailsType">> => <<"PayoutToolDetailsInternationalBankAccount">>,
<<"number">> => <<"12345678901234567890">>,
<<"iban">> => <<"GR1601101250000000012300695">>,
<<"bankDetails">> => #{
<<"bik">> => <<"123456789">>,
<<"countryCode">> => <<"EUR">>,
<<"name">> => <<"testBankName">>,
<<"address">> => ?STRING
},
<<"correspondentBankAccount">> => #{
<<"number">> => <<"00000000000000000000">>
}
}
}
],
{error, {400, _}} = capi_client_claims:create_claim(?config(context, Config), Changeset).
-spec get_contract_by_id_ok_test(config()) -> _.
get_contract_by_id_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
@ -1959,178 +1741,6 @@ delete_webhook_by_id(Config) ->
),
ok = capi_client_webhooks:delete_webhook_by_id(?config(context, Config), ?INTEGER_BINARY).
-spec get_reports_ok_test(config()) -> _.
get_reports_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{reporting, fun('GetReports', _) -> {ok, ?FOUND_REPORTS} end}], Config),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"GetReports">>, ?STRING, Config),
{ok, _} = capi_client_reports:get_reports(?config(context, Config), ?STRING, ?TIMESTAMP, ?TIMESTAMP).
-spec get_reports_for_party_ok_test(config()) -> _.
get_reports_for_party_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{reporting, fun('GetReports', _) -> {ok, ?FOUND_REPORTS} end}], Config),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"GetReportsForParty">>, ?STRING, Config),
{ok, _} = capi_client_reports:get_reports_for_party(
?config(context, Config),
?STRING,
?STRING,
?TIMESTAMP,
?TIMESTAMP
).
-spec get_report_ok_test(config()) -> _.
get_report_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{reporting, fun('GetReport', _) -> {ok, ?REPORT} end}], Config),
_ = capi_ct_helper_bouncer:mock_assert_report_op_ctx(
<<"GetReport">>,
?STRING,
?STRING,
?INTEGER_BINARY,
[?CTX_ENTITY(?STRING)],
Config
),
{ok, _} = capi_client_reports:get_report(?config(context, Config), ?STRING, ?INTEGER_BINARY).
-spec get_report_for_party_ok_test(config()) -> _.
get_report_for_party_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{reporting, fun('GetReport', _) -> {ok, ?REPORT} end}], Config),
_ = capi_ct_helper_bouncer:mock_assert_report_op_ctx(
<<"GetReportForParty">>,
?STRING,
?STRING,
?INTEGER_BINARY,
[?CTX_ENTITY(?STRING)],
Config
),
{ok, _} = capi_client_reports:get_report_for_party(?config(context, Config), ?STRING, ?STRING, ?INTEGER_BINARY).
-spec get_report_not_found_test(config()) -> _.
get_report_not_found_test(Config) ->
_ = capi_ct_helper:mock_services([{reporting, fun('GetReport', _) -> {ok, ?REPORT} end}], Config),
_ = capi_ct_helper_bouncer:mock_assert_report_op_ctx(
<<"GetReport">>,
?STRING,
?STRING,
?INTEGER_BINARY,
[?CTX_ENTITY(?STRING)],
Config
),
{error, {404, #{<<"message">> := <<"Report not found">>}}} =
capi_client_reports:get_report(?config(context, Config), <<"WRONG_STRING">>, ?INTEGER_BINARY).
-spec create_report_ok_test(config()) -> _.
create_report_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{reporting, fun
('CreateReport', _) -> {ok, ?INTEGER};
('GetReport', {?INTEGER}) -> {ok, ?REPORT}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"CreateReport">>, ?STRING, Config),
{ok, _} = capi_client_reports:create_report(
?config(context, Config),
?STRING,
?REPORT_TYPE,
?TIMESTAMP,
?TIMESTAMP
).
-spec create_report_for_party_ok_test(config()) -> _.
create_report_for_party_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{reporting, fun
('CreateReport', _) -> {ok, ?INTEGER};
('GetReport', {?INTEGER}) -> {ok, ?REPORT}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"CreateReportForParty">>, ?STRING, Config),
{ok, _} = capi_client_reports:create_report_for_party(
?config(context, Config),
?STRING,
?STRING,
?REPORT_TYPE,
?TIMESTAMP,
?TIMESTAMP
).
-spec download_report_file_ok_test(_) -> _.
download_report_file_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{reporting, fun
('GetReport', _) -> {ok, ?REPORT};
('GeneratePresignedUrl', _) -> {ok, ?STRING}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_report_op_ctx(
<<"DownloadFile">>,
?STRING,
?STRING,
?INTEGER_BINARY,
?STRING,
[?CTX_ENTITY(?STRING)],
Config
),
{ok, _} = capi_client_reports:download_file(?config(context, Config), ?STRING, ?INTEGER_BINARY, ?STRING).
-spec download_report_file_for_party_ok_test(_) -> _.
download_report_file_for_party_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{reporting, fun
('GetReport', _) -> {ok, ?REPORT};
('GeneratePresignedUrl', _) -> {ok, ?STRING}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_report_op_ctx(
<<"DownloadFileForParty">>,
?STRING,
?STRING,
?INTEGER_BINARY,
?STRING,
[?CTX_ENTITY(?STRING)],
Config
),
{ok, _} = capi_client_reports:download_file_for_party(
?config(context, Config),
?STRING,
?STRING,
?INTEGER_BINARY,
?STRING
).
-spec download_report_file_not_found_test(_) -> _.
download_report_file_not_found_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{reporting, fun
('GetReport', _) -> {ok, ?REPORT};
('GeneratePresignedUrl', _) -> {ok, ?STRING}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_report_op_ctx(
<<"DownloadFile">>,
?STRING,
?STRING,
?INTEGER_BINARY,
?STRING,
[?CTX_ENTITY(?STRING)],
Config
),
{error, {404, #{<<"message">> := <<"Report not found">>}}} =
capi_client_reports:download_file(?config(context, Config), <<"WRONG_STRING">>, ?INTEGER_BINARY, ?STRING).
-spec get_categories_ok_test(config()) -> _.
get_categories_ok_test(Config) ->
_ = capi_ct_helper_bouncer:mock_assert_op_ctx(<<"GetCategories">>, Config),
@ -2209,7 +1819,7 @@ retrieve_payment_by_external_id_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{invoicing, fun('Get', _) ->
{ok, ?PAYPROC_INVOICE([?PAYPROC_PAYMENT(PaymentID, ExternalID)])}
{ok, ?PAYPROC_INVOICE([?PAYPROC_PAYMENT(?PAYMENT_W_EXTERNAL_ID(PaymentID, ExternalID))])}
end},
{bender, fun('GetInternalID', _) ->
{ok, capi_ct_helper_bender:get_internal_id_result(PaymentID, BenderContext)}

View File

@ -1,6 +1,8 @@
-ifndef(capi_bouncer_data_included__).
-define(capi_bouncer_data_included__, ok).
-include_lib("stdlib/include/assert.hrl").
-include_lib("bouncer_proto/include/bouncer_decision_thrift.hrl").
-include_lib("bouncer_proto/include/bouncer_base_thrift.hrl").
-include_lib("bouncer_proto/include/bouncer_ctx_thrift.hrl").
@ -83,63 +85,17 @@
party = ?CTX_ENTITY(PartyID)
}).
-define(CTX_SEARCH_INVOICE_OP(ID, PartyID, ShopID, InvoiceID, PaymentID, CustomerID), #ctx_v1_CommonAPIOperation{
id = ID,
party = ?CTX_ENTITY(PartyID),
shop = ?CTX_ENTITY(ShopID),
invoice = ?CTX_ENTITY(InvoiceID),
payment = ?CTX_ENTITY(PaymentID),
customer = ?CTX_ENTITY(CustomerID)
}).
-define(CTX_SEARCH_PAYMENT_OP(ID, PartyID, ShopID, InvoiceID, PaymentID), #ctx_v1_CommonAPIOperation{
id = ID,
party = ?CTX_ENTITY(PartyID),
shop = ?CTX_ENTITY(ShopID),
invoice = ?CTX_ENTITY(InvoiceID),
payment = ?CTX_ENTITY(PaymentID)
}).
-define(CTX_SEARCH_PAYMENT_OP(ID, PartyID, ShopID), #ctx_v1_CommonAPIOperation{
id = ID,
party = ?CTX_ENTITY(PartyID),
shop = ?CTX_ENTITY(ShopID)
}).
-define(CTX_SEARCH_PAYOUT_OP(ID, PartyID, ShopID, PayoutID), #ctx_v1_CommonAPIOperation{
id = ID,
party = ?CTX_ENTITY(PartyID),
shop = ?CTX_ENTITY(ShopID),
payout = ?CTX_ENTITY(PayoutID)
}).
-define(CTX_REPORT_OP(ID, ReportID), #ctx_v1_CommonAPIOperation{
id = ID,
report = ?CTX_ENTITY(ReportID)
}).
-define(CTX_REPORT_OP(ID, PartyID, ShopID, ReportID, FileID), #ctx_v1_CommonAPIOperation{
id = ID,
party = ?CTX_ENTITY(PartyID),
shop = ?CTX_ENTITY(ShopID),
report = ?CTX_ENTITY(ReportID),
file = ?CTX_ENTITY(FileID)
}).
-define(CTX_FILE_OP(ID, ReportID, FileID), #ctx_v1_CommonAPIOperation{
id = ID,
report = ?CTX_ENTITY(ReportID),
file = ?CTX_ENTITY(FileID)
}).
-define(CTX_SEARCH_REFUND_OP(ID, PartyID, ShopID, InvoiceID, PaymentID, RefundID), #ctx_v1_CommonAPIOperation{
id = ID,
party = ?CTX_ENTITY(PartyID),
shop = ?CTX_ENTITY(ShopID),
invoice = ?CTX_ENTITY(InvoiceID),
payment = ?CTX_ENTITY(PaymentID),
refund = ?CTX_ENTITY(RefundID)
}).
-define(CTX_SEARCH_OP(ID, PartyID, ShopID, InvoiceID, PaymentID),
?CTX_SEARCH_OP(
ID,
PartyID,
ShopID,
InvoiceID,
PaymentID,
undefined,
undefined
)
).
-define(CTX_SEARCH_OP(
ID,
@ -148,27 +104,19 @@
InvoiceID,
PaymentID,
CustomerID,
PayoutID,
RefundID
),
#ctx_v1_CommonAPIOperation{
id = ID,
party = ?CTX_ENTITY(PartyID),
shop = ?CTX_ENTITY(ShopID),
invoice = ?CTX_ENTITY(InvoiceID),
payment = ?CTX_ENTITY(PaymentID),
customer = ?CTX_ENTITY(CustomerID),
payout = ?CTX_ENTITY(PayoutID),
refund = ?CTX_ENTITY(RefundID)
invoice = capi_utils:maybe(InvoiceID, fun(V) -> ?CTX_ENTITY(V) end),
payment = capi_utils:maybe(PaymentID, fun(V) -> ?CTX_ENTITY(V) end),
customer = capi_utils:maybe(CustomerID, fun(V) -> ?CTX_ENTITY(V) end),
refund = capi_utils:maybe(RefundID, fun(V) -> ?CTX_ENTITY(V) end)
}
).
-define(CTX_CLAIM_OP(ID, PartyID, ClaimID), #ctx_v1_CommonAPIOperation{
id = ID,
party = ?CTX_ENTITY(PartyID),
claim = ?CTX_ENTITY(ClaimID)
}).
-define(CTX_INVOICE(ID, PartyID, ShopID), #ctx_v1_Invoice{
id = ID,
party = ?CTX_ENTITY(PartyID),
@ -208,17 +156,6 @@
shop = ?CTX_ENTITY(ShopID)
}).
-define(CTX_REPORT(ID, PartyID, ShopID, Files), #ctx_v1_Report{
id = ID,
party = ?CTX_ENTITY(PartyID),
shop = ?CTX_ENTITY(ShopID),
files = Files
}).
-define(CTX_CONTEXT_REPORTS(Report), #ctx_v1_ContextReports{
report = Report
}).
-define(assertContextMatches(Expect), fun(Context) ->
try
?assertMatch(Expect, Context),

View File

@ -30,9 +30,6 @@
-define(CAPI_HOST_NAME, "localhost").
-define(CAPI_URL, ?CAPI_HOST_NAME ++ ":" ++ integer_to_list(?CAPI_PORT)).
-define(TK_META_NS_KEYCLOAK, <<"dev.vality.keycloak">>).
-define(TK_META_NS_APIKEYMGMT, <<"dev.vality.apikeymgmt">>).
%%
-type config() :: [{atom(), any()}].
-type app_name() :: atom().

View File

@ -1,15 +1,11 @@
-module(capi_ct_helper_bouncer).
-include_lib("common_test/include/ct.hrl").
-include_lib("capi_dummy_data.hrl").
-include_lib("capi_bouncer_data.hrl").
-include_lib("stdlib/include/assert.hrl").
-export([mock_assert_op_ctx/2]).
-export([mock_assert_party_op_ctx/3]).
-export([mock_assert_shop_op_ctx/4]).
-export([mock_assert_report_op_ctx/6]).
-export([mock_assert_report_op_ctx/7]).
-export([mock_assert_contract_op_ctx/4]).
-export([mock_assert_invoice_op_ctx/5]).
-export([mock_assert_payment_op_ctx/5]).
@ -17,14 +13,10 @@
-export([mock_assert_refund_op_ctx/7]).
-export([mock_assert_invoice_tpl_op_ctx/5]).
-export([mock_assert_customer_op_ctx/5]).
-export([mock_assert_claim_op_ctx/4]).
-export([mock_assert_webhook_op_ctx/4]).
-export([mock_assert_payout_op_ctx/6]).
-export([mock_assert_search_invoice_op_ctx/7]).
-export([mock_assert_search_payment_op_ctx/4]).
-export([mock_assert_search_payment_op_ctx/6]).
-export([mock_assert_search_payout_op_ctx/5]).
-export([mock_assert_search_refund_op_ctx/7]).
-export([mock_assert_search_op_ctx/2]).
-export([mock_assert_search_op_ctx/3]).
-export([mock_client/1]).
-export([mock_arbiter/2]).
@ -161,17 +153,6 @@ mock_assert_customer_op_ctx(Op, CustomerID, PartyID, ShopID, Config) ->
Config
).
-spec mock_assert_claim_op_ctx(_, _, _, _) -> _.
mock_assert_claim_op_ctx(Op, PartyID, ClaimID, Config) ->
mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(?CTX_CLAIM_OP(Op, PartyID, ClaimID))
}
),
Config
).
-spec mock_assert_webhook_op_ctx(_, _, _, _) -> _.
mock_assert_webhook_op_ctx(Op, WebhookID, PartyID, Config) ->
mock_arbiter(
@ -200,13 +181,8 @@ mock_assert_payout_op_ctx(Op, PayoutID, PartyID, ContractID, ShopID, Config) ->
Config
).
-spec mock_assert_search_payment_op_ctx(_, _, _, _) -> _.
mock_assert_search_payment_op_ctx(Op, PartyID, ShopID, Config) ->
SearchCtx = ?CTX_SEARCH_PAYMENT_OP(
Op,
PartyID,
ShopID
),
-spec mock_assert_search_op_ctx(_, _) -> _.
mock_assert_search_op_ctx(SearchCtx, Config) ->
mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
@ -216,97 +192,13 @@ mock_assert_search_payment_op_ctx(Op, PartyID, ShopID, Config) ->
Config
).
-spec mock_assert_search_payment_op_ctx(_, _, _, _, _, _) -> _.
mock_assert_search_payment_op_ctx(Op, PartyID, ShopID, InvoiceID, PaymentID, Config) ->
SearchCtx = ?CTX_SEARCH_PAYMENT_OP(
Op,
PartyID,
ShopID,
InvoiceID,
PaymentID
),
-spec mock_assert_search_op_ctx(_, _, _) -> _.
mock_assert_search_op_ctx(SearchCtx, PayprocCtx, Config) ->
mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(SearchCtx)
}
),
Config
).
-spec mock_assert_search_invoice_op_ctx(_, _, _, _, _, _, _) -> _.
mock_assert_search_invoice_op_ctx(Op, PartyID, ShopID, InvoiceID, PaymentID, CustomerID, Config) ->
SearchCtx = ?CTX_SEARCH_INVOICE_OP(
Op,
PartyID,
ShopID,
InvoiceID,
PaymentID,
CustomerID
),
mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(SearchCtx)
}
),
Config
).
-spec mock_assert_search_refund_op_ctx(_, _, _, _, _, _, _) -> _.
mock_assert_search_refund_op_ctx(Op, PartyID, ShopID, InvoiceID, PaymentID, RefundID, Config) ->
SearchCtx = ?CTX_SEARCH_REFUND_OP(
Op,
PartyID,
ShopID,
InvoiceID,
PaymentID,
RefundID
),
mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(SearchCtx)
}
),
Config
).
-spec mock_assert_search_payout_op_ctx(_, _, _, _, _) -> _.
mock_assert_search_payout_op_ctx(Op, PartyID, ShopID, PayoutID, Config) ->
SearchCtx = ?CTX_SEARCH_PAYOUT_OP(
Op,
PartyID,
ShopID,
PayoutID
),
mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(SearchCtx)
}
),
Config
).
-spec mock_assert_report_op_ctx(_, _, _, _, _, _) -> _.
mock_assert_report_op_ctx(Op, PartyID, ShopID, ReportID, Files, Config) ->
mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(?CTX_REPORT_OP(Op, ReportID)),
reports = ?CTX_CONTEXT_REPORTS(?CTX_REPORT(ReportID, PartyID, ShopID, Files))
}
),
Config
).
-spec mock_assert_report_op_ctx(_, _, _, _, _, _, _) -> _.
mock_assert_report_op_ctx(Op, PartyID, ShopID, ReportID, FileID, Files, Config) ->
mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(?CTX_FILE_OP(Op, ReportID, FileID)),
reports = ?CTX_CONTEXT_REPORTS(?CTX_REPORT(ReportID, PartyID, ShopID, Files))
capi = ?CTX_CAPI(SearchCtx),
payment_processing = PayprocCtx
}
),
Config

View File

@ -26,6 +26,7 @@
-define(DETAILS, #domain_InvoiceDetails{
product = ?STRING,
description = ?STRING,
cart = ?INVOICE_CART,
bank_account = ?INVOICE_BANK_ACCOUNT
}).
@ -81,17 +82,15 @@
external_id = EID
}).
-define(INVOICE_CART_TAXMODE, #{
<<"type">> => <<"InvoiceLineTaxVAT">>,
<<"rate">> => <<"10%">>
}).
-define(INVOICE_CART, [
-define(SWAG_INVOICE_CART, [
#{
<<"taxMode">> => ?INVOICE_CART_TAXMODE,
<<"product">> => ?STRING,
<<"price">> => ?INTEGER,
<<"quantity">> => ?INTEGER
<<"quantity">> => ?INTEGER,
<<"taxMode">> => #{
<<"type">> => <<"InvoiceLineTaxVAT">>,
<<"rate">> => <<"10%">>
}
}
]).
@ -166,13 +165,14 @@
]
}).
-define(THRIFT_INVOICE_CART, #domain_InvoiceCart{
-define(INVOICE_CART, ?INVOICE_CART(#{<<"TaxMode">> => {str, <<"10%">>}})).
-define(INVOICE_CART(MD), #domain_InvoiceCart{
lines = [
#domain_InvoiceLine{
product = ?STRING,
quantity = ?INTEGER,
price = ?CASH,
metadata = #{<<"TaxMode">> := {str, <<"10%">>}}
metadata = MD
}
]
}).
@ -240,8 +240,8 @@
year = Year
}).
-define(DISP_PAYMENT_RESOURCE, #domain_DisposablePaymentResource{
payment_tool = {bank_card, ?BANK_CARD},
-define(DISP_PAYMENT_RESOURCE(PT), #domain_DisposablePaymentResource{
payment_tool = PT,
payment_session_id = ?STRING,
client_info = #domain_ClientInfo{
fingerprint = ?STRING,
@ -249,10 +249,7 @@
}
}).
-define(PAYMENT_RESOURCE_PAYER, #domain_PaymentResourcePayer{
resource = ?DISP_PAYMENT_RESOURCE,
contact_info = ?CONTACT_INFO
}).
-define(DISP_PAYMENT_RESOURCE, ?DISP_PAYMENT_RESOURCE({bank_card, ?BANK_CARD})).
-define(RECURRENT_PAYER,
{recurrent, #domain_RecurrentPayer{
@ -275,55 +272,43 @@
}}
).
-define(PAYER, {payment_resource, ?PAYMENT_RESOURCE_PAYER}).
-define(PAYER(PT),
{payment_resource, #domain_PaymentResourcePayer{
resource = ?DISP_PAYMENT_RESOURCE(PT),
contact_info = ?CONTACT_INFO
}}
).
-define(PAYER, ?PAYER({bank_card, ?BANK_CARD})).
-define(PAYER_SESSION_INFO, #domain_PayerSessionInfo{
redirect_url = ?URL
}).
-define(PAYMENT(ID, IED, Status), #domain_InvoicePayment{
-define(PAYMENT_STATUS_PENDING, {pending, #domain_InvoicePaymentPending{}}).
-define(PAYMENT_STATUS_FAILED(F), {failed, #domain_InvoicePaymentFailed{failure = F}}).
-define(PAYMENT(ID, Status, Payer, ExternalID), #domain_InvoicePayment{
id = ID,
created_at = ?TIMESTAMP,
domain_revision = ?INTEGER,
status = Status,
payer = ?PAYER,
payer = Payer,
payer_session_info = ?PAYER_SESSION_INFO,
cost = ?CASH,
flow = {instant, #domain_InvoicePaymentFlowInstant{}},
context = ?CONTENT,
make_recurrent = false,
external_id = IED
external_id = ExternalID
}).
-define(PAYMENT_WITH_RECURRENT_PAYER, #domain_InvoicePayment{
id = ?STRING,
created_at = ?TIMESTAMP,
domain_revision = ?INTEGER,
status = {pending, #domain_InvoicePaymentPending{}},
payer = ?RECURRENT_PAYER,
cost = ?CASH,
flow = {instant, #domain_InvoicePaymentFlowInstant{}},
context = ?CONTENT,
make_recurrent = false,
external_id = undefined
}).
-define(PAYMENT(ID, Status, Payer), ?PAYMENT(ID, Status, Payer, undefined)).
-define(PAYMENT, ?PAYMENT(?STRING, ?PAYMENT_STATUS_PENDING, ?PAYER)).
-define(PAYMENT_WITH_CUSTOMER_PAYER, #domain_InvoicePayment{
id = ?STRING,
created_at = ?TIMESTAMP,
domain_revision = ?INTEGER,
status = {pending, #domain_InvoicePaymentPending{}},
payer = ?CUSTOMER_PAYER,
cost = ?CASH,
flow = {instant, #domain_InvoicePaymentFlowInstant{}},
context = ?CONTENT,
make_recurrent = false,
external_id = undefined
}).
-define(PAYMENT_WITH_RECURRENT_PAYER, ?PAYMENT(?STRING, ?PAYMENT_STATUS_PENDING, ?RECURRENT_PAYER)).
-define(PAYMENT_WITH_CUSTOMER_PAYER, ?PAYMENT(?STRING, ?PAYMENT_STATUS_PENDING, ?CUSTOMER_PAYER)).
-define(PAYMENT, ?PAYMENT(?STRING, undefined, {pending, #domain_InvoicePaymentPending{}})).
-define(PAYMENT(ID, IED), ?PAYMENT(ID, IED, {pending, #domain_InvoicePaymentPending{}})).
-define(PAYMENT_W_EXTERNAL_ID(ID, ExternalID), ?PAYMENT(ID, ?PAYMENT_STATUS_PENDING, ?PAYER, ExternalID)).
-define(RECURRENT_PAYMENT(Status), #domain_InvoicePayment{
id = ?STRING,
@ -350,11 +335,11 @@
allocation = ?ALLOCATION
}).
-define(PAYPROC_PAYMENT(Payment), ?PAYPROC_PAYMENT(Payment, [?REFUND], [?ADJUSTMENT], [?PAYPROC_CHARGEBACK])).
-define(PAYPROC_PAYMENT, ?PAYPROC_PAYMENT(?PAYMENT, [?REFUND], [?ADJUSTMENT], [?PAYPROC_CHARGEBACK])).
-define(PAYPROC_PAYMENT(ID, IED), ?PAYPROC_PAYMENT(?PAYMENT(ID, IED), [?REFUND], [?ADJUSTMENT], [?PAYPROC_CHARGEBACK])).
-define(FAILED_PAYMENT(Failure), ?PAYMENT(?STRING, ?STRING, {failed, #domain_InvoicePaymentFailed{failure = Failure}})).
-define(FAILED_PAYMENT(Failure), ?PAYMENT(?STRING, ?PAYMENT_STATUS_FAILED(Failure), ?PAYER)).
-define(PAYPROC_FAILED_PAYMENT(Failure), ?PAYPROC_PAYMENT(?FAILED_PAYMENT(Failure), [?REFUND], [], [])).
@ -413,7 +398,7 @@
-define(CONTRACT, #domain_Contract{
id = ?STRING,
contractor = ?CONTRACTOR,
contractor = ?CONTRACTOR_REGISTERED_USER,
payment_institution = #domain_PaymentInstitutionRef{id = ?INTEGER},
created_at = ?TIMESTAMP,
valid_since = ?TIMESTAMP,
@ -426,10 +411,29 @@
?PAYOUT_TOOL(?BANKID_US, ?INTERNATIONAL_BANK_ACCOUNT),
?PAYOUT_TOOL(?WALLET_TOOL, ?WALLET_INFO),
?PAYOUT_TOOL(?PI_ACCOUNT_TOOL, ?PAYMENT_INSTITUTION_ACCOUNT)
]
],
legal_agreement = ?CONTRACT_LEGAL_AGREEMENT,
report_preferences = ?CONTRACT_REPORT_PREFS
}).
-define(CONTRACTOR, {registered_user, #domain_RegisteredUser{email = ?STRING}}).
-define(CONTRACT_LEGAL_AGREEMENT, #domain_LegalAgreement{
signed_at = ?TIMESTAMP,
legal_agreement_id = ?STRING,
valid_until = ?TIMESTAMP
}).
-define(CONTRACT_REPORT_PREFS, #domain_ReportPreferences{
service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{
schedule = #domain_BusinessScheduleRef{id = ?INTEGER},
signer = #domain_Representative{
position = ?STRING,
full_name = ?STRING,
document = {articles_of_association, #domain_ArticlesOfAssociation{}}
}
}
}).
-define(CONTRACTOR_REGISTERED_USER, {registered_user, #domain_RegisteredUser{email = ?STRING}}).
-define(BLOCKING,
{unblocked, #domain_Unblocked{
@ -525,160 +529,6 @@
revision = 0
}).
-define(CLAIM(Changeset), #payproc_Claim{
id = ?INTEGER,
revision = ?INTEGER,
created_at = ?TIMESTAMP,
updated_at = ?TIMESTAMP,
status = {pending, #payproc_ClaimPending{}},
changeset = Changeset
}).
-define(CLAIM_CHANGESET, [
%% contract modifications
{contract_modification, #payproc_ContractModificationUnit{
id = ?STRING,
modification =
{creation, #payproc_ContractParams{
contractor = ?CONTRACTOR,
payment_institution = #domain_PaymentInstitutionRef{id = ?INTEGER}
}}
}},
{contract_modification, #payproc_ContractModificationUnit{
id = ?STRING,
modification =
{termination, #payproc_ContractTermination{
reason = ?STRING
}}
}},
{contract_modification, #payproc_ContractModificationUnit{
id = ?STRING,
modification =
{adjustment_modification, #payproc_ContractAdjustmentModificationUnit{
adjustment_id = ?STRING,
modification =
{creation, #payproc_ContractAdjustmentParams{
template = #domain_ContractTemplateRef{id = ?INTEGER}
}}
}}
}},
{contract_modification, #payproc_ContractModificationUnit{
id = ?STRING,
modification =
{payout_tool_modification, #payproc_PayoutToolModificationUnit{
payout_tool_id = ?STRING,
modification =
{creation, #payproc_PayoutToolParams{
currency = #domain_CurrencyRef{symbolic_code = ?RUB},
tool_info = ?RUSSIAN_BANK_ACCOUNT
}}
}}
}},
{contract_modification, #payproc_ContractModificationUnit{
id = ?STRING,
modification =
{legal_agreement_binding, #domain_LegalAgreement{
signed_at = ?TIMESTAMP,
legal_agreement_id = ?STRING,
valid_until = ?TIMESTAMP
}}
}},
{contract_modification, #payproc_ContractModificationUnit{
id = ?STRING,
modification =
{report_preferences_modification, #domain_ReportPreferences{
service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{
schedule = #domain_BusinessScheduleRef{id = ?INTEGER},
signer = #domain_Representative{
position = ?STRING,
full_name = ?STRING,
document = {articles_of_association, #domain_ArticlesOfAssociation{}}
}
}
}}
}},
%% shop modifications
{shop_modification, #payproc_ShopModificationUnit{
id = ?STRING,
modification =
{creation, #payproc_ShopParams{
location = ?SHOP_LOCATION,
details = ?SHOP_DETAILS,
contract_id = ?STRING,
payout_tool_id = ?STRING
}}
}},
{shop_modification, #payproc_ShopModificationUnit{
id = ?STRING,
modification = {category_modification, #domain_CategoryRef{id = ?INTEGER}}
}},
{shop_modification, #payproc_ShopModificationUnit{
id = ?STRING,
modification = {details_modification, ?SHOP_DETAILS}
}},
{shop_modification, #payproc_ShopModificationUnit{
id = ?STRING,
modification =
{contract_modification, #payproc_ShopContractModification{
contract_id = ?STRING,
payout_tool_id = ?STRING
}}
}},
{shop_modification, #payproc_ShopModificationUnit{
id = ?STRING,
modification = {payout_tool_modification, ?STRING}
}},
{shop_modification, #payproc_ShopModificationUnit{
id = ?STRING,
modification = {location_modification, ?SHOP_LOCATION}
}},
{shop_modification, #payproc_ShopModificationUnit{
id = ?STRING,
modification =
{shop_account_creation, #payproc_ShopAccountParams{
currency = #domain_CurrencyRef{symbolic_code = ?RUB}
}}
}},
{shop_modification, #payproc_ShopModificationUnit{
id = ?STRING,
modification =
{payout_schedule_modification, #payproc_ScheduleModification{
schedule = #domain_BusinessScheduleRef{id = ?INTEGER}
}}
}}
]).
-define(CONTRACTOR_CLAIM_CHANGESET, [
%% contractor modifications
{contractor_modification, #payproc_ContractorModificationUnit{
id = ?STRING,
modification = {creation, ?CONTRACTOR}
}},
{contractor_modification, #payproc_ContractorModificationUnit{
id = ?STRING,
modification = {identification_level_modification, partial}
}},
{contractor_modification, #payproc_ContractorModificationUnit{
id = ?STRING,
modification =
{identity_documents_modification, #payproc_ContractorIdentityDocumentsModification{
identity_documents = []
}}
}}
]).
-define(WALLET_CLAIM_CHANGESET, [
%% wallet modifications
{wallet_modification, #payproc_WalletModificationUnit{
id = ?STRING,
modification =
{creation, #payproc_WalletParams{
name = ?STRING,
contract_id = ?WALLET_CONTRACT_ID
}}
}}
]).
-define(ADJUSTMENT, #domain_InvoicePaymentAdjustment{
id = ?STRING,
status = {pending, #domain_InvoicePaymentAdjustmentPending{}},
@ -866,6 +716,33 @@
enabled = true
}).
-define(STAT_RESPONSE_INVOICES, #magista_StatInvoiceResponse{
invoices = [
?STAT_INVOICE({unpaid, #domain_InvoiceUnpaid{}}),
?STAT_INVOICE({paid, #domain_InvoicePaid{}}),
?STAT_INVOICE({cancelled, #domain_InvoiceCancelled{details = ?STRING}}),
?STAT_INVOICE({fulfilled, #domain_InvoiceFulfilled{details = ?STRING}})
],
continuation_token = ?STRING
}).
-define(STAT_INVOICE(Status), #magista_StatInvoice{
id = ?STRING,
owner_id = ?STRING,
shop_id = ?STRING,
created_at = ?TIMESTAMP,
status = Status,
product = ?STRING,
description = ?STRING,
due = ?TIMESTAMP,
amount = ?INTEGER,
currency_symbolic_code = ?RUB,
context = ?CONTENT,
cart = ?INVOICE_CART,
external_id = ?STRING,
status_changed_at = ?TIMESTAMP
}).
-define(STAT_RESPONSE_PAYMENTS, #magista_StatPaymentResponse{
payments = [
?STAT_PAYMENT(
@ -931,46 +808,32 @@
{failed, #domain_InvoicePaymentFailed{failure = {failure, #domain_Failure{code = <<"error_code">>}}}}
).
-define(STAT_RECORD, #{
<<"offset">> => ?INTEGER_BINARY,
<<"successful_count">> => ?INTEGER_BINARY,
<<"total_count">> => ?INTEGER_BINARY,
<<"conversion">> => ?INTEGER_BINARY,
<<"city_id">> => ?INTEGER_BINARY,
<<"currency_symbolic_code">> => ?RUB,
<<"amount_with_fee">> => ?INTEGER_BINARY,
<<"amount_without_fee">> => ?INTEGER_BINARY,
<<"unic_count">> => ?INTEGER_BINARY,
<<"payment_system">> => <<"visa">>
}).
-define(REPORT_TYPE, <<"paymentRegistry">>).
-define(REPORT, #reports_Report{
report_id = ?INTEGER,
time_range = #reports_ReportTimeRange{
from_time = ?TIMESTAMP,
to_time = ?TIMESTAMP
},
created_at = ?TIMESTAMP,
report_type = <<"provision_of_service">>,
status = created,
files = [
#reports_FileMeta{
file_id = ?STRING,
filename = ?STRING,
signature = #reports_Signature{
md5 = ?MD5,
sha256 = ?SHA256
}
}
-define(STAT_RESPONSE_REFUNDS, #magista_StatRefundResponse{
refunds = [
?STAT_REFUND({pending, #domain_InvoicePaymentRefundPending{}}),
?STAT_REFUND({succeeded, #domain_InvoicePaymentRefundSucceeded{}})
?STAT_REFUND({failed, #domain_InvoicePaymentRefundFailed{
failure = {operation_timeout, #domain_OperationTimeout{}}
}})
],
shop_id = ?STRING,
party_id = ?STRING
continuation_token = ?STRING
}).
-define(FOUND_REPORTS, #'reports_StatReportResponse'{
reports = [?REPORT]
-define(STAT_REFUND(Status), #magista_StatRefund{
id = ?STRING,
payment_id = ?STRING,
invoice_id = ?STRING,
owner_id = ?STRING,
shop_id = ?STRING,
status = Status,
created_at = ?TIMESTAMP,
amount = ?INTEGER,
fee = ?INTEGER,
currency_symbolic_code = ?RUB,
reason = ?STRING,
cart = ?INVOICE_CART,
external_id = ?STRING,
status_changed_at = ?TIMESTAMP
}).
-define(SNAPSHOT, #'domain_conf_Snapshot'{

View File

@ -689,7 +689,7 @@ create_payment(BenderKey, Requests, Config) ->
{ok, ?PAYPROC_INVOICE};
('StartPayment', {_, IPP}) ->
#payproc_InvoicePaymentParams{id = ID, external_id = EID, context = ?CONTENT} = IPP,
{ok, ?PAYPROC_PAYMENT(ID, EID)}
{ok, ?PAYPROC_PAYMENT(?PAYMENT_W_EXTERNAL_ID(ID, EID))}
end},
{bender, fun('GenerateID', {_, _, CtxMsgPack}) ->
capi_ct_helper_bender:get_internal_id(Tid, BenderKey, CtxMsgPack)

View File

@ -287,7 +287,7 @@ create_payment_ok_test(Config) ->
payer_session_info = ?PAYER_SESSION_INFO,
context = ?CONTENT
} = PaymentParams,
{ok, ?PAYPROC_PAYMENT(ID, EID)}
{ok, ?PAYPROC_PAYMENT(?PAYMENT_W_EXTERNAL_ID(ID, EID))}
end},
{bender, fun('GenerateID', _) ->
{ok, capi_ct_helper_bender:get_result(BenderKey)}
@ -314,12 +314,8 @@ create_payment_expired_test(Config) ->
PaymentTool = {bank_card, ?BANK_CARD},
_ = capi_ct_helper:mock_services(
[
{invoicing, fun
('Get', _) ->
{ok, ?PAYPROC_INVOICE};
('StartPayment', {_, IPP}) ->
#payproc_InvoicePaymentParams{id = ID, external_id = EID, context = ?CONTENT} = IPP,
{ok, ?PAYPROC_PAYMENT(ID, EID)}
{invoicing, fun('Get', _) ->
{ok, ?PAYPROC_INVOICE}
end}
],
Config
@ -390,7 +386,7 @@ create_payment_w_payment_tool(PaymentTool, Config) ->
}},
Params#payproc_InvoicePaymentParams.payer
),
{ok, ?PAYPROC_PAYMENT}
{ok, ?PAYPROC_PAYMENT(?PAYMENT(?STRING, ?PAYMENT_STATUS_PENDING, ?PAYER(PaymentTool)))}
end},
{generator, fun('GenerateID', _) ->
capi_ct_helper_bender:generate_id(?STRING)
@ -535,7 +531,7 @@ capture_partial_payment_ok_test(Config) ->
_,
#payproc_InvoicePaymentCaptureParams{
cash = ?CASH,
cart = ?THRIFT_INVOICE_CART
cart = ?INVOICE_CART(#{<<"TaxMode">> := {str, <<"10%">>}})
}
}
) ->
@ -548,7 +544,7 @@ capture_partial_payment_ok_test(Config) ->
<<"reason">> => ?STRING,
<<"amount">> => ?INTEGER,
<<"currency">> => ?RUB,
<<"cart">> => ?INVOICE_CART
<<"cart">> => ?SWAG_INVOICE_CART
},
_ = capi_ct_helper_bouncer:mock_assert_payment_op_ctx(
<<"CapturePayment">>,

View File

@ -1,10 +1,10 @@
-module(capi_magista_stat_tests_SUITE).
-include_lib("common_test/include/ct.hrl").
-include_lib("stdlib/include/assert.hrl").
-include_lib("damsel/include/dmsl_base_thrift.hrl").
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("damsel/include/dmsl_payproc_thrift.hrl").
-include_lib("magista_proto/include/magista_magista_thrift.hrl").
-include_lib("capi_dummy_data.hrl").
-include_lib("capi_bouncer_data.hrl").
@ -21,8 +21,14 @@
-export([init/1]).
-export([
search_invoices_ok_test/1,
search_invoices_by_invoice_id_ok_test/1,
search_invoices_by_customer_id_ok_test/1,
search_payments_without_all_optional_fields_ok_test/1,
search_payments_ok_test/1,
search_refunds_ok_test/1,
search_refunds_by_refund_id_ok_test/1,
search_refunds_by_invoice_id_ok_test/1,
search_payments_invalid_request_test/1,
search_payments_invalid_token_test/1,
search_payments_limit_exceeded_test/1
@ -55,8 +61,14 @@ groups() ->
{group, operations_by_any_token}
]},
{operations_by_any_token, [], [
search_invoices_ok_test,
search_invoices_by_invoice_id_ok_test,
search_invoices_by_customer_id_ok_test,
search_payments_without_all_optional_fields_ok_test,
search_payments_ok_test,
search_refunds_ok_test,
search_refunds_by_refund_id_ok_test,
search_refunds_by_invoice_id_ok_test,
search_payments_invalid_request_test,
search_payments_invalid_token_test,
search_payments_limit_exceeded_test
@ -109,19 +121,103 @@ end_per_testcase(_Name, C) ->
%%% Tests
-spec search_invoices_ok_test(config()) -> _.
search_invoices_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{magista, fun('SearchInvoices', _) -> {ok, ?STAT_RESPONSE_INVOICES} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_search_op_ctx(
?CTX_SEARCH_OP(<<"SearchInvoices">>, ?STRING, ?STRING, undefined, undefined),
#ctx_v1_ContextPaymentProcessing{},
Config
),
{ok, _, _} = search_invoices([], Config),
{ok, _, _} = search_invoices([{'offset', 42}], Config),
{ok, _, _} = search_invoices([{'invoiceStatus', <<"unpaid">>}], Config),
{ok, _, _} = search_invoices([{'invoiceStatus', <<"cancelled">>}], Config),
{ok, _, _} = search_invoices([{'invoiceStatus', <<"fulfilled">>}, {'invoiceAmount', 42}], Config),
{ok, _, _} = search_invoices(
[
{'paymentStatus', <<"failed">>},
{'paymentAmount', 42},
{'payerEmail', ?EMAIL},
{'rrn', <<"090909090909">>},
{'approvalCode', <<"808080">>}
],
Config
).
-spec search_invoices_by_invoice_id_ok_test(config()) -> _.
search_invoices_by_invoice_id_ok_test(Config) ->
InvoiceID = <<"blarg">>,
PaymentID = <<"blorg">>,
_ = capi_ct_helper:mock_services(
[
{invoicing, fun('Get', _) -> {ok, ?PAYPROC_INVOICE_WITH_ID(InvoiceID)} end},
{magista, fun('SearchInvoices', _) -> {ok, ?STAT_RESPONSE_INVOICES} end}
],
Config
),
SearchCtx = ?CTX_SEARCH_OP(<<"SearchInvoices">>, ?STRING, ?STRING, InvoiceID, PaymentID),
_ = capi_ct_helper_bouncer:mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(SearchCtx),
payment_processing = #ctx_v1_ContextPaymentProcessing{
invoice = ?CTX_INVOICE(InvoiceID, ?STRING, ?STRING)
}
}
),
Config
),
{ok, _, _} = search_invoices([{'invoiceID', InvoiceID}, {'paymentID', PaymentID}], Config).
-spec search_invoices_by_customer_id_ok_test(config()) -> _.
search_invoices_by_customer_id_ok_test(Config) ->
CustomerID = <<"blerg">>,
_ = capi_ct_helper:mock_services(
[
{customer_management, fun('Get', _) -> {ok, ?CUSTOMER(CustomerID)} end},
{magista, fun('SearchInvoices', _) -> {ok, ?STAT_RESPONSE_INVOICES} end}
],
Config
),
SearchCtx = ?CTX_SEARCH_OP(<<"SearchInvoices">>, ?STRING, ?STRING, undefined, undefined, CustomerID, undefined),
_ = capi_ct_helper_bouncer:mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(SearchCtx),
payment_processing = #ctx_v1_ContextPaymentProcessing{
customer = ?CTX_CUSTOMER(CustomerID, ?STRING, ?STRING)
}
}
),
Config
),
{ok, _, _} = search_invoices([{'customerID', CustomerID}], Config).
search_invoices(Query, Config) ->
BaseQuery = [
{limit, 42},
{from_time, {{2015, 08, 11}, {19, 42, 35}}},
{to_time, {{2020, 08, 11}, {19, 42, 35}}},
{'continuationToken', <<"come_back_next_time">>}
],
capi_client_searches:search_invoices(?config(context, Config), ?STRING, BaseQuery ++ Query).
-spec search_payments_without_all_optional_fields_ok_test(config()) -> _.
search_payments_without_all_optional_fields_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
capi_test_hack:get_invoice_mock(),
{magista, fun('SearchPayments', _) -> {ok, ?STAT_RESPONSE_PAYMENTS} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_search_payment_op_ctx(
<<"SearchPayments">>,
?STRING,
?STRING,
_ = capi_ct_helper_bouncer:mock_assert_search_op_ctx(
?CTX_SEARCH_OP(<<"SearchPayments">>, ?STRING, ?STRING, undefined, undefined),
Config
),
Query = [
@ -135,44 +231,52 @@ search_payments_without_all_optional_fields_ok_test(Config) ->
search_payments_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
capi_test_hack:get_invoice_mock(),
{invoicing, fun('Get', _) -> {ok, ?PAYPROC_INVOICE_WITH_ID(<<"testInvoiceID">>)} end},
{magista, fun('SearchPayments', _) -> {ok, ?STAT_RESPONSE_PAYMENTS} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_search_payment_op_ctx(
<<"SearchPayments">>,
?STRING,
?STRING,
<<"testInvoiceID">>,
<<"testPaymentID">>,
SearchCtx = ?CTX_SEARCH_OP(<<"SearchPayments">>, ?STRING, ?STRING, <<"testInvoiceID">>, <<"testPaymentID">>),
_ = capi_ct_helper_bouncer:mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(SearchCtx),
payment_processing = #ctx_v1_ContextPaymentProcessing{
invoice = ?CTX_INVOICE(<<"testInvoiceID">>, ?STRING, ?STRING)
}
}
),
Config
),
{ok, _, _} = make_search_payments_query([{'paymentStatus', <<"pending">>}], Config),
{ok, _, _} = make_search_payments_query([{'paymentStatus', <<"processed">>}], Config),
{ok, _, _} = make_search_payments_query([{'paymentStatus', <<"captured">>}], Config),
{ok, _, _} = make_search_payments_query([{'paymentStatus', <<"cancelled">>}], Config),
{ok, _, _} = make_search_payments_query([{'paymentStatus', <<"refunded">>}], Config),
{ok, _, _} = make_search_payments_query([{'paymentStatus', <<"failed">>}], Config),
{ok, _, _} = make_search_payments_query([{'paymentFlow', <<"instant">>}], Config),
{ok, _, _} = make_search_payments_query([{'paymentFlow', <<"hold">>}], Config),
{ok, _, _} = make_search_payments_query([{'paymentMethod', <<"bankCard">>}], Config),
{ok, _, _} = make_search_payments_query([{'paymentMethod', <<"paymentTerminal">>}], Config),
{ok, _, _} = make_search_payments_query(
{ok, _, _} = search_payments([{'paymentStatus', <<"pending">>}], Config),
{ok, _, _} = search_payments([{'paymentStatus', <<"processed">>}], Config),
{ok, _, _} = search_payments([{'paymentStatus', <<"captured">>}], Config),
{ok, _, _} = search_payments([{'paymentStatus', <<"cancelled">>}], Config),
{ok, _, _} = search_payments([{'paymentStatus', <<"refunded">>}], Config),
{ok, _, _} = search_payments([{'paymentStatus', <<"failed">>}], Config),
{ok, _, _} = search_payments([{'paymentFlow', <<"instant">>}], Config),
{ok, _, _} = search_payments([{'paymentFlow', <<"hold">>}], Config),
{ok, _, _} = search_payments([{'paymentMethod', <<"bankCard">>}], Config),
{ok, _, _} = search_payments([{'paymentMethod', <<"paymentTerminal">>}], Config),
{ok, _, _} = search_payments(
[
{'payerFingerprint', <<"blablablalbalbal">>},
{'first6', <<"424242">>},
{'last4', <<"2222">>},
{'rrn', <<"090909090909">>},
{'approvalCode', <<"808080">>},
{'paymentAmount', 10000}
{'paymentAmount', 10000},
{'paymentTerminalProvider', <<"NEUROSET">>},
{'barnkCardPaymentSystem', <<"MONSTERCARD">>},
{'barnkCardTokenProvider', <<"BLABLAPAY">>}
],
Config
).
make_search_payments_query(QueryAdds, Config) ->
search_payments(QueryAdds, Config) ->
Query = [
{limit, 2},
{offset, 42},
{from_time, {{2015, 08, 11}, {19, 42, 35}}},
{to_time, {{2020, 08, 11}, {19, 42, 35}}},
{'payerEmail', <<"test@test.ru">>},
@ -183,29 +287,91 @@ make_search_payments_query(QueryAdds, Config) ->
],
capi_client_searches:search_payments(?config(context, Config), ?STRING, Query ++ QueryAdds).
-spec search_refunds_ok_test(config()) -> _.
search_refunds_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{magista, fun('SearchRefunds', _) -> {ok, ?STAT_RESPONSE_REFUNDS} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_search_op_ctx(
?CTX_SEARCH_OP(<<"SearchRefunds">>, ?STRING, ?STRING, undefined, undefined),
#ctx_v1_ContextPaymentProcessing{},
Config
),
{ok, _, _} = search_refunds([], Config),
{ok, _, _} = search_refunds([{'refundStatus', <<"pending">>}], Config),
{ok, _, _} = search_refunds([{'refundStatus', <<"succeeded">>}], Config),
{ok, _, _} = search_refunds([{'refundStatus', <<"failed">>}], Config),
{ok, _, _} = search_refunds([{'rrn', <<"090909090909">>}, {'approvalCode', <<"808080">>}], Config).
-spec search_refunds_by_refund_id_ok_test(config()) -> _.
search_refunds_by_refund_id_ok_test(Config) ->
RefundID = <<"refünd">>,
_ = capi_ct_helper:mock_services(
[
{magista, fun('SearchRefunds', _) -> {ok, ?STAT_RESPONSE_REFUNDS} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_search_op_ctx(
?CTX_SEARCH_OP(<<"SearchRefunds">>, ?STRING, ?STRING, undefined, undefined, undefined, RefundID),
#ctx_v1_ContextPaymentProcessing{},
Config
),
{ok, _, _} = search_refunds([{'refundID', RefundID}], Config).
-spec search_refunds_by_invoice_id_ok_test(config()) -> _.
search_refunds_by_invoice_id_ok_test(Config) ->
InvoiceID = <<"blarg">>,
PaymentID = <<"blorg">>,
_ = capi_ct_helper:mock_services(
[
{invoicing, fun('Get', _) -> {ok, ?PAYPROC_INVOICE_WITH_ID(InvoiceID)} end},
{magista, fun('SearchRefunds', _) -> {ok, ?STAT_RESPONSE_REFUNDS} end}
],
Config
),
SearchCtx = ?CTX_SEARCH_OP(<<"SearchRefunds">>, ?STRING, ?STRING, InvoiceID, PaymentID),
_ = capi_ct_helper_bouncer:mock_arbiter(
?assertContextMatches(
#ctx_v1_ContextFragment{
capi = ?CTX_CAPI(SearchCtx),
payment_processing = #ctx_v1_ContextPaymentProcessing{
invoice = ?CTX_INVOICE(InvoiceID, ?STRING, ?STRING)
}
}
),
Config
),
{ok, _, _} = search_refunds([{'invoiceID', InvoiceID}, {'paymentID', PaymentID}], Config).
search_refunds(Query, Config) ->
BaseQuery = [
{limit, 42},
{from_time, {{2015, 08, 11}, {19, 42, 35}}},
{to_time, {{2020, 08, 11}, {19, 42, 35}}},
{'continuationToken', <<"come_back_next_time">>}
],
capi_client_searches:search_refunds(?config(context, Config), ?STRING, BaseQuery ++ Query).
-spec search_payments_invalid_request_test(config()) -> _.
search_payments_invalid_request_test(Config) ->
_ = capi_ct_helper:mock_services(
[
capi_test_hack:get_invoice_mock(),
{magista, fun('SearchPayments', _) -> {throwing, #base_InvalidRequest{errors = [<<"error">>]}} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_search_payment_op_ctx(
<<"SearchPayments">>,
?STRING,
?STRING,
<<"testInvoiceID">>,
<<"testPaymentID">>,
_ = capi_ct_helper_bouncer:mock_assert_search_op_ctx(
?CTX_SEARCH_OP(<<"SearchPayments">>, ?STRING, ?STRING, undefined, undefined),
Config
),
Query = [
{limit, 2},
{from_time, {{2015, 08, 11}, {19, 42, 35}}},
{to_time, {{2020, 08, 11}, {19, 42, 35}}},
{'invoiceID', <<"testInvoiceID">>},
{'paymentID', <<"testPaymentID">>},
{'continuationToken', <<"come_back_next_time">>}
],
{error, {400, _}} = capi_client_searches:search_payments(?config(context, Config), ?STRING, Query).
@ -214,25 +380,18 @@ search_payments_invalid_request_test(Config) ->
search_payments_invalid_token_test(Config) ->
_ = capi_ct_helper:mock_services(
[
capi_test_hack:get_invoice_mock(),
{magista, fun('SearchPayments', _) -> {throwing, #magista_BadContinuationToken{reason = <<"">>}} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_search_payment_op_ctx(
<<"SearchPayments">>,
?STRING,
?STRING,
<<"testInvoiceID">>,
<<"testPaymentID">>,
_ = capi_ct_helper_bouncer:mock_assert_search_op_ctx(
?CTX_SEARCH_OP(<<"SearchPayments">>, ?STRING, ?STRING, undefined, undefined),
Config
),
Query = [
{limit, 2},
{from_time, {{2015, 08, 11}, {19, 42, 35}}},
{to_time, {{2020, 08, 11}, {19, 42, 35}}},
{'invoiceID', <<"testInvoiceID">>},
{'paymentID', <<"testPaymentID">>},
{'continuationToken', <<"come_back_next_time">>}
],
{error, {400, _}} = capi_client_searches:search_payments(?config(context, Config), ?STRING, Query).
@ -241,25 +400,18 @@ search_payments_invalid_token_test(Config) ->
search_payments_limit_exceeded_test(Config) ->
_ = capi_ct_helper:mock_services(
[
capi_test_hack:get_invoice_mock(),
{magista, fun('SearchPayments', _) -> {throwing, #magista_LimitExceeded{}} end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_search_payment_op_ctx(
<<"SearchPayments">>,
?STRING,
?STRING,
<<"testInvoiceID">>,
<<"testPaymentID">>,
_ = capi_ct_helper_bouncer:mock_assert_search_op_ctx(
?CTX_SEARCH_OP(<<"SearchPayments">>, ?STRING, ?STRING, undefined, undefined),
Config
),
Query = [
{limit, 2},
{from_time, {{2015, 08, 11}, {19, 42, 35}}},
{to_time, {{2020, 08, 11}, {19, 42, 35}}},
{'invoiceID', <<"testInvoiceID">>},
{'paymentID', <<"testPaymentID">>},
{'continuationToken', <<"come_back_next_time">>}
],
{error, {400, _}} = capi_client_searches:search_payments(?config(context, Config), ?STRING, Query).

View File

@ -1,13 +0,0 @@
-module(capi_test_hack).
-include_lib("damsel/include/dmsl_payproc_thrift.hrl").
-include_lib("damsel/include/dmsl_base_thrift.hrl").
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("capi_dummy_data.hrl").
-export([get_invoice_mock/0]).
-spec get_invoice_mock() -> _.
get_invoice_mock() ->
{invoicing, fun('Get', _) -> {ok, ?PAYPROC_INVOICE} end}.

View File

@ -1,69 +0,0 @@
-module(capi_client_claims).
-export([create_claim/2]).
-export([get_claim_by_id/2]).
-export([get_claims/1]).
-export([get_claims_by_status/2]).
-export([revoke_claim_by_id/4]).
-type context() :: capi_client_lib:context().
-spec create_claim(context(), [term()]) -> {ok, term()} | {error, term()}.
create_claim(Context, Changeset) ->
Params = #{
body => Changeset
},
{Host, Port, PreparedParams} = capi_client_lib:make_request(Context, Params),
Response = swag_client_claims_api:create_claim(Host, Port, PreparedParams),
capi_client_lib:handle_response(Response).
-spec get_claim_by_id(context(), integer()) -> {ok, term()} | {error, term()}.
get_claim_by_id(Context, ClaimID) ->
Params = #{
binding => #{
<<"claimID">> => ClaimID
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_claims_api:get_claim_by_id(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).
-spec get_claims(context()) -> {ok, term()} | {error, term()}.
get_claims(Context) ->
Params = #{
qs_val => #{}
},
{Host, Port, PreparedParams} = capi_client_lib:make_request(Context, Params),
Response = swag_client_claims_api:get_claims(Host, Port, PreparedParams),
capi_client_lib:handle_response(Response).
-spec get_claims_by_status(context(), term()) -> {ok, term()} | {error, term()}.
get_claims_by_status(Context, Status) ->
Params = #{
qs_val => #{
<<"claimStatus">> => genlib:to_binary(Status)
}
},
{Host, Port, PreparedParams} = capi_client_lib:make_request(Context, Params),
Response = swag_client_claims_api:get_claims(Host, Port, PreparedParams),
capi_client_lib:handle_response(Response).
-spec revoke_claim_by_id(context(), binary(), integer(), integer()) -> ok | {error, term()}.
revoke_claim_by_id(Context, Reason, ClaimID, Revision) ->
Params = #{
binding => #{
<<"claimID">> => ClaimID
},
qs_val => #{
<<"claimRevision">> => genlib:to_binary(Revision)
},
body => #{
<<"reason">> => genlib:to_binary(Reason)
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_claims_api:revoke_claim_by_id(Url, PreparedParams, Opts),
case capi_client_lib:handle_response(Response) of
{ok, _Body} -> ok;
{error, Error} -> {error, Error}
end.

View File

@ -1,129 +0,0 @@
-module(capi_client_reports).
-export([get_reports/4]).
-export([get_reports_for_party/5]).
-export([get_report/3]).
-export([get_report_for_party/4]).
-export([create_report/5]).
-export([create_report_for_party/6]).
-export([download_file/4]).
-export([download_file_for_party/5]).
-type context() :: capi_client_lib:context().
-spec get_reports(context(), binary(), binary(), binary()) -> {ok, list()} | {error, term()}.
get_reports(Context, ShopID, FromTime, ToTime) ->
Params = #{
binding => #{
<<"shopID">> => ShopID
},
qs_val => #{
<<"fromTime">> => FromTime,
<<"toTime">> => ToTime
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_reports_api:get_reports(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).
-spec get_reports_for_party(context(), binary(), binary(), binary(), binary()) -> {ok, list()} | {error, term()}.
get_reports_for_party(Context, PartyID, ShopID, FromTime, ToTime) ->
Params = #{
binding => #{
<<"partyID">> => PartyID,
<<"shopID">> => ShopID
},
qs_val => #{
<<"fromTime">> => FromTime,
<<"toTime">> => ToTime
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_reports_api:get_reports_for_party(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).
-spec get_report(context(), binary(), binary()) -> {ok, list()} | {error, term()}.
get_report(Context, ShopID, ReportID) ->
Params = #{
binding => #{
<<"shopID">> => ShopID,
<<"reportID">> => ReportID
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_reports_api:get_report(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).
-spec get_report_for_party(context(), binary(), binary(), binary()) -> {ok, list()} | {error, term()}.
get_report_for_party(Context, PartyID, ShopID, ReportID) ->
Params = #{
binding => #{
<<"partyID">> => PartyID,
<<"shopID">> => ShopID,
<<"reportID">> => ReportID
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_reports_api:get_report_for_party(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).
-spec create_report(context(), binary(), binary(), binary(), binary()) -> {ok, list()} | {error, term()}.
create_report(Context, ShopID, ReportType, FromTime, ToTime) ->
Params = #{
binding => #{
<<"shopID">> => ShopID
},
body => #{
<<"reportType">> => ReportType,
<<"fromTime">> => FromTime,
<<"toTime">> => ToTime
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_reports_api:create_report(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).
-spec create_report_for_party(context(), binary(), binary(), binary(), binary(), binary()) ->
{ok, list()} | {error, term()}.
create_report_for_party(Context, PartyID, ShopID, ReportType, FromTime, ToTime) ->
Params = #{
binding => #{
<<"partyID">> => PartyID,
<<"shopID">> => ShopID
},
body => #{
<<"reportType">> => ReportType,
<<"fromTime">> => FromTime,
<<"toTime">> => ToTime
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_reports_api:create_report_for_party(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).
-spec download_file(context(), binary(), binary(), binary()) -> {ok, redirect} | {error, term()}.
download_file(Context, ShopID, ReportID, FileID) ->
Params = #{
binding => #{
<<"shopID">> => ShopID,
<<"reportID">> => ReportID,
<<"fileID">> => FileID
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_reports_api:download_file(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).
-spec download_file_for_party(context(), binary(), binary(), binary(), binary()) -> {ok, redirect} | {error, term()}.
download_file_for_party(Context, PartyID, ShopID, ReportID, FileID) ->
Params = #{
binding => #{
<<"partyID">> => PartyID,
<<"shopID">> => ShopID,
<<"reportID">> => ReportID,
<<"fileID">> => FileID
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_reports_api:download_file_for_party(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).

View File

@ -1,19 +1,32 @@
-module(capi_client_searches).
-export([search_invoices/3]).
-export([search_payments/3]).
-export([search_refunds/3]).
-type context() :: capi_client_lib:context().
-type search_query() :: capi_client_lib:search_query().
-spec search_invoices(context(), binary(), search_query()) -> {ok, term(), term()} | {error, term()}.
search_invoices(Context, ShopID, Query) ->
search(Context, fun swag_client_search_api:search_invoices/3, ShopID, Query).
-spec search_payments(context(), binary(), search_query()) -> {ok, term(), term()} | {error, term()}.
search_payments(Context, ShopID, Query) ->
search(Context, fun swag_client_search_api:search_payments/3, ShopID, Query).
-spec search_refunds(context(), binary(), search_query()) -> {ok, term(), term()} | {error, term()}.
search_refunds(Context, ShopID, Query) ->
search(Context, fun swag_client_search_api:search_refunds/3, ShopID, Query).
search(Context, WithFun, ShopID, Query) ->
Qs = capi_client_lib:make_search_query_string(Query),
Params = #{
binding => #{<<"shopID">> => ShopID},
qs_val => Qs
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_search_api:search_payments(Url, PreparedParams, Opts),
Response = WithFun(Url, PreparedParams, Opts),
case capi_client_lib:handle_response(Response) of
{ok, #{<<"totalCount">> := TotalCount, <<"result">> := Payments}} ->
{ok, TotalCount, Payments};

View File

@ -79,8 +79,6 @@ get_service_modname(invoice_templating) ->
{dmsl_payproc_thrift, 'InvoiceTemplating'};
get_service_modname(magista) ->
{magista_magista_thrift, 'MerchantStatisticsService'};
get_service_modname(reporting) ->
{reporter_reports_thrift, 'Reporting'};
get_service_modname(payouts) ->
{payouts_payout_manager_thrift, 'PayoutManagement'};
get_service_modname(webhook_manager) ->

View File

@ -40,7 +40,6 @@
%% {oops_bodies, #{
%% 500 => "oops_bodies/500_body"
%% }},
{reporter_url_lifetime, 60}, % seconds
{graceful_shutdown_timeout, 5000}, % non_neg_integer() | infinity
{bouncer_ruleset_id, <<"service/authz/api">>},
{access_conf, #{
@ -92,7 +91,6 @@
invoice_templating => <<"http://hellgate:8022/v1/processing/invoice_templating">>,
webhook_manager => <<"http://hooker:8022/hook">>,
merchant_stat => <<"http://magista:8022/stat">>,
reporting => <<"http://reporter:8022/reports">>,
payouts => <<"http://payouter:8022/reports">>
}},
{service_deadlines, #{
@ -208,16 +206,6 @@
}}
]},
{how_are_you, [
{metrics_publishers, [
% {hay_statsd_publisher, #{
% key_prefix => <<"capi-v2.">>,
% host => "localhost",
% port => 8125
% }}
]}
]},
{snowflake, [
% {machine_id, 42}
]},

View File

@ -37,7 +37,6 @@
{damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}},
{bender_proto, {git, "https://github.com/valitydev/bender-proto.git", {branch, "master"}}},
{bender_client, {git, "https://github.com/valitydev/bender-client-erlang.git", {branch, "master"}}},
{reporter_proto, {git, "https://github.com/valitydev/reporter-proto.git", {branch, "master"}}},
{dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}},
{cowboy_cors, {git, "https://github.com/valitydev/cowboy_cors.git", {branch, "master"}}},
{cowboy_access_log, {git, "https://github.com/valitydev/cowboy_access_log.git", {branch, "master"}}},

View File

@ -108,10 +108,6 @@
{ref,"a19e716966b7206e96fbd767661d6fd3bab3119d"}},
0},
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},1},
{<<"reporter_proto">>,
{git,"https://github.com/valitydev/reporter-proto.git",
{ref,"d7d99959b35ab01acb8acedfc459779ddfbef4b4"}},
0},
{<<"scoper">>,
{git,"https://github.com/valitydev/scoper.git",
{ref,"7f3183df279bc8181efe58dafd9cae164f495e6f"}},
@ -123,11 +119,11 @@
{<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2},
{<<"swag_client">>,
{git,"https://github.com/valitydev/swag-payments",
{ref,"187da507554108df60a317582ec8a8d40433c9e5"}},
{ref,"279d481e4583f8650b0162470fae68b8f30c0cdc"}},
0},
{<<"swag_server">>,
{git,"https://github.com/valitydev/swag-payments",
{ref,"04149a7aad1b9fad8d1992bc29bffa0de5fbd498"}},
{ref,"06c30485b102036290a1c05d07e517ea2a0a85de"}},
0},
{<<"thrift">>,
{git,"https://github.com/valitydev/thrift_erlang.git",