mirror of
https://github.com/valitydev/capi-v2.git
synced 2024-11-06 01:55:20 +00:00
ED-57: payment handler bouncer integration (#527)
This commit is contained in:
parent
c533defaf1
commit
56137dfba0
@ -233,34 +233,6 @@ decode_bank_card(#domain_BankCard{
|
||||
% <<"tokenization_method">> => TokenizationMethod
|
||||
}).
|
||||
|
||||
% =======
|
||||
% 'token' = Token,
|
||||
% 'payment_system' = PaymentSystem,
|
||||
% 'bin' = Bin,
|
||||
% 'last_digits' = LastDigits,
|
||||
% 'token_provider' = TokenProvider,
|
||||
% 'issuer_country' = IssuerCountry,
|
||||
% 'bank_name' = BankName,
|
||||
% 'metadata' = Metadata,
|
||||
% 'is_cvv_empty' = IsCVVEmpty
|
||||
% % 'tokenization_method' = TokenizationMethod
|
||||
% }) ->
|
||||
% capi_utils:map_to_base64url(genlib_map:compact(#{
|
||||
% <<"type" >> => <<"bank_card">>,
|
||||
% <<"token" >> => Token,
|
||||
% <<"payment_system">> => PaymentSystem,
|
||||
% <<"bin" >> => Bin,
|
||||
% <<"masked_pan" >> => LastDigits,
|
||||
% <<"token_provider">> => TokenProvider,
|
||||
% <<"issuer_country">> => IssuerCountry,
|
||||
% <<"bank_name" >> => BankName,
|
||||
% <<"metadata" >> => decode_bank_card_metadata(Metadata),
|
||||
% <<"is_cvv_empty" >> => decode_bank_card_cvv_flag(IsCVVEmpty)
|
||||
% % TODO: Uncomment or delete this when we negotiate deploying non-breaking changes
|
||||
% % <<"tokenization_method">> => TokenizationMethod
|
||||
% })).
|
||||
% >>>>>>> master
|
||||
|
||||
decode_bank_card_cvv_flag(undefined) ->
|
||||
undefined;
|
||||
decode_bank_card_cvv_flag(CVVFlag) when is_atom(CVVFlag) ->
|
||||
|
@ -15,85 +15,97 @@
|
||||
Req :: capi_handler:request_data(),
|
||||
Context :: capi_handler:processing_context()
|
||||
) -> {ok, capi_handler:request_state()} | {error, noimpl}.
|
||||
prepare(OperationID, Req, Context) when
|
||||
OperationID =:= 'GetPaymentInstitutions' orelse
|
||||
OperationID =:= 'GetPaymentInstitutionByRef' orelse
|
||||
OperationID =:= 'GetPaymentInstitutionPaymentTerms' orelse
|
||||
OperationID =:= 'GetPaymentInstitutionPayoutMethods' orelse
|
||||
OperationID =:= 'GetPaymentInstitutionPayoutSchedules'
|
||||
->
|
||||
Authorize = fun() -> {ok, capi_auth:authorize_operation(OperationID, [], Context, Req)} end,
|
||||
Process = fun() -> process_request(OperationID, Context, Req) end,
|
||||
prepare(OperationID = 'GetPaymentInstitutions', Req, #{woody_context := WoodyContext} = Context) ->
|
||||
Authorize = mk_authorize_operation(OperationID, Context, Req),
|
||||
Process = fun() ->
|
||||
try
|
||||
Residence = capi_handler_encoder:encode_residence(genlib_map:get(residence, Req)),
|
||||
Realm = genlib_map:get(realm, Req),
|
||||
{ok, PaymentInstObjects} = capi_domain:get_payment_institutions(WoodyContext),
|
||||
Resp =
|
||||
lists:filtermap(
|
||||
fun(P) ->
|
||||
case check_payment_institution(Realm, Residence, P) of
|
||||
true ->
|
||||
{true, decode_payment_institution_obj(P)};
|
||||
false ->
|
||||
false
|
||||
end
|
||||
end,
|
||||
PaymentInstObjects
|
||||
),
|
||||
{ok, {200, #{}, Resp}}
|
||||
catch
|
||||
throw:{encode_residence, invalid_residence} ->
|
||||
{ok, logic_error(invalidRequest, <<"Invalid residence">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetPaymentInstitutionByRef', Req, Context) ->
|
||||
Authorize = mk_authorize_operation(OperationID, Context, Req),
|
||||
Process = fun() ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case capi_domain:get({payment_institution, ?payment_institution_ref(PaymentInstitutionID)}, Context) of
|
||||
{ok, PaymentInstitution} ->
|
||||
{ok, {200, #{}, decode_payment_institution_obj(PaymentInstitution)}};
|
||||
{error, not_found} ->
|
||||
{ok, general_error(404, <<"Payment institution not found">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetPaymentInstitutionPaymentTerms', Req, Context) ->
|
||||
Authorize = mk_authorize_operation(OperationID, Context, Req),
|
||||
Process = fun() ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case compute_payment_institution_terms(PaymentInstitutionID, #payproc_Varset{}, Context) of
|
||||
{ok, #domain_TermSet{payments = PaymentTerms}} ->
|
||||
{ok, {200, #{}, decode_payment_terms(PaymentTerms)}};
|
||||
{exception, #payproc_PaymentInstitutionNotFound{}} ->
|
||||
{ok, general_error(404, <<"Payment institution not found">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetPaymentInstitutionPayoutMethods', Req, Context) ->
|
||||
Authorize = mk_authorize_operation(OperationID, Context, Req),
|
||||
Process = fun() ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case compute_payment_institution_terms(PaymentInstitutionID, prepare_request_varset(Req, Context), Context) of
|
||||
{ok, #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_methods = PayoutMethods}}} ->
|
||||
{ok, {200, #{}, decode_payout_methods_selector(PayoutMethods)}};
|
||||
{ok, #domain_TermSet{payouts = undefined}} ->
|
||||
{ok, general_error(404, <<"Automatic payouts not allowed">>)};
|
||||
{exception, #payproc_PaymentInstitutionNotFound{}} ->
|
||||
{ok, general_error(404, <<"Payment institution not found">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetPaymentInstitutionPayoutSchedules', Req, Context) ->
|
||||
Authorize = mk_authorize_operation(OperationID, Context, Req),
|
||||
Process = fun() ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case compute_payment_institution_terms(PaymentInstitutionID, prepare_request_varset(Req, Context), Context) of
|
||||
{ok, #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_schedules = Schedules}}} ->
|
||||
{ok, {200, #{}, decode_business_schedules_selector(Schedules)}};
|
||||
{ok, #domain_TermSet{payouts = undefined}} ->
|
||||
{ok, general_error(404, <<"Automatic payouts not allowed">>)};
|
||||
{exception, #payproc_PaymentInstitutionNotFound{}} ->
|
||||
{ok, general_error(404, <<"Payment institution not found">>)}
|
||||
end
|
||||
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('GetPaymentInstitutions', #{woody_context := WoodyContext}, Req) ->
|
||||
try
|
||||
Residence = capi_handler_encoder:encode_residence(genlib_map:get(residence, Req)),
|
||||
Realm = genlib_map:get(realm, Req),
|
||||
{ok, PaymentInstObjects} = capi_domain:get_payment_institutions(WoodyContext),
|
||||
Resp =
|
||||
lists:filtermap(
|
||||
fun(P) ->
|
||||
case check_payment_institution(Realm, Residence, P) of
|
||||
true ->
|
||||
{true, decode_payment_institution_obj(P)};
|
||||
false ->
|
||||
false
|
||||
end
|
||||
end,
|
||||
PaymentInstObjects
|
||||
),
|
||||
{ok, {200, #{}, Resp}}
|
||||
catch
|
||||
throw:{encode_residence, invalid_residence} ->
|
||||
{ok, logic_error(invalidRequest, <<"Invalid residence">>)}
|
||||
end;
|
||||
process_request('GetPaymentInstitutionByRef', #{woody_context := WoodyContext}, Req) ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case capi_domain:get({payment_institution, ?payment_institution_ref(PaymentInstitutionID)}, WoodyContext) of
|
||||
{ok, PaymentInstitution} ->
|
||||
{ok, {200, #{}, decode_payment_institution_obj(PaymentInstitution)}};
|
||||
{error, not_found} ->
|
||||
{ok, general_error(404, <<"Payment institution not found">>)}
|
||||
end;
|
||||
process_request('GetPaymentInstitutionPaymentTerms', Context, Req) ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case compute_payment_institution_terms(PaymentInstitutionID, #payproc_Varset{}, Context) of
|
||||
{ok, #domain_TermSet{payments = PaymentTerms}} ->
|
||||
{ok, {200, #{}, decode_payment_terms(PaymentTerms)}};
|
||||
{exception, #payproc_PaymentInstitutionNotFound{}} ->
|
||||
{ok, general_error(404, <<"Payment institution not found">>)}
|
||||
end;
|
||||
process_request('GetPaymentInstitutionPayoutMethods', Context, Req) ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case compute_payment_institution_terms(PaymentInstitutionID, prepare_request_varset(Req, Context), Context) of
|
||||
{ok, #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_methods = PayoutMethods}}} ->
|
||||
{ok, {200, #{}, decode_payout_methods_selector(PayoutMethods)}};
|
||||
{ok, #domain_TermSet{payouts = undefined}} ->
|
||||
{ok, general_error(404, <<"Automatic payouts not allowed">>)};
|
||||
{exception, #payproc_PaymentInstitutionNotFound{}} ->
|
||||
{ok, general_error(404, <<"Payment institution not found">>)}
|
||||
end;
|
||||
process_request('GetPaymentInstitutionPayoutSchedules', Context, Req) ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case compute_payment_institution_terms(PaymentInstitutionID, prepare_request_varset(Req, Context), Context) of
|
||||
{ok, #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_schedules = Schedules}}} ->
|
||||
{ok, {200, #{}, decode_business_schedules_selector(Schedules)}};
|
||||
{ok, #domain_TermSet{payouts = undefined}} ->
|
||||
{ok, general_error(404, <<"Automatic payouts not allowed">>)};
|
||||
{exception, #payproc_PaymentInstitutionNotFound{}} ->
|
||||
{ok, general_error(404, <<"Payment institution not found">>)}
|
||||
end.
|
||||
|
||||
%%
|
||||
|
||||
mk_authorize_operation(OperationID, Context, Req) ->
|
||||
fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end.
|
||||
|
||||
check_payment_institution(Realm, Residence, PaymentInstitution) ->
|
||||
check_payment_institution_realm(Realm, PaymentInstitution) andalso
|
||||
check_payment_institution_residence(Residence, PaymentInstitution).
|
||||
|
@ -15,412 +15,480 @@
|
||||
Req :: capi_handler:request_data(),
|
||||
Context :: capi_handler:processing_context()
|
||||
) -> {ok, capi_handler:request_state()} | {error, noimpl}.
|
||||
prepare(OperationID, Req, Context) when
|
||||
OperationID =:= 'CreatePayment' orelse
|
||||
OperationID =:= 'GetPayments' orelse
|
||||
OperationID =:= 'GetPaymentByID' orelse
|
||||
OperationID =:= 'GetRefundByExternalID' orelse
|
||||
OperationID =:= 'GetPaymentByExternalID' orelse
|
||||
OperationID =:= 'CancelPayment' orelse
|
||||
OperationID =:= 'CapturePayment' orelse
|
||||
OperationID =:= 'CreateRefund' orelse
|
||||
OperationID =:= 'GetRefunds' orelse
|
||||
OperationID =:= 'GetRefundByID' orelse
|
||||
OperationID =:= 'GetChargebacks' orelse
|
||||
OperationID =:= 'GetChargebackByID'
|
||||
->
|
||||
Authorize = fun() -> {ok, capi_auth:authorize_operation(OperationID, [], Context, Req)} 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('CreatePayment' = OperationID, Context, Req) ->
|
||||
InvoiceID = maps:get('invoiceID', Req),
|
||||
prepare(OperationID = 'CreatePayment', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
Invoice = map_result(get_invoice_by_id(InvoiceID, Context)),
|
||||
PaymentParams = maps:get('PaymentParams', Req),
|
||||
PartyID = capi_handler_utils:get_party_id(Context),
|
||||
Result =
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID, invoice => InvoiceID}},
|
||||
{payproc, #{invoice => Invoice}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
Process = fun() ->
|
||||
try
|
||||
create_payment(InvoiceID, PartyID, PaymentParams, Context, OperationID)
|
||||
catch
|
||||
throw:Error when
|
||||
Error =:= invalid_token orelse
|
||||
Error =:= invalid_payment_session orelse
|
||||
Error =:= invalid_processing_deadline
|
||||
->
|
||||
{error, Error};
|
||||
throw:Error = {external_id_conflict, _, _, _} ->
|
||||
{error, Error}
|
||||
end,
|
||||
case Result of
|
||||
{ok, Payment} ->
|
||||
{ok, {201, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidInvoiceStatus{} ->
|
||||
capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)),
|
||||
case create_payment(Invoice, PaymentParams, Context, OperationID) of
|
||||
{ok, Payment} ->
|
||||
{ok, {201, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{exception, #payproc_InvalidInvoiceStatus{}} ->
|
||||
{ok, logic_error(invalidInvoiceStatus, <<"Invalid invoice status">>)};
|
||||
#payproc_InvoicePaymentPending{} ->
|
||||
{exception, #payproc_InvoicePaymentPending{}} ->
|
||||
ErrorResp = logic_error(
|
||||
invoicePaymentPending,
|
||||
<<"Invoice payment pending">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
{exception, #'InvalidRequest'{errors = Errors}} ->
|
||||
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
|
||||
{ok, logic_error(invalidRequest, FormattedErrors)};
|
||||
#payproc_InvalidPartyStatus{} ->
|
||||
{exception, #payproc_InvalidPartyStatus{}} ->
|
||||
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)};
|
||||
#payproc_InvalidShopStatus{} ->
|
||||
{exception, #payproc_InvalidShopStatus{}} ->
|
||||
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)};
|
||||
#payproc_InvalidContractStatus{} ->
|
||||
{exception, #payproc_InvalidContractStatus{}} ->
|
||||
ErrorResp = logic_error(
|
||||
invalidContractStatus,
|
||||
<<"Invalid contract status">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InvalidRecurrentParentPayment{} ->
|
||||
{exception, #payproc_InvalidRecurrentParentPayment{}} ->
|
||||
ErrorResp = logic_error(
|
||||
invalidRecurrentParent,
|
||||
<<"Specified recurrent parent is invalid">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InvalidUser{} ->
|
||||
{exception, #payproc_InvalidUser{}} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{exception, #payproc_InvoiceNotFound{}} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)}
|
||||
end;
|
||||
{error, invalid_token} ->
|
||||
{ok,
|
||||
logic_error(
|
||||
invalidPaymentToolToken,
|
||||
<<"Specified payment tool token is invalid">>
|
||||
)};
|
||||
{error, invalid_payment_session} ->
|
||||
{ok,
|
||||
logic_error(
|
||||
invalidPaymentSession,
|
||||
<<"Specified payment session is invalid">>
|
||||
)};
|
||||
{error, invalid_processing_deadline} ->
|
||||
{ok,
|
||||
logic_error(
|
||||
invalidProcessingDeadline,
|
||||
<<"Specified processing deadline is invalid">>
|
||||
)};
|
||||
{error, {external_id_conflict, PaymentID, ExternalID, _Schema}} ->
|
||||
{ok, logic_error(externalIDConflict, {PaymentID, ExternalID})}
|
||||
end;
|
||||
process_request('GetPayments', Context, Req) ->
|
||||
end
|
||||
catch
|
||||
throw:invalid_token ->
|
||||
{ok,
|
||||
logic_error(
|
||||
invalidPaymentToolToken,
|
||||
<<"Specified payment tool token is invalid">>
|
||||
)};
|
||||
throw:invalid_payment_session ->
|
||||
{ok,
|
||||
logic_error(
|
||||
invalidPaymentSession,
|
||||
<<"Specified payment session is invalid">>
|
||||
)};
|
||||
throw:invalid_processing_deadline ->
|
||||
{ok,
|
||||
logic_error(
|
||||
invalidProcessingDeadline,
|
||||
<<"Specified processing deadline is invalid">>
|
||||
)};
|
||||
throw:{external_id_conflict, PaymentID, ExternalID, _Schema} ->
|
||||
{ok, logic_error(externalIDConflict, {PaymentID, ExternalID})}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetPayments', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
case capi_handler_utils:get_invoice_by_id(InvoiceID, Context) of
|
||||
{ok, #'payproc_Invoice'{payments = Payments}} ->
|
||||
{ok, {200, #{}, [decode_invoice_payment(InvoiceID, P, Context) || P <- Payments]}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)}
|
||||
end
|
||||
end;
|
||||
process_request('GetPaymentByID', Context, Req) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
case capi_handler_utils:get_payment_by_id(InvoiceID, maps:get(paymentID, Req), Context) of
|
||||
{ok, Payment} ->
|
||||
{ok, {200, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)}
|
||||
end
|
||||
end;
|
||||
process_request('GetRefundByExternalID', Context, Req) ->
|
||||
ExternalID = maps:get(externalID, Req),
|
||||
case get_refund_by_external_id(ExternalID, Context) of
|
||||
{ok, Refund} ->
|
||||
{ok, {200, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}};
|
||||
{error, internal_id_not_found} ->
|
||||
{ok, general_error(404, <<"Refund not found">>)};
|
||||
{error, payment_not_found} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
{error, invoice_not_found} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentRefundNotFound{} ->
|
||||
{ok, general_error(404, <<"Refund not found">>)};
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)}
|
||||
end
|
||||
end;
|
||||
process_request('GetPaymentByExternalID', Context, Req) ->
|
||||
ExternalID = maps:get(externalID, Req),
|
||||
case get_payment_by_external_id(ExternalID, Context) of
|
||||
{ok, InvoiceID, Payment} ->
|
||||
{ok, {200, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{error, internal_id_not_found} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
{error, invoice_not_found} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)}
|
||||
end
|
||||
end;
|
||||
process_request('CancelPayment', Context, Req) ->
|
||||
CallArgs = {maps:get(invoiceID, Req), maps:get(paymentID, Req), maps:get(<<"reason">>, maps:get('Reason', Req))},
|
||||
Call = {invoicing, 'CancelPayment', CallArgs},
|
||||
case capi_handler_utils:service_call_with([user_info], Call, Context) of
|
||||
{ok, _} ->
|
||||
{ok, {202, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvalidPaymentStatus{} ->
|
||||
{ok, logic_error(invalidPaymentStatus, <<"Invalid payment status">>)};
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
|
||||
{ok, logic_error(invalidRequest, FormattedErrors)};
|
||||
#payproc_OperationNotPermitted{} ->
|
||||
ErrorResp = logic_error(
|
||||
operationNotPermitted,
|
||||
<<"Operation not permitted">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InvalidPartyStatus{} ->
|
||||
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)};
|
||||
#payproc_InvalidShopStatus{} ->
|
||||
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}
|
||||
end
|
||||
end;
|
||||
process_request('CapturePayment', Context, Req) ->
|
||||
CaptureParams = maps:get('CaptureParams', Req),
|
||||
Invoice = map_result(get_invoice_by_id(InvoiceID, Context)),
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID, invoice => InvoiceID}},
|
||||
{payproc, #{invoice => Invoice}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
Process = fun() ->
|
||||
capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)),
|
||||
#'payproc_Invoice'{payments = Payments} = Invoice,
|
||||
{ok, {200, #{}, [decode_invoice_payment(InvoiceID, P, Context) || P <- Payments]}}
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetPaymentByID', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
PaymentID = maps:get(paymentID, Req),
|
||||
try
|
||||
CallArgs = {
|
||||
InvoiceID,
|
||||
PaymentID,
|
||||
#payproc_InvoicePaymentCaptureParams{
|
||||
reason = maps:get(<<"reason">>, CaptureParams),
|
||||
cash = encode_optional_cash(CaptureParams, InvoiceID, PaymentID, Context),
|
||||
cart = capi_handler_encoder:encode_invoice_cart(CaptureParams)
|
||||
}
|
||||
},
|
||||
Call = {invoicing, 'CapturePayment', CallArgs},
|
||||
capi_handler_utils:service_call_with([user_info], Call, Context)
|
||||
of
|
||||
{ok, _} ->
|
||||
{ok, {202, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvalidPaymentStatus{} ->
|
||||
{ok, logic_error(invalidPaymentStatus, <<"Invalid payment status">>)};
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
|
||||
{ok, logic_error(invalidRequest, FormattedErrors)};
|
||||
#payproc_OperationNotPermitted{} ->
|
||||
ErrorResp = logic_error(
|
||||
operationNotPermitted,
|
||||
<<"Operation not permitted">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InvalidPartyStatus{} ->
|
||||
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)};
|
||||
#payproc_InvalidShopStatus{} ->
|
||||
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)};
|
||||
#payproc_InconsistentCaptureCurrency{payment_currency = PaymentCurrency} ->
|
||||
{ok,
|
||||
logic_error(
|
||||
inconsistentCaptureCurrency,
|
||||
io_lib:format("Correct currency: ~p", [PaymentCurrency])
|
||||
)};
|
||||
#payproc_AmountExceededCaptureBalance{payment_amount = PaymentAmount} ->
|
||||
{ok,
|
||||
logic_error(
|
||||
amountExceededCaptureBalance,
|
||||
io_lib:format("Max amount: ~p", [PaymentAmount])
|
||||
)}
|
||||
end
|
||||
catch
|
||||
throw:invoice_cart_empty ->
|
||||
{ok, logic_error(invalidInvoiceCart, <<"Wrong size. Path to item: cart">>)}
|
||||
end;
|
||||
process_request('CreateRefund' = OperationID, Context, Req) ->
|
||||
Invoice = map_result(get_invoice_by_id(InvoiceID, Context)),
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID, invoice => InvoiceID, payment => PaymentID}},
|
||||
{payproc, #{invoice => Invoice}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
Process = fun() ->
|
||||
capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)),
|
||||
case find_payment_by_id(PaymentID, Invoice) of
|
||||
{ok, Payment} ->
|
||||
{ok, {200, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{error, payment_not_found} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetPaymentByExternalID', Req, Context) ->
|
||||
ExternalID = maps:get(externalID, Req),
|
||||
InternalID = map_result(get_payment_by_external_id(ExternalID, Context)),
|
||||
Invoice = map_result(
|
||||
maybe(InternalID, fun({InvoiceID, _}) ->
|
||||
get_invoice_by_id(InvoiceID, Context)
|
||||
end)
|
||||
),
|
||||
|
||||
OperationPrototype = maybe(
|
||||
InternalID,
|
||||
fun({InvoiceID, PaymentID}) ->
|
||||
#{id => OperationID, invoice => InvoiceID, payment => PaymentID}
|
||||
end
|
||||
),
|
||||
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, genlib:define(OperationPrototype, #{id => OperationID})},
|
||||
{payproc, #{invoice => Invoice}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
Process = fun() ->
|
||||
capi_handler:respond_if_undefined(InternalID, general_error(404, <<"Payment not found">>)),
|
||||
capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)),
|
||||
|
||||
{InvoiceID, PaymentID} = InternalID,
|
||||
case find_payment_by_id(PaymentID, Invoice) of
|
||||
{ok, Payment} ->
|
||||
{ok, {200, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{error, payment_not_found} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'CapturePayment', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
PaymentID = maps:get(paymentID, Req),
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID, invoice => InvoiceID, payment => PaymentID}},
|
||||
{payproc, #{invoice => InvoiceID}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
Process = fun() ->
|
||||
Params = maps:get('CaptureParams', Req),
|
||||
try
|
||||
CaptureParams = #payproc_InvoicePaymentCaptureParams{
|
||||
reason = maps:get(<<"reason">>, Params),
|
||||
cash = encode_optional_cash(Params, InvoiceID, PaymentID, Context),
|
||||
cart = capi_handler_encoder:encode_invoice_cart(Params)
|
||||
},
|
||||
CallArgs = {InvoiceID, PaymentID, CaptureParams},
|
||||
Call = {invoicing, 'CapturePayment', CallArgs},
|
||||
capi_handler_utils:service_call_with([user_info], Call, Context)
|
||||
of
|
||||
{ok, _} ->
|
||||
{ok, {202, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvalidPaymentStatus{} ->
|
||||
{ok, logic_error(invalidPaymentStatus, <<"Invalid payment status">>)};
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
|
||||
{ok, logic_error(invalidRequest, FormattedErrors)};
|
||||
#payproc_OperationNotPermitted{} ->
|
||||
ErrorResp = logic_error(
|
||||
operationNotPermitted,
|
||||
<<"Operation not permitted">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InvalidPartyStatus{} ->
|
||||
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)};
|
||||
#payproc_InvalidShopStatus{} ->
|
||||
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)};
|
||||
#payproc_InconsistentCaptureCurrency{payment_currency = PaymentCurrency} ->
|
||||
{ok,
|
||||
logic_error(
|
||||
inconsistentCaptureCurrency,
|
||||
io_lib:format("Correct currency: ~p", [PaymentCurrency])
|
||||
)};
|
||||
#payproc_AmountExceededCaptureBalance{payment_amount = PaymentAmount} ->
|
||||
{ok,
|
||||
logic_error(
|
||||
amountExceededCaptureBalance,
|
||||
io_lib:format("Max amount: ~p", [PaymentAmount])
|
||||
)}
|
||||
end
|
||||
catch
|
||||
throw:invoice_cart_empty ->
|
||||
{ok, logic_error(invalidInvoiceCart, <<"Wrong size. Path to item: cart">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'CancelPayment', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
PaymentID = maps:get(paymentID, Req),
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID, invoice => InvoiceID}},
|
||||
{payproc, #{invoice => InvoiceID}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
Process = fun() ->
|
||||
Reason = maps:get(<<"reason">>, maps:get('Reason', Req)),
|
||||
CallArgs = {InvoiceID, PaymentID, Reason},
|
||||
Call = {invoicing, 'CancelPayment', CallArgs},
|
||||
case capi_handler_utils:service_call_with([user_info], Call, Context) of
|
||||
{ok, _} ->
|
||||
{ok, {202, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvalidPaymentStatus{} ->
|
||||
{ok, logic_error(invalidPaymentStatus, <<"Invalid payment status">>)};
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
|
||||
{ok, logic_error(invalidRequest, FormattedErrors)};
|
||||
#payproc_OperationNotPermitted{} ->
|
||||
ErrorResp = logic_error(
|
||||
operationNotPermitted,
|
||||
<<"Operation not permitted">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InvalidPartyStatus{} ->
|
||||
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)};
|
||||
#payproc_InvalidShopStatus{} ->
|
||||
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}
|
||||
end
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'CreateRefund', Req, Context) ->
|
||||
InvoiceID = maps:get('invoiceID', Req),
|
||||
PaymentID = maps:get(paymentID, Req),
|
||||
RefundParams = maps:get('RefundParams', Req),
|
||||
try create_refund(InvoiceID, PaymentID, RefundParams, Context, OperationID) of
|
||||
{ok, Refund} ->
|
||||
{ok, {201, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvalidPartyStatus{} ->
|
||||
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)};
|
||||
#payproc_InvalidShopStatus{} ->
|
||||
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)};
|
||||
#payproc_InvalidContractStatus{} ->
|
||||
ErrorResp = logic_error(
|
||||
invalidContractStatus,
|
||||
<<"Invalid contract status">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_OperationNotPermitted{} ->
|
||||
ErrorResp = logic_error(
|
||||
operationNotPermitted,
|
||||
<<"Operation not permitted">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InvalidPaymentStatus{} ->
|
||||
ErrorResp = logic_error(
|
||||
invalidPaymentStatus,
|
||||
<<"Invalid invoice payment status">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InsufficientAccountBalance{} ->
|
||||
{ok,
|
||||
logic_error(
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID, invoice => InvoiceID, payment => PaymentID}},
|
||||
{payproc, #{invoice => InvoiceID}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
Process = fun() ->
|
||||
try create_refund(InvoiceID, PaymentID, RefundParams, Context, OperationID) of
|
||||
{ok, Refund} ->
|
||||
{ok, {201, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvalidPartyStatus{} ->
|
||||
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)};
|
||||
#payproc_InvalidShopStatus{} ->
|
||||
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)};
|
||||
#payproc_InvalidContractStatus{} ->
|
||||
ErrorResp = logic_error(
|
||||
invalidContractStatus,
|
||||
<<"Invalid contract status">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_OperationNotPermitted{} ->
|
||||
ErrorResp = logic_error(
|
||||
operationNotPermitted,
|
||||
<<"Operation not permitted">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InvalidPaymentStatus{} ->
|
||||
ErrorResp = logic_error(
|
||||
invalidPaymentStatus,
|
||||
<<"Invalid invoice payment status">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InsufficientAccountBalance{} ->
|
||||
ErrResp = logic_error(
|
||||
insufficentAccountBalance,
|
||||
<<"Operation can not be conducted because of insufficient funds on the merchant account">>
|
||||
)};
|
||||
#payproc_InvoicePaymentAmountExceeded{} ->
|
||||
ErrorResp = logic_error(
|
||||
invoicePaymentAmountExceeded,
|
||||
<<"Payment amount exceeded">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InconsistentRefundCurrency{} ->
|
||||
ErrorResp = logic_error(
|
||||
inconsistentRefundCurrency,
|
||||
<<"Inconsistent refund currency">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
|
||||
{ok, logic_error(invalidRequest, FormattedErrors)}
|
||||
end
|
||||
catch
|
||||
throw:invoice_cart_empty ->
|
||||
{ok, logic_error(invalidInvoiceCart, <<"Wrong size. Path to item: cart">>)};
|
||||
throw:{external_id_conflict, RefundID, ExternalID, _Schema} ->
|
||||
{ok, logic_error(externalIDConflict, {RefundID, ExternalID})}
|
||||
end;
|
||||
process_request('GetRefunds', Context, Req) ->
|
||||
case capi_handler_utils:get_payment_by_id(maps:get(invoiceID, Req), maps:get(paymentID, Req), Context) of
|
||||
{ok, #payproc_InvoicePayment{refunds = Refunds}} ->
|
||||
{ok,
|
||||
{200, #{}, [
|
||||
capi_handler_decoder_invoicing:decode_refund(R, Context)
|
||||
|| #payproc_InvoicePaymentRefund{refund = R} <- Refunds
|
||||
]}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)}
|
||||
end
|
||||
end;
|
||||
process_request('GetRefundByID', Context, Req) ->
|
||||
case
|
||||
capi_handler_utils:get_refund_by_id(
|
||||
maps:get(invoiceID, Req),
|
||||
maps:get(paymentID, Req),
|
||||
maps:get(refundID, Req),
|
||||
Context
|
||||
)
|
||||
of
|
||||
{ok, Refund} ->
|
||||
{ok, {200, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentRefundNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice payment refund not found">>)};
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)}
|
||||
end
|
||||
end;
|
||||
process_request('GetChargebacks', Context, Req) ->
|
||||
DecodeChargebackFun = fun(C) ->
|
||||
capi_handler_decoder_invoicing:decode_chargeback(C#payproc_InvoicePaymentChargeback.chargeback, Context)
|
||||
),
|
||||
{ok, ErrResp};
|
||||
#payproc_InvoicePaymentAmountExceeded{} ->
|
||||
ErrorResp = logic_error(
|
||||
invoicePaymentAmountExceeded,
|
||||
<<"Payment amount exceeded">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#payproc_InconsistentRefundCurrency{} ->
|
||||
ErrorResp = logic_error(
|
||||
inconsistentRefundCurrency,
|
||||
<<"Inconsistent refund currency">>
|
||||
),
|
||||
{ok, ErrorResp};
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
|
||||
{ok, logic_error(invalidRequest, FormattedErrors)}
|
||||
end
|
||||
catch
|
||||
throw:invoice_cart_empty ->
|
||||
{ok, logic_error(invalidInvoiceCart, <<"Wrong size. Path to item: cart">>)};
|
||||
throw:{external_id_conflict, RefundID, ExternalID, _Schema} ->
|
||||
{ok, logic_error(externalIDConflict, {RefundID, ExternalID})}
|
||||
end
|
||||
end,
|
||||
case capi_handler_utils:get_payment_by_id(maps:get(invoiceID, Req), maps:get(paymentID, Req), Context) of
|
||||
{ok, #payproc_InvoicePayment{chargebacks = Chargebacks}} ->
|
||||
{ok, {200, #{}, [DecodeChargebackFun(C) || C <- Chargebacks]}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)}
|
||||
end
|
||||
end;
|
||||
process_request('GetChargebackByID', Context, Req) ->
|
||||
CallArgs = {maps:get(invoiceID, Req), maps:get(paymentID, Req), maps:get(chargebackID, Req)},
|
||||
Call = {invoicing, 'GetPaymentChargeback', CallArgs},
|
||||
case capi_handler_utils:service_call_with([user_info], Call, Context) of
|
||||
{ok, Chargeback} ->
|
||||
{ok, {200, #{}, capi_handler_decoder_invoicing:decode_chargeback(Chargeback, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentChargebackNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice payment chargeback not found">>)};
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
#payproc_InvoiceNotFound{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)};
|
||||
#payproc_InvalidUser{} ->
|
||||
{ok, general_error(404, <<"Invoice not found">>)}
|
||||
end
|
||||
end.
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetRefunds', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
PaymentID = maps:get(paymentID, Req),
|
||||
Invoice = map_result(get_invoice_by_id(InvoiceID, Context)),
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID, invoice => InvoiceID, payment => PaymentID}},
|
||||
{payproc, #{invoice => Invoice}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
Process = fun() ->
|
||||
capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)),
|
||||
case find_payment_by_id(PaymentID, Invoice) of
|
||||
{ok, #payproc_InvoicePayment{refunds = Refunds}} ->
|
||||
{ok,
|
||||
{200, #{}, [
|
||||
capi_handler_decoder_invoicing:decode_refund(R, Context)
|
||||
|| #payproc_InvoicePaymentRefund{refund = R} <- Refunds
|
||||
]}};
|
||||
{error, payment_not_found} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetRefundByID', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
PaymentID = maps:get(paymentID, Req),
|
||||
RefundID = maps:get(refundID, Req),
|
||||
Invoice = map_result(get_invoice_by_id(InvoiceID, Context)),
|
||||
Payment = map_result(find_payment_by_id(PaymentID, Invoice)),
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID, invoice => InvoiceID, payment => PaymentID, refund => RefundID}},
|
||||
{payproc, #{invoice => Invoice}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
|
||||
Process = fun() ->
|
||||
capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)),
|
||||
capi_handler:respond_if_undefined(Payment, general_error(404, <<"Payment not found">>)),
|
||||
|
||||
case find_refund_by_id(RefundID, Payment) of
|
||||
{ok, #payproc_InvoicePaymentRefund{refund = Refund}} ->
|
||||
{ok, {200, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}};
|
||||
{error, refund_not_found} ->
|
||||
{ok, general_error(404, <<"Invoice payment refund not found">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetRefundByExternalID', Req, Context) ->
|
||||
ExternalID = maps:get(externalID, Req),
|
||||
InternalID = map_result(get_refund_by_external_id(ExternalID, Context)),
|
||||
Invoice = map_result(
|
||||
maybe(InternalID, fun({InvoiceID, _PaymentID, _RefundID}) ->
|
||||
get_invoice_by_id(InvoiceID, Context)
|
||||
end)
|
||||
),
|
||||
OperationPrototype = maybe(InternalID, fun({InvoiceID, PaymentID, RefundID}) ->
|
||||
#{id => OperationID, invoice => InvoiceID, payment => PaymentID, refund => RefundID}
|
||||
end),
|
||||
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, genlib:define(OperationPrototype, #{id => OperationID})},
|
||||
{payproc, #{invoice => Invoice}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
|
||||
Process = fun() ->
|
||||
capi_handler:respond_if_undefined(InternalID, general_error(404, <<"Refund not found">>)),
|
||||
capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)),
|
||||
{_InvoiceID, PaymentID, RefundID} = InternalID,
|
||||
Payment = map_result(find_payment_by_id(PaymentID, Invoice)),
|
||||
capi_handler:respond_if_undefined(Payment, general_error(404, <<"Payment not found">>)),
|
||||
|
||||
case find_refund_by_id(RefundID, Payment) of
|
||||
{ok, #payproc_InvoicePaymentRefund{refund = Refund}} ->
|
||||
{ok, {200, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}};
|
||||
{error, refund_not_found} ->
|
||||
{ok, general_error(404, <<"Invoice payment refund not found">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetChargebacks', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
PaymentID = maps:get(paymentID, Req),
|
||||
Invoice = map_result(get_invoice_by_id(InvoiceID, Context)),
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID, invoice => InvoiceID, payment => PaymentID}},
|
||||
{payproc, #{invoice => Invoice}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
Process = fun() ->
|
||||
capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)),
|
||||
DecodeChargebackFun = fun(C) ->
|
||||
capi_handler_decoder_invoicing:decode_chargeback(C#payproc_InvoicePaymentChargeback.chargeback, Context)
|
||||
end,
|
||||
case find_payment_by_id(PaymentID, Invoice) of
|
||||
{ok, #payproc_InvoicePayment{chargebacks = Chargebacks}} ->
|
||||
{ok, {200, #{}, [DecodeChargebackFun(C) || C <- Chargebacks]}};
|
||||
{error, payment_not_found} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(OperationID = 'GetChargebackByID', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
PaymentID = maps:get(paymentID, Req),
|
||||
ChargebackID = maps:get(chargebackID, Req),
|
||||
Invoice = map_result(get_invoice_by_id(InvoiceID, Context)),
|
||||
Payment = map_result(find_payment_by_id(PaymentID, Invoice)),
|
||||
|
||||
Authorize = fun() ->
|
||||
Prototypes = [
|
||||
{operation, #{id => OperationID, invoice => InvoiceID, payment => PaymentID}},
|
||||
{payproc, #{invoice => Invoice}}
|
||||
],
|
||||
{ok, capi_auth:authorize_operation(OperationID, Prototypes, Context, Req)}
|
||||
end,
|
||||
Process = fun() ->
|
||||
capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)),
|
||||
capi_handler:respond_if_undefined(Payment, general_error(404, <<"Payment not found">>)),
|
||||
case find_chargeback_by_id(ChargebackID, Payment) of
|
||||
{ok, Chargeback} ->
|
||||
{ok, {200, #{}, capi_handler_decoder_invoicing:decode_chargeback(Chargeback, Context)}};
|
||||
{error, chargeback_not_found} ->
|
||||
{ok, general_error(404, <<"Invoice payment chargeback not found">>)}
|
||||
end
|
||||
end,
|
||||
{ok, #{authorize => Authorize, process => Process}};
|
||||
prepare(_OperationID, _Req, _Context) ->
|
||||
{error, noimpl}.
|
||||
|
||||
%%
|
||||
|
||||
create_payment(InvoiceID, PartyID, PaymentParams, Context, BenderPrefix) ->
|
||||
create_payment(Invoice, PaymentParams, Context, BenderPrefix) ->
|
||||
ExternalID = maps:get(<<"externalID">>, PaymentParams, undefined),
|
||||
#payproc_Invoice{invoice = #domain_Invoice{id = InvoiceID, owner_id = PartyID}} = Invoice,
|
||||
IdempotentKey = {BenderPrefix, PartyID, ExternalID},
|
||||
{Payer, PaymentToolThrift} = decrypt_payer(maps:get(<<"payer">>, PaymentParams)),
|
||||
|
||||
@ -443,6 +511,62 @@ start_payment(ID, InvoiceID, ExternalID, PaymentParamsDecrypted, PaymentToolThri
|
||||
Call = {invoicing, 'StartPayment', {InvoiceID, InvoicePaymentParams}},
|
||||
capi_handler_utils:service_call_with([user_info], Call, Context).
|
||||
|
||||
find_payment_by_id(PaymentID, #payproc_Invoice{payments = Payments}) ->
|
||||
Fun = fun(#payproc_InvoicePayment{payment = #domain_InvoicePayment{id = ID}}) ->
|
||||
PaymentID == ID
|
||||
end,
|
||||
case find_by(Fun, genlib:define(Payments, [])) of
|
||||
undefined ->
|
||||
{error, payment_not_found};
|
||||
Payment ->
|
||||
{ok, Payment}
|
||||
end.
|
||||
|
||||
find_refund_by_id(RefundID, #payproc_InvoicePayment{refunds = Refunds}) ->
|
||||
Fun = fun(#payproc_InvoicePaymentRefund{refund = Refund}) ->
|
||||
Refund#domain_InvoicePaymentRefund.id == RefundID
|
||||
end,
|
||||
case find_by(Fun, genlib:define(Refunds, [])) of
|
||||
undefined ->
|
||||
{error, refund_not_found};
|
||||
Refund ->
|
||||
{ok, Refund}
|
||||
end.
|
||||
|
||||
find_chargeback_by_id(ChargebackID, #payproc_InvoicePayment{chargebacks = Chargebacks}) ->
|
||||
Fun = fun(#payproc_InvoicePaymentChargeback{chargeback = Chargeback}) ->
|
||||
Chargeback#domain_InvoicePaymentChargeback.id == ChargebackID
|
||||
end,
|
||||
case find_by(Fun, genlib:define(Chargebacks, [])) of
|
||||
undefined ->
|
||||
{error, chargeback_not_found};
|
||||
Chargeback ->
|
||||
{ok, Chargeback}
|
||||
end.
|
||||
|
||||
find_by(Fun, [E | Rest]) ->
|
||||
case Fun(E) of
|
||||
true -> E;
|
||||
false -> find_by(Fun, Rest)
|
||||
end;
|
||||
find_by(_, []) ->
|
||||
undefined.
|
||||
|
||||
get_invoice_by_id(InvoiceID, Context) ->
|
||||
case capi_handler_utils:get_invoice_by_id(InvoiceID, Context) of
|
||||
{ok, Invoice} ->
|
||||
{ok, Invoice};
|
||||
{exception, #payproc_InvalidUser{}} ->
|
||||
{error, invalid_user};
|
||||
{exception, #payproc_InvoiceNotFound{}} ->
|
||||
{error, invoice_not_found}
|
||||
end.
|
||||
|
||||
map_result({ok, Value}) ->
|
||||
Value;
|
||||
map_result(_) ->
|
||||
undefined.
|
||||
|
||||
decrypt_payer(#{<<"payerType">> := <<"PaymentResourcePayer">>} = Payer) ->
|
||||
#{<<"paymentToolToken">> := Token} = Payer,
|
||||
Payer2 = maps:without([<<"paymentToolToken">>], Payer),
|
||||
@ -559,39 +683,24 @@ get_refund_by_external_id(ExternalID, #{woody_context := WoodyContext} = Context
|
||||
IdempotentKey = {'CreateRefund', PartyID, ExternalID},
|
||||
case capi_bender:get_internal_id(IdempotentKey, WoodyContext) of
|
||||
{ok, RefundID, CtxData} ->
|
||||
InvoiceID = maps:get(<<"invoice_id">>, CtxData, undefined),
|
||||
PaymentID = maps:get(<<"payment_id">>, CtxData, undefined),
|
||||
get_refund(InvoiceID, PaymentID, RefundID, Context);
|
||||
Error ->
|
||||
InvoiceID = maps:get(<<"invoice_id">>, CtxData),
|
||||
PaymentID = maps:get(<<"payment_id">>, CtxData),
|
||||
{ok, {InvoiceID, PaymentID, RefundID}};
|
||||
{error, internal_id_not_found} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
get_refund(undefined, _, _, _) ->
|
||||
{error, invoice_not_found};
|
||||
get_refund(_, undefined, _, _) ->
|
||||
{error, payment_not_found};
|
||||
get_refund(InvoiceID, PaymentID, RefundID, Context) ->
|
||||
capi_handler_utils:get_refund_by_id(InvoiceID, PaymentID, RefundID, Context).
|
||||
|
||||
-spec get_payment_by_external_id(binary(), capi_handler:processing_context()) -> woody:result().
|
||||
-spec get_payment_by_external_id(binary(), capi_handler:processing_context()) ->
|
||||
{ok, {binary(), binary()}}
|
||||
| {error, internal_id_not_found}.
|
||||
get_payment_by_external_id(ExternalID, #{woody_context := WoodyContext} = Context) ->
|
||||
PartyID = capi_handler_utils:get_party_id(Context),
|
||||
IdempotentKey = {'CreatePayment', PartyID, ExternalID},
|
||||
case capi_bender:get_internal_id(IdempotentKey, WoodyContext) of
|
||||
{ok, PaymentID, CtxData} ->
|
||||
InvoiceID = maps:get(<<"invoice_id">>, CtxData, undefined),
|
||||
get_payment(InvoiceID, PaymentID, Context);
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
get_payment(undefined, _, _) ->
|
||||
{error, invoice_not_found};
|
||||
get_payment(InvoiceID, PaymentID, Context) ->
|
||||
case capi_handler_utils:get_payment_by_id(InvoiceID, PaymentID, Context) of
|
||||
{ok, Payment} ->
|
||||
{ok, InvoiceID, Payment};
|
||||
Error ->
|
||||
InvoiceID = maps:get(<<"invoice_id">>, CtxData),
|
||||
{ok, {InvoiceID, PaymentID}};
|
||||
{error, internal_id_not_found} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
@ -644,3 +753,8 @@ create_sequence_id([Identifier | Rest], BenderPrefix) ->
|
||||
<<Identifier/binary, ".", Next/binary>>;
|
||||
create_sequence_id([], BenderPrefix) ->
|
||||
genlib:to_binary(BenderPrefix).
|
||||
|
||||
maybe(undefined, _) ->
|
||||
undefined;
|
||||
maybe(V, Fun) ->
|
||||
Fun(V).
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
-include_lib("damsel/include/dmsl_domain_config_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
|
||||
-include_lib("capi_dummy_data.hrl").
|
||||
-include_lib("jose/include/jose_jwk.hrl").
|
||||
|
||||
@ -29,7 +29,6 @@
|
||||
authorization_bad_token_error_test/1
|
||||
]).
|
||||
|
||||
-define(badresp(Code), {error, {invalid_response_code, Code}}).
|
||||
-define(emptyresp(Code), {error, {Code, #{}}}).
|
||||
|
||||
-type test_case_name() :: atom().
|
||||
@ -80,7 +79,7 @@ end_per_suite(C) ->
|
||||
-spec init_per_group(group_name(), config()) -> config().
|
||||
init_per_group(_, Config) ->
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
Apps = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
Apps = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
[{group_apps, Apps}, {group_test_sup, SupPid} | Config].
|
||||
|
||||
-spec end_per_group(group_name(), config()) -> _.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,11 +42,16 @@
|
||||
payment = ?CTX_ENTITY(PaymentID)
|
||||
}).
|
||||
|
||||
-define(CTX_PAYMENT_OP(ID, InvoiceID), #bctx_v1_CommonAPIOperation{
|
||||
id = ID,
|
||||
invoice = ?CTX_ENTITY(InvoiceID)
|
||||
}).
|
||||
|
||||
-define(CTX_REFUND_OP(ID, InvoiceID, PaymentID, RefundID), #bctx_v1_CommonAPIOperation{
|
||||
id = ID,
|
||||
invoice = ?CTX_ENTITY(InvoiceID),
|
||||
payment = ?CTX_ENTITY(PaymentID),
|
||||
refund = ?CTX_ENTITY(PaymentID)
|
||||
refund = ?CTX_ENTITY(RefundID)
|
||||
}).
|
||||
|
||||
-define(CTX_INVOICE_TPL_OP(ID, InvoiceTemplateID), #bctx_v1_CommonAPIOperation{
|
||||
@ -76,6 +81,39 @@
|
||||
party = ?CTX_ENTITY(PartyID)
|
||||
}).
|
||||
|
||||
-define(CTX_SEARCH_INVOICE_OP(ID, PartyID, ShopID, InvoiceID, PaymentID, CustomerID), #bctx_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), #bctx_v1_CommonAPIOperation{
|
||||
id = ID,
|
||||
party = ?CTX_ENTITY(PartyID),
|
||||
shop = ?CTX_ENTITY(ShopID),
|
||||
invoice = ?CTX_ENTITY(InvoiceID),
|
||||
payment = ?CTX_ENTITY(PaymentID)
|
||||
}).
|
||||
|
||||
-define(CTX_SEARCH_PAYOUT_OP(ID, PartyID, ShopID, PayoutID), #bctx_v1_CommonAPIOperation{
|
||||
id = ID,
|
||||
party = ?CTX_ENTITY(PartyID),
|
||||
shop = ?CTX_ENTITY(ShopID),
|
||||
payout = ?CTX_ENTITY(PayoutID)
|
||||
}).
|
||||
|
||||
-define(CTX_SEARCH_REFUND_OP(ID, PartyID, ShopID, InvoiceID, PaymentID, RefundID), #bctx_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,
|
||||
@ -151,8 +189,14 @@
|
||||
}).
|
||||
|
||||
-define(assertContextMatches(Expect), fun(Context) ->
|
||||
?assertMatch(Expect, Context),
|
||||
{ok, ?JUDGEMENT(?ALLOWED)}
|
||||
try
|
||||
?assertMatch(Expect, Context),
|
||||
{ok, ?JUDGEMENT(?ALLOWED)}
|
||||
catch
|
||||
error:AssertMatchError:Stacktrace ->
|
||||
logger:error("failed ~p at ~p", [AssertMatchError, Stacktrace]),
|
||||
{throwing, #bdcs_InvalidContext{}}
|
||||
end
|
||||
end).
|
||||
|
||||
-endif.
|
||||
|
@ -55,7 +55,7 @@ init_suite(Module, Config, CapiEnv) ->
|
||||
Apps2 =
|
||||
start_app(dmt_client, [{max_cache_size, #{}}, {service_urls, ServiceURLs}, {cache_update_interval, 50000}]) ++
|
||||
start_capi(Config, CapiEnv) ++
|
||||
capi_ct_helper_bouncer:mock_bouncer_client(SupPid),
|
||||
capi_ct_helper_bouncer:mock_client(SupPid),
|
||||
[{apps, lists:reverse(Apps1 ++ Apps2)}, {suite_test_sup, SupPid} | Config].
|
||||
|
||||
-spec start_app(app_name()) -> [app_name()].
|
||||
|
@ -5,29 +5,34 @@
|
||||
-include_lib("capi_bouncer_data.hrl").
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
|
||||
-export([mock_bouncer_assert_op_ctx/2]).
|
||||
-export([mock_bouncer_assert_party_op_ctx/3]).
|
||||
-export([mock_bouncer_assert_shop_op_ctx/4]).
|
||||
-export([mock_bouncer_assert_contract_op_ctx/4]).
|
||||
-export([mock_bouncer_assert_invoice_op_ctx/5]).
|
||||
-export([mock_bouncer_assert_payment_op_ctx/6]).
|
||||
-export([mock_bouncer_assert_invoice_tpl_op_ctx/5]).
|
||||
-export([mock_bouncer_assert_customer_op_ctx/5]).
|
||||
-export([mock_bouncer_assert_claim_op_ctx/4]).
|
||||
-export([mock_bouncer_assert_webhook_op_ctx/4]).
|
||||
-export([mock_bouncer_assert_payout_op_ctx/6]).
|
||||
-export([mock_bouncer_assert_search_op_ctx/9]).
|
||||
-export([mock_assert_op_ctx/2]).
|
||||
-export([mock_assert_party_op_ctx/3]).
|
||||
-export([mock_assert_shop_op_ctx/4]).
|
||||
-export([mock_assert_contract_op_ctx/4]).
|
||||
-export([mock_assert_invoice_op_ctx/5]).
|
||||
-export([mock_assert_payment_op_ctx/5]).
|
||||
-export([mock_assert_payment_op_ctx/6]).
|
||||
-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/6]).
|
||||
-export([mock_assert_search_payout_op_ctx/5]).
|
||||
-export([mock_assert_search_refund_op_ctx/7]).
|
||||
|
||||
-export([mock_bouncer_client/1]).
|
||||
-export([mock_bouncer_arbiter/2]).
|
||||
-export([mock_client/1]).
|
||||
-export([mock_arbiter/2]).
|
||||
-export([judge_always_allowed/0]).
|
||||
-export([judge_always_forbidden/0]).
|
||||
|
||||
%%
|
||||
|
||||
-spec mock_bouncer_assert_op_ctx(_, _) -> _.
|
||||
mock_bouncer_assert_op_ctx(Op, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_op_ctx(_, _) -> _.
|
||||
mock_assert_op_ctx(Op, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_CAPI_OP(Op))
|
||||
@ -36,9 +41,9 @@ mock_bouncer_assert_op_ctx(Op, Config) ->
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_party_op_ctx(_, _, _) -> _.
|
||||
mock_bouncer_assert_party_op_ctx(Op, PartyID, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_party_op_ctx(_, _, _) -> _.
|
||||
mock_assert_party_op_ctx(Op, PartyID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_PARTY_OP(Op, PartyID))
|
||||
@ -47,9 +52,9 @@ mock_bouncer_assert_party_op_ctx(Op, PartyID, Config) ->
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_shop_op_ctx(_, _, _, _) -> _.
|
||||
mock_bouncer_assert_shop_op_ctx(Op, PartyID, ShopID, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_shop_op_ctx(_, _, _, _) -> _.
|
||||
mock_assert_shop_op_ctx(Op, PartyID, ShopID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_SHOP_OP(Op, PartyID, ShopID))
|
||||
@ -58,9 +63,9 @@ mock_bouncer_assert_shop_op_ctx(Op, PartyID, ShopID, Config) ->
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_contract_op_ctx(_, _, _, _) -> _.
|
||||
mock_bouncer_assert_contract_op_ctx(Op, PartyID, ContractID, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_contract_op_ctx(_, _, _, _) -> _.
|
||||
mock_assert_contract_op_ctx(Op, PartyID, ContractID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_CONTRACT_OP(Op, PartyID, ContractID))
|
||||
@ -69,9 +74,9 @@ mock_bouncer_assert_contract_op_ctx(Op, PartyID, ContractID, Config) ->
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_invoice_op_ctx(_, _, _, _, _) -> _.
|
||||
mock_bouncer_assert_invoice_op_ctx(Op, InvoiceID, PartyID, ShopID, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_invoice_op_ctx(_, _, _, _, _) -> _.
|
||||
mock_assert_invoice_op_ctx(Op, InvoiceID, PartyID, ShopID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_INVOICE_OP(Op, InvoiceID)),
|
||||
@ -83,9 +88,9 @@ mock_bouncer_assert_invoice_op_ctx(Op, InvoiceID, PartyID, ShopID, Config) ->
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_payment_op_ctx(_, _, _, _, _, _) -> _.
|
||||
mock_bouncer_assert_payment_op_ctx(Op, InvoiceID, PaymentID, PartyID, ShopID, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_payment_op_ctx(_, _, _, _, _, _) -> _.
|
||||
mock_assert_payment_op_ctx(Op, InvoiceID, PaymentID, PartyID, ShopID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_PAYMENT_OP(Op, InvoiceID, PaymentID)),
|
||||
@ -97,9 +102,37 @@ mock_bouncer_assert_payment_op_ctx(Op, InvoiceID, PaymentID, PartyID, ShopID, Co
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_invoice_tpl_op_ctx(_, _, _, _, _) -> _.
|
||||
mock_bouncer_assert_invoice_tpl_op_ctx(Op, InvoiceTemplateID, PartyID, ShopID, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_payment_op_ctx(_, _, _, _, _) -> _.
|
||||
mock_assert_payment_op_ctx(Op, InvoiceID, PartyID, ShopID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_PAYMENT_OP(Op, InvoiceID)),
|
||||
payment_processing = #bctx_v1_ContextPaymentProcessing{
|
||||
invoice = ?CTX_INVOICE(InvoiceID, PartyID, ShopID, [])
|
||||
}
|
||||
}
|
||||
),
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_assert_refund_op_ctx(_, _, _, _, _, _, _) -> _.
|
||||
mock_assert_refund_op_ctx(Op, InvoiceID, PaymentID, RefundID, PartyID, ShopID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_REFUND_OP(Op, InvoiceID, PaymentID, RefundID)),
|
||||
payment_processing = #bctx_v1_ContextPaymentProcessing{
|
||||
invoice = ?CTX_INVOICE(InvoiceID, PartyID, ShopID, [?CTX_PAYMENT(PaymentID)])
|
||||
}
|
||||
}
|
||||
),
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_assert_invoice_tpl_op_ctx(_, _, _, _, _) -> _.
|
||||
mock_assert_invoice_tpl_op_ctx(Op, InvoiceTemplateID, PartyID, ShopID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_INVOICE_TPL_OP(Op, InvoiceTemplateID)),
|
||||
@ -111,9 +144,9 @@ mock_bouncer_assert_invoice_tpl_op_ctx(Op, InvoiceTemplateID, PartyID, ShopID, C
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_customer_op_ctx(_, _, _, _, _) -> _.
|
||||
mock_bouncer_assert_customer_op_ctx(Op, CustomerID, PartyID, ShopID, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_customer_op_ctx(_, _, _, _, _) -> _.
|
||||
mock_assert_customer_op_ctx(Op, CustomerID, PartyID, ShopID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_CUSTOMER_OP(Op, CustomerID)),
|
||||
@ -125,9 +158,9 @@ mock_bouncer_assert_customer_op_ctx(Op, CustomerID, PartyID, ShopID, Config) ->
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_claim_op_ctx(_, _, _, _) -> _.
|
||||
mock_bouncer_assert_claim_op_ctx(Op, PartyID, ClaimID, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_claim_op_ctx(_, _, _, _) -> _.
|
||||
mock_assert_claim_op_ctx(Op, PartyID, ClaimID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_CLAIM_OP(Op, PartyID, ClaimID))
|
||||
@ -136,9 +169,9 @@ mock_bouncer_assert_claim_op_ctx(Op, PartyID, ClaimID, Config) ->
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_webhook_op_ctx(_, _, _, _) -> _.
|
||||
mock_bouncer_assert_webhook_op_ctx(Op, WebhookID, PartyID, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_webhook_op_ctx(_, _, _, _) -> _.
|
||||
mock_assert_webhook_op_ctx(Op, WebhookID, PartyID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_WEBHOOK_OP(Op, WebhookID)),
|
||||
@ -150,9 +183,9 @@ mock_bouncer_assert_webhook_op_ctx(Op, WebhookID, PartyID, Config) ->
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_payout_op_ctx(_, _, _, _, _, _) -> _.
|
||||
mock_bouncer_assert_payout_op_ctx(Op, PayoutID, PartyID, ContractID, ShopID, Config) ->
|
||||
mock_bouncer_arbiter(
|
||||
-spec mock_assert_payout_op_ctx(_, _, _, _, _, _) -> _.
|
||||
mock_assert_payout_op_ctx(Op, PayoutID, PartyID, ContractID, ShopID, Config) ->
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(?CTX_PAYOUT_OP(Op, PayoutID, PartyID)),
|
||||
@ -164,19 +197,70 @@ mock_bouncer_assert_payout_op_ctx(Op, PayoutID, PartyID, ContractID, ShopID, Con
|
||||
Config
|
||||
).
|
||||
|
||||
-spec mock_bouncer_assert_search_op_ctx(_, _, _, _, _, _, _, _, _) -> _.
|
||||
mock_bouncer_assert_search_op_ctx(Op, PartyID, ShopID, InvoiceID, PaymentID, CustomerID, PayoutID, RefundID, Config) ->
|
||||
SearchCtx = ?CTX_SEARCH_OP(
|
||||
-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
|
||||
),
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_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(
|
||||
#bctx_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,
|
||||
CustomerID,
|
||||
PayoutID,
|
||||
RefundID
|
||||
),
|
||||
mock_bouncer_arbiter(
|
||||
mock_arbiter(
|
||||
?assertContextMatches(
|
||||
#bctx_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(
|
||||
#bctx_v1_ContextFragment{
|
||||
capi = ?CTX_CAPI(SearchCtx)
|
||||
@ -186,15 +270,14 @@ mock_bouncer_assert_search_op_ctx(Op, PartyID, ShopID, InvoiceID, PaymentID, Cus
|
||||
).
|
||||
|
||||
%%
|
||||
|
||||
start_bouncer_client(ServiceURLs) ->
|
||||
start_client(ServiceURLs) ->
|
||||
ServiceClients = maps:map(fun(_, URL) -> #{url => URL} end, ServiceURLs),
|
||||
Acc = application:get_env(bouncer_client, service_clients, #{}),
|
||||
capi_ct_helper:start_app(bouncer_client, [{service_clients, maps:merge(Acc, ServiceClients)}]).
|
||||
|
||||
-spec mock_bouncer_client(_) -> _.
|
||||
mock_bouncer_client(SupOrConfig) ->
|
||||
start_bouncer_client(
|
||||
-spec mock_client(_) -> _.
|
||||
mock_client(SupOrConfig) ->
|
||||
start_client(
|
||||
capi_ct_helper:mock_services_(
|
||||
[
|
||||
{
|
||||
@ -216,16 +299,16 @@ mock_bouncer_client(SupOrConfig) ->
|
||||
)
|
||||
).
|
||||
|
||||
-spec mock_bouncer_arbiter(_, _) -> _.
|
||||
mock_bouncer_arbiter(JudgeFun, SupOrConfig) ->
|
||||
start_bouncer_client(
|
||||
-spec mock_arbiter(_, _) -> _.
|
||||
mock_arbiter(JudgeFun, SupOrConfig) ->
|
||||
start_client(
|
||||
capi_ct_helper:mock_services_(
|
||||
[
|
||||
{
|
||||
bouncer,
|
||||
{bouncer_decisions_thrift, 'Arbiter'},
|
||||
fun('Judge', {?TEST_RULESET_ID, Context}) ->
|
||||
Fragments = decode_bouncer_context(Context),
|
||||
Fragments = decode_context(Context),
|
||||
Combined = combine_fragments(Fragments),
|
||||
JudgeFun(Combined)
|
||||
end
|
||||
@ -235,10 +318,10 @@ mock_bouncer_arbiter(JudgeFun, SupOrConfig) ->
|
||||
)
|
||||
).
|
||||
|
||||
decode_bouncer_context(#bdcs_Context{fragments = Fragments}) ->
|
||||
maps:map(fun(_, Fragment) -> decode_bouncer_fragment(Fragment) end, Fragments).
|
||||
decode_context(#bdcs_Context{fragments = Fragments}) ->
|
||||
maps:map(fun(_, Fragment) -> decode_fragment(Fragment) end, Fragments).
|
||||
|
||||
decode_bouncer_fragment(#bctx_ContextFragment{type = v1_thrift_binary, content = Content}) ->
|
||||
decode_fragment(#bctx_ContextFragment{type = v1_thrift_binary, content = Content}) ->
|
||||
Type = {struct, struct, {bouncer_context_v1_thrift, 'ContextFragment'}},
|
||||
Codec = thrift_strict_binary_codec:new(Content),
|
||||
{ok, Fragment, _} = thrift_strict_binary_codec:read(Codec, Type),
|
||||
|
@ -2,10 +2,8 @@
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
-include_lib("damsel/include/dmsl_domain_config_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl").
|
||||
-include_lib("capi_dummy_data.hrl").
|
||||
-include_lib("jose/include/jose_jwk.hrl").
|
||||
|
||||
-export([all/0]).
|
||||
-export([groups/0]).
|
||||
@ -27,12 +25,6 @@
|
||||
get_customer_events_ok_test/1
|
||||
]).
|
||||
|
||||
-define(CAPI_PORT, 8080).
|
||||
-define(CAPI_HOST_NAME, "localhost").
|
||||
-define(CAPI_URL, ?CAPI_HOST_NAME ++ ":" ++ integer_to_list(?CAPI_PORT)).
|
||||
|
||||
-define(badresp(Code), {error, {invalid_response_code, Code}}).
|
||||
|
||||
-type test_case_name() :: atom().
|
||||
-type config() :: [{atom(), any()}].
|
||||
-type group_name() :: atom().
|
||||
@ -90,7 +82,7 @@ init_per_group(operations_by_customer_access_token_after_customer_creation, Conf
|
||||
],
|
||||
MockServiceSup
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), MockServiceSup),
|
||||
_ = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), MockServiceSup),
|
||||
{ok, Token} = capi_ct_helper:issue_token([{[customers], write}], unlimited),
|
||||
Req = #{
|
||||
<<"shopID">> => ?STRING,
|
||||
@ -102,12 +94,12 @@ init_per_group(operations_by_customer_access_token_after_customer_creation, Conf
|
||||
}} = capi_client_customers:create_customer(capi_ct_helper:get_context(Token), Req),
|
||||
_ = capi_ct_helper:stop_mocked_service_sup(MockServiceSup),
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
Apps = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
Apps = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
[{context, capi_ct_helper:get_context(CustAccToken)}, {group_apps, Apps}, {group_test_sup, SupPid} | Config];
|
||||
init_per_group(operations_by_customer_access_token_after_token_creation, Config) ->
|
||||
MockServiceSup = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
_ = capi_ct_helper:mock_services([{customer_management, fun('Get', _) -> {ok, ?CUSTOMER} end}], MockServiceSup),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), MockServiceSup),
|
||||
_ = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), MockServiceSup),
|
||||
{ok, Token} = capi_ct_helper:issue_token([{[customers], write}], unlimited),
|
||||
{ok, #{<<"payload">> := CustAccToken}} = capi_client_customers:create_customer_access_token(
|
||||
capi_ct_helper:get_context(Token),
|
||||
@ -115,7 +107,7 @@ init_per_group(operations_by_customer_access_token_after_token_creation, Config)
|
||||
),
|
||||
_ = capi_ct_helper:stop_mocked_service_sup(MockServiceSup),
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
Apps = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
Apps = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
[{context, capi_ct_helper:get_context(CustAccToken)}, {group_apps, Apps}, {group_test_sup, SupPid} | Config];
|
||||
init_per_group(_, Config) ->
|
||||
Config.
|
||||
|
@ -2,9 +2,8 @@
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
-include_lib("damsel/include/dmsl_domain_config_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
|
||||
-include_lib("capi_dummy_data.hrl").
|
||||
-include_lib("jose/include/jose_jwk.hrl").
|
||||
|
||||
-export([all/0]).
|
||||
-export([groups/0]).
|
||||
@ -86,7 +85,7 @@ init_per_group(deadline_header, Config) ->
|
||||
Context = capi_ct_helper:get_context(Token),
|
||||
Config2 = [{context_with_relative_deadline, get_context(Token2, <<"3s">>)} | Config],
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
[{context_with_absolute_deadline, Context}, {group_apps, Apps1}, {group_test_sup, SupPid} | Config2];
|
||||
init_per_group(_, Config) ->
|
||||
Config.
|
||||
|
@ -312,6 +312,11 @@
|
||||
external_id = EID
|
||||
}).
|
||||
|
||||
-define(PAYPROC_REFUND(ID, EID), #payproc_InvoicePaymentRefund{
|
||||
refund = ?REFUND(ID, EID),
|
||||
sessions = []
|
||||
}).
|
||||
|
||||
-define(CHARGEBACK, ?CHARGEBACK(?STRING)).
|
||||
|
||||
-define(PAYPROC_CHARGEBACK, ?PAYPROC_CHARGEBACK(?STRING)).
|
||||
@ -1200,9 +1205,11 @@
|
||||
bank_card = ?BANK_CARD
|
||||
}).
|
||||
|
||||
-define(PAYOUT(Type, PayoutSummary), #'payout_processing_Payout'{
|
||||
-define(PAYOUT(Type, PayoutSummary), ?PAYOUT(Type, ?STRING, PayoutSummary)).
|
||||
|
||||
-define(PAYOUT(Type, PartyID, PayoutSummary), #'payout_processing_Payout'{
|
||||
id = ?STRING,
|
||||
party_id = ?STRING,
|
||||
party_id = PartyID,
|
||||
shop_id = ?STRING,
|
||||
contract_id = ?STRING,
|
||||
created_at = ?TIMESTAMP,
|
||||
@ -1336,3 +1343,18 @@
|
||||
<<"how_about_null">> => null
|
||||
}
|
||||
}).
|
||||
|
||||
-define(PAYMENT_PARAMS(EID, Token), #{
|
||||
<<"externalID">> => EID,
|
||||
<<"flow">> => #{<<"type">> => <<"PaymentFlowInstant">>},
|
||||
<<"payer">> => #{
|
||||
<<"payerType">> => <<"PaymentResourcePayer">>,
|
||||
<<"paymentSession">> => ?TEST_PAYMENT_SESSION,
|
||||
<<"paymentToolToken">> => Token,
|
||||
<<"contactInfo">> => #{
|
||||
<<"email">> => <<"bla@bla.ru">>
|
||||
}
|
||||
},
|
||||
<<"metadata">> => ?JSON,
|
||||
<<"processingDeadline">> => <<"5m">>
|
||||
}).
|
||||
|
@ -4,7 +4,6 @@
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
|
||||
-include_lib("capi_dummy_data.hrl").
|
||||
-include_lib("damsel/include/dmsl_domain_config_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl").
|
||||
|
||||
-export([all/0]).
|
||||
@ -132,7 +131,6 @@ init_per_group(payment_creation, Config) ->
|
||||
],
|
||||
MockServiceSup
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_shop_op_ctx(<<"CreateInvoice">>, ?STRING, ?STRING, MockServiceSup),
|
||||
Req = #{
|
||||
<<"shopID">> => ?STRING,
|
||||
<<"amount">> => ?INTEGER,
|
||||
@ -142,6 +140,8 @@ init_per_group(payment_creation, Config) ->
|
||||
<<"product">> => <<"test_product">>,
|
||||
<<"description">> => <<"test_invoice_description">>
|
||||
},
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
{{ok, #{
|
||||
<<"invoiceAccessToken">> := #{<<"payload">> := InvAccToken}
|
||||
}},
|
||||
@ -151,67 +151,21 @@ init_per_group(payment_creation, Config) ->
|
||||
end),
|
||||
|
||||
capi_ct_helper:stop_mocked_service_sup(MockServiceSup),
|
||||
[{context, capi_ct_helper:get_context(InvAccToken)} | Config];
|
||||
init_per_group(invoice_with_template_creation, Config) ->
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
|
||||
BasePermissions = base_permissions(),
|
||||
|
||||
{ok, Token} = capi_ct_helper:issue_token(BasePermissions, unlimited),
|
||||
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{customer_management, fun('Get', _) ->
|
||||
{ok, ?CUSTOMER}
|
||||
end},
|
||||
{invoice_templating, fun('Create', _) -> {ok, ?INVOICE_TPL} end},
|
||||
{bender, fun('GenerateID', {_, _, CtxMsgPack}) ->
|
||||
{ok, capi_ct_helper_bender:get_result(<<"bender_key">>, CtxMsgPack)}
|
||||
end}
|
||||
],
|
||||
SupPid
|
||||
),
|
||||
Req = #{
|
||||
<<"externalID">> => genlib:unique(),
|
||||
<<"shopID">> => <<"1">>,
|
||||
<<"lifetime">> => #{
|
||||
<<"days">> => ?INTEGER,
|
||||
<<"months">> => ?INTEGER,
|
||||
<<"years">> => ?INTEGER
|
||||
},
|
||||
<<"details">> => ?INVOICE_TMPL_DETAILS_PARAMS,
|
||||
<<"description">> => <<"Sample text">>
|
||||
},
|
||||
{{ok, #{
|
||||
<<"invoiceTemplate">> := #{<<"id">> := InvoiceTemplateID}
|
||||
}},
|
||||
_} =
|
||||
with_feature_storage(fun() ->
|
||||
capi_client_invoice_templates:create(capi_ct_helper:get_context(Token, #{}), Req)
|
||||
end),
|
||||
|
||||
Apps1 = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
|
||||
[
|
||||
{invoice_template_id, InvoiceTemplateID},
|
||||
{context, capi_ct_helper:get_context(Token)},
|
||||
{group_apps, Apps1},
|
||||
{group_test_sup, SupPid}
|
||||
| Config
|
||||
];
|
||||
[{context, capi_ct_helper:get_context(InvAccToken)}, {group_apps, Apps1} | Config];
|
||||
init_per_group(GroupName, Config) when
|
||||
GroupName =:= invoice_creation orelse
|
||||
GroupName =:= refund_creation orelse
|
||||
GroupName =:= customer_binding_creation orelse
|
||||
GroupName =:= invoice_template_creation orelse
|
||||
GroupName =:= customer_creation
|
||||
GroupName =:= customer_creation orelse
|
||||
GroupName =:= invoice_with_template_creation
|
||||
->
|
||||
BasePermissions = base_permissions(),
|
||||
{ok, Token} = capi_ct_helper:issue_token(BasePermissions, unlimited),
|
||||
{ok, Token2} = capi_ct_helper:issue_token(<<"TEST2">>, BasePermissions, unlimited, #{}),
|
||||
Config2 = [{context_with_diff_party, capi_ct_helper:get_context(Token2)} | Config],
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
[{context, capi_ct_helper:get_context(Token)}, {group_apps, Apps1}, {group_test_sup, SupPid} | Config2];
|
||||
init_per_group(_, Config) ->
|
||||
Config.
|
||||
@ -571,7 +525,7 @@ create_invoice_template_fail_test(Config) ->
|
||||
-spec create_invoice_with_template_ok_test(config()) -> _.
|
||||
create_invoice_with_template_ok_test(Config) ->
|
||||
BenderKey = <<"create_invoice_with_template_ok_test">>,
|
||||
InvoiceTemplateID = ?config(invoice_template_id, Config),
|
||||
InvoiceTemplateID = ?STRING,
|
||||
Req1 = #{
|
||||
<<"externalID">> => genlib:unique(),
|
||||
<<"amount">> => ?INTEGER,
|
||||
@ -601,7 +555,7 @@ create_invoice_with_template_ok_test(Config) ->
|
||||
-spec create_invoice_with_template_fail_test(config()) -> _.
|
||||
create_invoice_with_template_fail_test(Config) ->
|
||||
BenderKey = <<"create_invoice_with_template_fail_test">>,
|
||||
InvoiceTemplateID = ?config(invoice_template_id, Config),
|
||||
InvoiceTemplateID = ?STRING,
|
||||
ExternalID = genlib:unique(),
|
||||
Req1 = #{
|
||||
<<"externalID">> => ExternalID,
|
||||
@ -751,9 +705,12 @@ create_payment(BenderKey, Requests, Config) ->
|
||||
Tid = capi_ct_helper_bender:create_storage(),
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun('StartPayment', {_, _, IPP}) ->
|
||||
#payproc_InvoicePaymentParams{id = ID, external_id = EID, context = ?CONTENT} = IPP,
|
||||
{ok, ?PAYPROC_PAYMENT(ID, EID)}
|
||||
{invoicing, fun
|
||||
('Get', _) ->
|
||||
{ok, ?PAYPROC_INVOICE};
|
||||
('StartPayment', {_, _, IPP}) ->
|
||||
#payproc_InvoicePaymentParams{id = ID, external_id = EID, context = ?CONTENT} = IPP,
|
||||
{ok, ?PAYPROC_PAYMENT(ID, EID)}
|
||||
end},
|
||||
{bender, fun('GenerateID', {_, _, CtxMsgPack}) ->
|
||||
capi_ct_helper_bender:get_internal_id(Tid, BenderKey, CtxMsgPack)
|
||||
@ -798,11 +755,14 @@ create_refunds(BenderKey, Requests, Config) ->
|
||||
Tid = capi_ct_helper_bender:create_storage(),
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun(
|
||||
'RefundPayment',
|
||||
{_, _, _, #payproc_InvoicePaymentRefundParams{id = ID, external_id = EID}}
|
||||
) ->
|
||||
{ok, ?REFUND(ID, EID)}
|
||||
{invoicing, fun
|
||||
('Get', _) ->
|
||||
{ok, ?PAYPROC_INVOICE([?PAYPROC_PAYMENT])};
|
||||
(
|
||||
'RefundPayment',
|
||||
{_, _, _, #payproc_InvoicePaymentRefundParams{id = ID, external_id = EID}}
|
||||
) ->
|
||||
{ok, ?REFUND(ID, EID)}
|
||||
end},
|
||||
{bender, fun('GenerateID', {_, _, CtxMsgPack}) ->
|
||||
capi_ct_helper_bender:get_internal_id(Tid, BenderKey, CtxMsgPack)
|
||||
|
@ -2,12 +2,9 @@
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
-include_lib("damsel/include/dmsl_domain_config_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_payment_processing_errors_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_payment_tool_token_thrift.hrl").
|
||||
-include_lib("capi_dummy_data.hrl").
|
||||
-include_lib("jose/include/jose_jwk.hrl").
|
||||
|
||||
-export([all/0]).
|
||||
-export([groups/0]).
|
||||
@ -41,12 +38,6 @@
|
||||
get_recurrent_payments_ok_test/1
|
||||
]).
|
||||
|
||||
-define(CAPI_PORT, 8080).
|
||||
-define(CAPI_HOST_NAME, "localhost").
|
||||
-define(CAPI_URL, ?CAPI_HOST_NAME ++ ":" ++ integer_to_list(?CAPI_PORT)).
|
||||
|
||||
-define(badresp(Code), {error, {invalid_response_code, Code}}).
|
||||
|
||||
-type test_case_name() :: atom().
|
||||
-type config() :: [{atom(), any()}].
|
||||
-type group_name() :: atom().
|
||||
@ -61,46 +52,38 @@ init([]) ->
|
||||
all() ->
|
||||
[
|
||||
{group, operations_by_invoice_access_token_after_invoice_creation},
|
||||
{group, operations_by_invoice_access_token_after_token_creation},
|
||||
{group, operations_by_invoice_access_token_after_invoice_creation_with_new_auth},
|
||||
{group, operations_by_invoice_access_token_after_token_creation_with_new_auth}
|
||||
{group, operations_by_invoice_access_token_after_token_creation}
|
||||
].
|
||||
|
||||
invoice_access_token_tests() ->
|
||||
[
|
||||
create_payment_ok_test,
|
||||
create_payment_expired_test,
|
||||
create_payment_qiwi_access_token_ok_test,
|
||||
create_payment_with_empty_cvv_ok_test,
|
||||
create_payment_with_googlepay_encrypt_ok_test,
|
||||
get_payments_ok_test,
|
||||
get_client_payment_status_test,
|
||||
get_payment_by_id_ok_test,
|
||||
get_payment_by_id_trx_ok_test,
|
||||
cancel_payment_ok_test,
|
||||
capture_payment_ok_test,
|
||||
capture_partial_payment_ok_test,
|
||||
create_first_recurrent_payment_ok_test,
|
||||
create_second_recurrent_payment_ok_test,
|
||||
get_recurrent_payments_ok_test
|
||||
].
|
||||
get_recurrent_payments_ok_test,
|
||||
|
||||
invoice_access_token_tests_with_new_auth() ->
|
||||
[
|
||||
get_invoice_ok_test,
|
||||
get_invoice_events_ok_test,
|
||||
get_invoice_payment_methods_ok_test
|
||||
get_invoice_payment_methods_ok_test,
|
||||
|
||||
create_payment_ok_test,
|
||||
create_payment_expired_test,
|
||||
create_payment_with_empty_cvv_ok_test,
|
||||
create_payment_with_googlepay_encrypt_ok_test,
|
||||
get_payments_ok_test,
|
||||
create_payment_qiwi_access_token_ok_test,
|
||||
create_first_recurrent_payment_ok_test,
|
||||
create_second_recurrent_payment_ok_test
|
||||
].
|
||||
|
||||
-spec groups() -> [{group_name(), list(), [test_case_name()]}].
|
||||
groups() ->
|
||||
[
|
||||
{operations_by_invoice_access_token_after_invoice_creation, [], invoice_access_token_tests()},
|
||||
{operations_by_invoice_access_token_after_token_creation, [], invoice_access_token_tests()},
|
||||
{operations_by_invoice_access_token_after_invoice_creation_with_new_auth, [],
|
||||
invoice_access_token_tests_with_new_auth()},
|
||||
{operations_by_invoice_access_token_after_token_creation_with_new_auth, [],
|
||||
invoice_access_token_tests_with_new_auth()}
|
||||
{operations_by_invoice_access_token_after_token_creation, [], invoice_access_token_tests()}
|
||||
].
|
||||
|
||||
%%
|
||||
@ -128,60 +111,7 @@ init_per_group(operations_by_invoice_access_token_after_invoice_creation, Config
|
||||
],
|
||||
MockServiceSup
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_shop_op_ctx(<<"CreateInvoice">>, ?STRING, ?STRING, MockServiceSup),
|
||||
Req = #{
|
||||
<<"shopID">> => ?STRING,
|
||||
<<"amount">> => ?INTEGER,
|
||||
<<"currency">> => ?RUB,
|
||||
<<"metadata">> => #{<<"invoice_dummy_metadata">> => <<"test_value">>},
|
||||
<<"dueDate">> => ?TIMESTAMP,
|
||||
<<"product">> => <<"test_product">>,
|
||||
<<"description">> => <<"test_invoice_description">>
|
||||
},
|
||||
{ok, #{
|
||||
<<"invoiceAccessToken">> := #{<<"payload">> := InvAccToken}
|
||||
}} = capi_client_invoices:create_invoice(capi_ct_helper:get_context(Token, ExtraProperties), Req),
|
||||
capi_ct_helper:stop_mocked_service_sup(MockServiceSup),
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
[{context, capi_ct_helper:get_context(InvAccToken)}, {group_apps, Apps1}, {group_test_sup, SupPid} | Config];
|
||||
init_per_group(operations_by_invoice_access_token_after_token_creation, Config) ->
|
||||
MockServiceSup = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
{ok, Token} = capi_ct_helper:issue_token([{[invoices], write}], unlimited),
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun('Get', _) -> {ok, ?PAYPROC_INVOICE} end},
|
||||
{bender, fun('GenerateID', _) -> {ok, capi_ct_helper_bender:get_result(<<"bender_key">>)} end}
|
||||
],
|
||||
MockServiceSup
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_invoice_op_ctx(
|
||||
<<"CreateInvoiceAccessToken">>,
|
||||
?STRING,
|
||||
?STRING,
|
||||
?STRING,
|
||||
MockServiceSup
|
||||
),
|
||||
{ok, #{<<"payload">> := InvAccToken}} = capi_client_invoices:create_invoice_access_token(
|
||||
capi_ct_helper:get_context(Token),
|
||||
?STRING
|
||||
),
|
||||
capi_ct_helper:stop_mocked_service_sup(MockServiceSup),
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
[{context, capi_ct_helper:get_context(InvAccToken)}, {group_apps, Apps1}, {group_test_sup, SupPid} | Config];
|
||||
init_per_group(operations_by_invoice_access_token_after_invoice_creation_with_new_auth, Config) ->
|
||||
MockServiceSup = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
ExtraProperties = #{<<"ip_replacement_allowed">> => true},
|
||||
{ok, Token} = capi_ct_helper:issue_token([{[invoices], write}], unlimited, ExtraProperties),
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun('Create', _) -> {ok, ?PAYPROC_INVOICE} end},
|
||||
{generator, fun('GenerateID', _) -> capi_ct_helper_bender:generate_id(<<"bender_key">>) end}
|
||||
],
|
||||
MockServiceSup
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_shop_op_ctx(<<"CreateInvoice">>, ?STRING, ?STRING, MockServiceSup),
|
||||
_ = capi_ct_helper_bouncer:mock_assert_shop_op_ctx(<<"CreateInvoice">>, ?STRING, ?STRING, MockServiceSup),
|
||||
Req = #{
|
||||
<<"shopID">> => ?STRING,
|
||||
<<"amount">> => ?INTEGER,
|
||||
@ -196,7 +126,7 @@ init_per_group(operations_by_invoice_access_token_after_invoice_creation_with_ne
|
||||
}} = capi_client_invoices:create_invoice(capi_ct_helper:get_context(Token, ExtraProperties), Req),
|
||||
capi_ct_helper:stop_mocked_service_sup(MockServiceSup),
|
||||
[{context, capi_ct_helper:get_context(InvAccToken)} | Config];
|
||||
init_per_group(operations_by_invoice_access_token_after_token_creation_with_new_auth, Config) ->
|
||||
init_per_group(operations_by_invoice_access_token_after_token_creation, Config) ->
|
||||
MockServiceSup = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
{ok, Token} = capi_ct_helper:issue_token([{[invoices], write}], unlimited),
|
||||
_ = capi_ct_helper:mock_services(
|
||||
@ -206,7 +136,7 @@ init_per_group(operations_by_invoice_access_token_after_token_creation_with_new_
|
||||
],
|
||||
MockServiceSup
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_invoice_op_ctx(
|
||||
_ = capi_ct_helper_bouncer:mock_assert_invoice_op_ctx(
|
||||
<<"CreateInvoiceAccessToken">>,
|
||||
?STRING,
|
||||
?STRING,
|
||||
@ -241,7 +171,7 @@ end_per_testcase(_Name, C) ->
|
||||
-spec get_invoice_ok_test(config()) -> _.
|
||||
get_invoice_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services([{invoicing, fun('Get', _) -> {ok, ?PAYPROC_INVOICE} end}], Config),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_invoice_op_ctx(
|
||||
_ = capi_ct_helper_bouncer:mock_assert_invoice_op_ctx(
|
||||
<<"GetInvoiceByID">>,
|
||||
?STRING,
|
||||
?STRING,
|
||||
@ -280,7 +210,7 @@ get_invoice_events_ok_test(Config) ->
|
||||
],
|
||||
Config
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_invoice_op_ctx(
|
||||
_ = capi_ct_helper_bouncer:mock_assert_invoice_op_ctx(
|
||||
<<"GetInvoiceEvents">>,
|
||||
?STRING,
|
||||
?STRING,
|
||||
@ -304,7 +234,7 @@ get_invoice_payment_methods_ok_test(Config) ->
|
||||
],
|
||||
Config
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_invoice_op_ctx(
|
||||
_ = capi_ct_helper_bouncer:mock_assert_invoice_op_ctx(
|
||||
<<"GetInvoicePaymentMethods">>,
|
||||
?STRING,
|
||||
?STRING,
|
||||
@ -319,9 +249,12 @@ create_payment_ok_test(Config) ->
|
||||
ExternalID = <<"merch_id">>,
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun('StartPayment', {_, _, IPP}) ->
|
||||
#payproc_InvoicePaymentParams{id = ID, external_id = EID, context = ?CONTENT} = IPP,
|
||||
{ok, ?PAYPROC_PAYMENT(ID, EID)}
|
||||
{invoicing, fun
|
||||
('Get', _) ->
|
||||
{ok, ?PAYPROC_INVOICE};
|
||||
('StartPayment', {_, _, IPP}) ->
|
||||
#payproc_InvoicePaymentParams{id = ID, external_id = EID, context = ?CONTENT} = IPP,
|
||||
{ok, ?PAYPROC_PAYMENT(ID, EID)}
|
||||
end},
|
||||
{bender, fun('GenerateID', _) ->
|
||||
{ok, capi_ct_helper_bender:get_result(BenderKey)}
|
||||
@ -329,29 +262,35 @@ create_payment_ok_test(Config) ->
|
||||
],
|
||||
Config
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_assert_payment_op_ctx(
|
||||
<<"CreatePayment">>,
|
||||
?STRING,
|
||||
?STRING,
|
||||
?STRING,
|
||||
Config
|
||||
),
|
||||
PaymentToolToken = get_encrypted_token(visa, ?EXP_DATE(2, 2020)),
|
||||
Req2 = #{
|
||||
<<"externalID">> => ExternalID,
|
||||
<<"flow">> => #{<<"type">> => <<"PaymentFlowInstant">>},
|
||||
<<"payer">> => #{
|
||||
<<"payerType">> => <<"PaymentResourcePayer">>,
|
||||
<<"paymentSession">> => ?TEST_PAYMENT_SESSION,
|
||||
<<"paymentToolToken">> => PaymentToolToken,
|
||||
<<"contactInfo">> => #{
|
||||
<<"email">> => <<"bla@bla.ru">>
|
||||
}
|
||||
},
|
||||
<<"metadata">> => ?JSON,
|
||||
<<"processingDeadline">> => <<"5m">>
|
||||
},
|
||||
Req = ?PAYMENT_PARAMS(ExternalID, PaymentToolToken),
|
||||
{ok, #{
|
||||
<<"id">> := BenderKey,
|
||||
<<"externalID">> := ExternalID
|
||||
}} = capi_client_payments:create_payment(?config(context, Config), Req2, ?STRING).
|
||||
}} = capi_client_payments:create_payment(?config(context, Config), Req, ?STRING).
|
||||
|
||||
-spec create_payment_expired_test(config()) -> _.
|
||||
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)}
|
||||
end}
|
||||
],
|
||||
Config
|
||||
),
|
||||
ValidUntil = capi_utils:deadline_from_timeout(0),
|
||||
PaymentToolToken = capi_crypto:create_encrypted_payment_tool_token(PaymentTool, ValidUntil),
|
||||
Req = #{
|
||||
@ -375,25 +314,28 @@ create_payment_expired_test(Config) ->
|
||||
create_payment_with_empty_cvv_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun(
|
||||
'StartPayment',
|
||||
{
|
||||
_UserInfo,
|
||||
_InvoiceID,
|
||||
#payproc_InvoicePaymentParams{
|
||||
payer =
|
||||
{payment_resource, #payproc_PaymentResourcePayerParams{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = {
|
||||
bank_card,
|
||||
#domain_BankCard{is_cvv_empty = true}
|
||||
{invoicing, fun
|
||||
('Get', _) ->
|
||||
{ok, ?PAYPROC_INVOICE};
|
||||
(
|
||||
'StartPayment',
|
||||
{
|
||||
_UserInfo,
|
||||
_InvoiceID,
|
||||
#payproc_InvoicePaymentParams{
|
||||
payer =
|
||||
{payment_resource, #payproc_PaymentResourcePayerParams{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = {
|
||||
bank_card,
|
||||
#domain_BankCard{is_cvv_empty = true}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
) ->
|
||||
{ok, ?PAYPROC_PAYMENT}
|
||||
) ->
|
||||
{ok, ?PAYPROC_PAYMENT}
|
||||
end},
|
||||
{generator, fun('GenerateID', _) -> capi_ct_helper_bender:generate_id(<<"bender_key">>) end}
|
||||
],
|
||||
@ -417,25 +359,28 @@ create_payment_with_empty_cvv_ok_test(Config) ->
|
||||
create_payment_qiwi_access_token_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun(
|
||||
'StartPayment',
|
||||
{
|
||||
_UserInfo,
|
||||
_InvoiceID,
|
||||
#payproc_InvoicePaymentParams{
|
||||
payer =
|
||||
{payment_resource, #payproc_PaymentResourcePayerParams{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = {
|
||||
digital_wallet,
|
||||
#domain_DigitalWallet{token = <<"benderkey0">>}
|
||||
{invoicing, fun
|
||||
('Get', _) ->
|
||||
{ok, ?PAYPROC_INVOICE};
|
||||
(
|
||||
'StartPayment',
|
||||
{
|
||||
_UserInfo,
|
||||
_InvoiceID,
|
||||
#payproc_InvoicePaymentParams{
|
||||
payer =
|
||||
{payment_resource, #payproc_PaymentResourcePayerParams{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = {
|
||||
digital_wallet,
|
||||
#domain_DigitalWallet{token = <<"benderkey0">>}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
) ->
|
||||
{ok, ?PAYPROC_PAYMENT}
|
||||
) ->
|
||||
{ok, ?PAYPROC_PAYMENT}
|
||||
end},
|
||||
{generator, fun('GenerateID', _) -> capi_ct_helper_bender:generate_id(<<"bender_key">>) end}
|
||||
],
|
||||
@ -457,29 +402,32 @@ create_payment_qiwi_access_token_ok_test(Config) ->
|
||||
create_payment_with_googlepay_encrypt_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun(
|
||||
'StartPayment',
|
||||
{
|
||||
_UserInfo,
|
||||
_InvoiceID,
|
||||
#payproc_InvoicePaymentParams{
|
||||
payer =
|
||||
{payment_resource, #payproc_PaymentResourcePayerParams{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = {
|
||||
bank_card,
|
||||
#domain_BankCard{
|
||||
is_cvv_empty = undefined,
|
||||
token_provider_deprecated = undefined,
|
||||
payment_system_deprecated = mastercard
|
||||
{invoicing, fun
|
||||
('Get', _) ->
|
||||
{ok, ?PAYPROC_INVOICE};
|
||||
(
|
||||
'StartPayment',
|
||||
{
|
||||
_UserInfo,
|
||||
_InvoiceID,
|
||||
#payproc_InvoicePaymentParams{
|
||||
payer =
|
||||
{payment_resource, #payproc_PaymentResourcePayerParams{
|
||||
resource = #domain_DisposablePaymentResource{
|
||||
payment_tool = {
|
||||
bank_card,
|
||||
#domain_BankCard{
|
||||
is_cvv_empty = undefined,
|
||||
token_provider_deprecated = undefined,
|
||||
payment_system_deprecated = mastercard
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
) ->
|
||||
{ok, ?PAYPROC_PAYMENT}
|
||||
) ->
|
||||
{ok, ?PAYPROC_PAYMENT}
|
||||
end},
|
||||
{generator, fun('GenerateID', _) -> capi_ct_helper_bender:generate_id(<<"bender_key">>) end}
|
||||
],
|
||||
@ -511,12 +459,23 @@ get_payments_ok_test(Config) ->
|
||||
-spec get_payment_by_id_ok_test(config()) -> _.
|
||||
get_payment_by_id_ok_test(Config) ->
|
||||
Result = ?PAYPROC_PAYMENT(?PAYMENT_WITH_RECURRENT_PAYER, [?REFUND], [?ADJUSTMENT], [?PAYPROC_CHARGEBACK]),
|
||||
_ = capi_ct_helper:mock_services([{invoicing, fun('GetPayment', _) -> {ok, Result} end}], Config),
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun
|
||||
('Get', _) -> {ok, ?PAYPROC_INVOICE([Result])};
|
||||
('GetPayment', _) -> {ok, Result}
|
||||
end}
|
||||
],
|
||||
Config
|
||||
),
|
||||
{ok, _} = capi_client_payments:get_payment_by_id(?config(context, Config), ?STRING, ?STRING).
|
||||
|
||||
-spec get_payment_by_id_trx_ok_test(config()) -> _.
|
||||
get_payment_by_id_trx_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services([{invoicing, fun('GetPayment', _) -> {ok, ?PAYPROC_PAYMENT} end}], Config),
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[{invoicing, fun('Get', _) -> {ok, ?PAYPROC_INVOICE([?PAYPROC_PAYMENT])} end}],
|
||||
Config
|
||||
),
|
||||
{ok, #{
|
||||
<<"transactionInfo">> := #{
|
||||
<<"rrn">> := <<"090909090909">>,
|
||||
@ -533,12 +492,28 @@ get_client_payment_status_test(Config) ->
|
||||
|
||||
-spec cancel_payment_ok_test(config()) -> _.
|
||||
cancel_payment_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services([{invoicing, fun('CancelPayment', _) -> {ok, ok} end}], Config),
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun
|
||||
('Get', _) -> {ok, ?PAYPROC_INVOICE};
|
||||
('CancelPayment', _) -> {ok, ok}
|
||||
end}
|
||||
],
|
||||
Config
|
||||
),
|
||||
ok = capi_client_payments:cancel_payment(?config(context, Config), ?STRING, ?STRING, ?STRING).
|
||||
|
||||
-spec capture_payment_ok_test(config()) -> _.
|
||||
capture_payment_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services([{invoicing, fun('CapturePayment', _) -> {ok, ok} end}], Config),
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun
|
||||
('Get', _) -> {ok, ?PAYPROC_INVOICE};
|
||||
('CapturePayment', _) -> {ok, ok}
|
||||
end}
|
||||
],
|
||||
Config
|
||||
),
|
||||
Req = #{
|
||||
<<"reason">> => ?STRING
|
||||
},
|
||||
@ -548,19 +523,22 @@ capture_payment_ok_test(Config) ->
|
||||
capture_partial_payment_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun(
|
||||
'CapturePayment',
|
||||
{
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
#payproc_InvoicePaymentCaptureParams{
|
||||
cash = ?CASH,
|
||||
cart = ?THRIFT_INVOICE_CART
|
||||
{invoicing, fun
|
||||
('Get', _) ->
|
||||
{ok, ?PAYPROC_INVOICE};
|
||||
(
|
||||
'CapturePayment',
|
||||
{
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
#payproc_InvoicePaymentCaptureParams{
|
||||
cash = ?CASH,
|
||||
cart = ?THRIFT_INVOICE_CART
|
||||
}
|
||||
}
|
||||
}
|
||||
) ->
|
||||
{ok, ok}
|
||||
) ->
|
||||
{ok, ok}
|
||||
end}
|
||||
],
|
||||
Config
|
||||
@ -577,7 +555,12 @@ capture_partial_payment_ok_test(Config) ->
|
||||
create_first_recurrent_payment_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun('StartPayment', _) -> {ok, ?PAYPROC_PAYMENT} end},
|
||||
{invoicing, fun
|
||||
('Get', _) ->
|
||||
{ok, ?PAYPROC_INVOICE};
|
||||
('StartPayment', _) ->
|
||||
{ok, ?PAYPROC_PAYMENT}
|
||||
end},
|
||||
{generator, fun('GenerateID', _) ->
|
||||
capi_ct_helper_bender:generate_id(<<"bender_key">>)
|
||||
end}
|
||||
@ -603,7 +586,12 @@ create_first_recurrent_payment_ok_test(Config) ->
|
||||
create_second_recurrent_payment_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun('StartPayment', _) -> {ok, ?PAYPROC_PAYMENT} end},
|
||||
{invoicing, fun
|
||||
('Get', _) ->
|
||||
{ok, ?PAYPROC_INVOICE};
|
||||
('StartPayment', _) ->
|
||||
{ok, ?PAYPROC_PAYMENT}
|
||||
end},
|
||||
{generator, fun('GenerateID', _) -> capi_ct_helper_bender:generate_id(<<"bender_key">>) end}
|
||||
],
|
||||
Config
|
||||
@ -641,7 +629,12 @@ get_failed_payment_with_invalid_cvv(Config) ->
|
||||
),
|
||||
_ = capi_ct_helper:mock_services(
|
||||
[
|
||||
{invoicing, fun('GetPayment', _) -> {ok, ?PAYPROC_FAILED_PAYMENT({failure, Failure})} end}
|
||||
{invoicing, fun
|
||||
('Get', _) ->
|
||||
{ok, ?PAYPROC_INVOICE([?PAYPROC_FAILED_PAYMENT({failure, Failure})])};
|
||||
('GetPayment', _) ->
|
||||
{ok, ?PAYPROC_FAILED_PAYMENT({failure, Failure})}
|
||||
end}
|
||||
],
|
||||
Config
|
||||
),
|
||||
|
@ -80,7 +80,7 @@ init_per_group(operations_by_invoice_template_access_token, Config) ->
|
||||
],
|
||||
MockServiceSup
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_shop_op_ctx(
|
||||
_ = capi_ct_helper_bouncer:mock_assert_shop_op_ctx(
|
||||
<<"CreateInvoiceTemplate">>,
|
||||
?STRING,
|
||||
?STRING,
|
||||
@ -136,10 +136,11 @@ create_invoice_with_tpl_ok_test(Config) ->
|
||||
],
|
||||
Config
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_shop_op_ctx(
|
||||
_ = capi_ct_helper_bouncer:mock_assert_invoice_tpl_op_ctx(
|
||||
<<"CreateInvoiceWithTemplate">>,
|
||||
?STRING,
|
||||
?STRING,
|
||||
?STRING,
|
||||
Config
|
||||
),
|
||||
Req = #{
|
||||
@ -152,7 +153,13 @@ create_invoice_with_tpl_ok_test(Config) ->
|
||||
-spec get_invoice_template_ok_test(config()) -> _.
|
||||
get_invoice_template_ok_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services([{invoice_templating, fun('Get', _) -> {ok, ?INVOICE_TPL} end}], Config),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_shop_op_ctx(<<"GetInvoiceTemplateByID">>, ?STRING, ?STRING, Config),
|
||||
_ = capi_ct_helper_bouncer:mock_assert_invoice_tpl_op_ctx(
|
||||
<<"GetInvoiceTemplateByID">>,
|
||||
?STRING,
|
||||
?STRING,
|
||||
?STRING,
|
||||
Config
|
||||
),
|
||||
{ok, _} = capi_client_invoice_templates:get_template_by_id(?config(context, Config), ?STRING).
|
||||
|
||||
-spec get_invoice_payment_methods_by_tpl_id_ok_test(config()) -> _.
|
||||
@ -167,10 +174,11 @@ get_invoice_payment_methods_by_tpl_id_ok_test(Config) ->
|
||||
],
|
||||
Config
|
||||
),
|
||||
_ = capi_ct_helper_bouncer:mock_bouncer_assert_shop_op_ctx(
|
||||
_ = capi_ct_helper_bouncer:mock_assert_invoice_tpl_op_ctx(
|
||||
<<"GetInvoicePaymentMethodsByTemplateID">>,
|
||||
?STRING,
|
||||
?STRING,
|
||||
?STRING,
|
||||
Config
|
||||
),
|
||||
{ok, _} = capi_client_invoice_templates:get_invoice_payment_methods(?config(context, Config), ?STRING).
|
||||
|
@ -1,13 +1,10 @@
|
||||
-module(capi_self_tests_SUITE).
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
|
||||
-include_lib("damsel/include/dmsl_domain_config_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_merch_stat_thrift.hrl").
|
||||
-include_lib("capi_dummy_data.hrl").
|
||||
-include_lib("jose/include/jose_jwk.hrl").
|
||||
|
||||
-export([all/0]).
|
||||
-export([groups/0]).
|
||||
@ -90,7 +87,7 @@ init_per_group(GroupName, Config) when stream_handler_tests =:= GroupName; valid
|
||||
{ok, Token} = capi_ct_helper:issue_token(BasePermissions, unlimited),
|
||||
Context = capi_ct_helper:get_context(Token),
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
[{context, Context}, {group_apps, Apps1}, {group_test_sup, SupPid} | Config];
|
||||
init_per_group(_, Config) ->
|
||||
Config.
|
||||
|
@ -2,10 +2,6 @@
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
-include_lib("damsel/include/dmsl_domain_config_thrift.hrl").
|
||||
-include_lib("capi_dummy_data.hrl").
|
||||
-include_lib("jose/include/jose_jwk.hrl").
|
||||
|
||||
-export([all/0]).
|
||||
-export([groups/0]).
|
||||
-export([init_per_suite/1]).
|
||||
@ -82,7 +78,7 @@ init_per_group(woody_errors, Config) ->
|
||||
{ok, Token} = capi_ct_helper:issue_token(BasePermissions, unlimited),
|
||||
Context = capi_ct_helper:get_context(Token),
|
||||
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_bouncer_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
Apps1 = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
|
||||
[{context, Context}, {group_apps, Apps1}, {group_test_sup, SupPid} | Config];
|
||||
init_per_group(_, Config) ->
|
||||
Config.
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 24aa772730be966667adb285a09fcb494d4f218e
|
||||
Subproject commit 56606f5cacec1c30ca11088c575e9c285f1f2f40
|
Loading…
Reference in New Issue
Block a user