mirror of
https://github.com/valitydev/capi-v2.git
synced 2024-11-06 10:05:21 +00:00
CAPI-95/HOOK-1 Payments extended search, Webhooks (#42)
* HOOK-1: Implement webhook management * CAPI-95 Add new payments/invoices search with custom api_clientP * CAPI-95 Move to the newest dependencies
This commit is contained in:
parent
69bf9f54b7
commit
4c85e3b84e
@ -126,8 +126,10 @@ get_operation_access('GetPayments' , #{'invoiceID' := ID}) ->
|
||||
[{[{invoices, ID}, payments], read}];
|
||||
get_operation_access('GetPaymentByID' , #{'invoiceID' := ID1, paymentID := ID2}) ->
|
||||
[{[{invoices, ID1}, {payments, ID2}], read}];
|
||||
get_operation_access('GetInvoices' , _) ->
|
||||
get_operation_access('SearchInvoices' , _) ->
|
||||
[{[invoices], read}];
|
||||
get_operation_access('SearchPayments' , _) ->
|
||||
[{[invoices, payments], read}];
|
||||
get_operation_access('CreatePaymentToolToken' , _) ->
|
||||
[{[payment_tool_tokens] , write}];
|
||||
get_operation_access('GetPaymentConversionStats' , _) ->
|
||||
@ -176,6 +178,14 @@ get_operation_access('CreateContract' , _) ->
|
||||
[{[party], write}];
|
||||
get_operation_access('GetContractByID' , _) ->
|
||||
[{[party], read}];
|
||||
get_operation_access('GetWebhooks' , _) ->
|
||||
[{[party], read}];
|
||||
get_operation_access('GetWebhookByID' , _) ->
|
||||
[{[party], read}];
|
||||
get_operation_access('CreateWebhook' , _) ->
|
||||
[{[party], write}];
|
||||
get_operation_access('DeleteWebhookByID' , _) ->
|
||||
[{[party], write}];
|
||||
get_operation_access('GetCategories' , _) ->
|
||||
[];
|
||||
get_operation_access('GetCategoryByRef' , _) ->
|
||||
|
@ -5,6 +5,7 @@
|
||||
-include_lib("cp_proto/include/cp_cds_thrift.hrl").
|
||||
-include_lib("cp_proto/include/cp_merch_stat_thrift.hrl").
|
||||
-include_lib("cp_proto/include/cp_proxy_merch_config_thrift.hrl").
|
||||
-include_lib("cp_proto/include/cp_webhooker_thrift.hrl").
|
||||
-include_lib("cp_proto/include/cp_user_interaction_thrift.hrl").
|
||||
-include_lib("cp_proto/include/cp_geo_ip_thrift.hrl").
|
||||
|
||||
@ -276,20 +277,24 @@ process_request(OperationID = 'GetPaymentByID', Req, Context, ReqCtx) ->
|
||||
process_exception(OperationID, Exception)
|
||||
end;
|
||||
|
||||
process_request(OperationID = 'GetInvoices', Req, Context, ReqCtx) ->
|
||||
process_request(OperationID = 'SearchInvoices', Req, Context, ReqCtx) ->
|
||||
Limit = genlib_map:get('limit', Req),
|
||||
Offset = genlib_map:get('offset', Req),
|
||||
InvoiceStatus = case genlib_map:get('status', Req) of
|
||||
undefined -> undefined;
|
||||
[Status | _] -> Status
|
||||
end, %%@TODO deal with many statuses
|
||||
Query = #{
|
||||
<<"merchant_id">> => get_party_id(Context),
|
||||
<<"shop_id">> => genlib_map:get('shopID', Req),
|
||||
<<"invoice_id">> => genlib_map:get('invoiceID', Req),
|
||||
<<"from_time">> => get_time('fromTime', Req),
|
||||
<<"to_time">> => get_time('toTime', Req),
|
||||
<<"invoice_status">> => InvoiceStatus
|
||||
<<"invoice_status">> => genlib_map:get('invoiceStatus', Req),
|
||||
<<"payment_status">> => genlib_map:get('paymentStatus', Req),
|
||||
<<"payment_id">> => genlib_map:get('paymentID', Req),
|
||||
<<"payment_email">> => genlib_map:get('payerEmail', Req),
|
||||
<<"payment_ip">> => genlib_map:get('payerIP', Req),
|
||||
<<"payment_fingerprint">> => genlib_map:get('payerFingerprint', Req),
|
||||
<<"payment_pan_mask">> => genlib_map:get('cardNumberMask', Req),
|
||||
<<"payment_amount">> => genlib_map:get('paymentAmount', Req),
|
||||
<<"invoice_amount">> => genlib_map:get('invoiceAmount', Req)
|
||||
},
|
||||
QueryParams = #{
|
||||
<<"size">> => Limit,
|
||||
@ -304,7 +309,7 @@ process_request(OperationID = 'GetInvoices', Req, Context, ReqCtx) ->
|
||||
),
|
||||
case Result of
|
||||
{ok, #merchstat_StatResponse{data = {'invoices', Invoices}, total_count = TotalCount}} ->
|
||||
DecodedInvoices = [decode_invoice(I) || #merchstat_StatInvoice{invoice = I} <- Invoices],
|
||||
DecodedInvoices = [decode_invoice_search_result(I) || #merchstat_StatInvoice{invoice = I} <- Invoices],
|
||||
Resp = #{
|
||||
<<"invoices">> => DecodedInvoices,
|
||||
<<"totalCount">> => TotalCount
|
||||
@ -314,6 +319,52 @@ process_request(OperationID = 'GetInvoices', Req, Context, ReqCtx) ->
|
||||
process_exception(OperationID, Exception)
|
||||
end;
|
||||
|
||||
process_request(OperationID = 'SearchPayments', Req, Context, ReqCtx) ->
|
||||
Limit = genlib_map:get('limit', Req),
|
||||
Offset = genlib_map:get('offset', Req),
|
||||
Query = #{
|
||||
<<"merchant_id">> => get_party_id(Context),
|
||||
<<"shop_id">> => genlib_map:get('shopID', Req),
|
||||
<<"invoice_id">> => genlib_map:get('invoiceID', Req),
|
||||
<<"from_time">> => get_time('fromTime', Req),
|
||||
<<"to_time">> => get_time('toTime', Req),
|
||||
<<"payment_status">> => genlib_map:get('paymentStatus', Req),
|
||||
<<"payment_id">> => genlib_map:get('paymentID', Req),
|
||||
<<"payment_email">> => genlib_map:get('payerEmail', Req),
|
||||
<<"payment_ip">> => genlib_map:get('payerIP', Req),
|
||||
<<"payment_fingerprint">> => genlib_map:get('payerFingerprint', Req),
|
||||
<<"payment_pan_mask">> => genlib_map:get('cardNumberMask', Req),
|
||||
<<"payment_amount">> => genlib_map:get('paymentAmount', Req)
|
||||
},
|
||||
QueryParams = #{
|
||||
<<"size">> => Limit,
|
||||
<<"from">> => Offset
|
||||
},
|
||||
Dsl = create_dsl(payments, Query, QueryParams),
|
||||
Result = service_call(
|
||||
merchant_stat,
|
||||
'GetPayments',
|
||||
[encode_stat_request(Dsl)],
|
||||
ReqCtx
|
||||
),
|
||||
case Result of
|
||||
{ok, #merchstat_StatResponse{data = {'payments', Payments}, total_count = TotalCount}} ->
|
||||
DecodedPayments = [
|
||||
decode_payment_search_result(InvoiceID, I)
|
||||
|| #merchstat_StatPayment{
|
||||
invoice_id = InvoiceID,
|
||||
payment = I
|
||||
} <- Payments
|
||||
],
|
||||
Resp = #{
|
||||
<<"payments">> => DecodedPayments,
|
||||
<<"totalCount">> => TotalCount
|
||||
},
|
||||
{ok, {200, [], Resp}};
|
||||
{exception, Exception} ->
|
||||
process_exception(OperationID, Exception)
|
||||
end;
|
||||
|
||||
process_request(OperationID = 'GetPaymentConversionStats', Req, Context, ReqCtx) ->
|
||||
StatType = payments_conversion_stat,
|
||||
Result = call_merchant_stat(StatType, Req, Context, ReqCtx),
|
||||
@ -854,9 +905,83 @@ process_request(OperationID = 'GetAccountByID', Req, Context, ReqCtx) ->
|
||||
process_exception(OperationID, Exception)
|
||||
end;
|
||||
|
||||
process_request(OperationID = 'CreateWebhook', Req, Context, ReqCtx) ->
|
||||
PartyID = get_party_id(Context),
|
||||
Params = maps:get('WebhookParams', Req),
|
||||
EventFilter = encode_event_filter(maps:get(<<"scope">>, Params)),
|
||||
case validate_event_filter(EventFilter, Context, ReqCtx) of
|
||||
{ok, _} ->
|
||||
WebhookParams = #webhooker_WebhookParams{
|
||||
party_id = PartyID,
|
||||
url = maps:get(<<"url">>, Params),
|
||||
event_filter = EventFilter
|
||||
},
|
||||
case service_call(webhook_manager, 'Create', [WebhookParams], ReqCtx) of
|
||||
{ok, Webhook} ->
|
||||
Resp = decode_webhook(Webhook),
|
||||
{ok, {201, [], Resp}};
|
||||
{exception, Exception} ->
|
||||
process_exception(OperationID, Exception)
|
||||
end;
|
||||
{exception, Exception} ->
|
||||
process_exception(OperationID, Exception)
|
||||
end;
|
||||
|
||||
process_request(_OperationID = 'GetWebhooks', _Req, Context, ReqCtx) ->
|
||||
PartyID = get_party_id(Context),
|
||||
{ok, Webhooks} = service_call(webhook_manager, 'GetList', [PartyID], ReqCtx),
|
||||
{ok, {200, [], [decode_webhook(V) || V <- Webhooks]}};
|
||||
|
||||
process_request(OperationID = 'GetWebhookByID', Req, Context, ReqCtx) ->
|
||||
PartyID = get_party_id(Context),
|
||||
WebhookID = binary_to_integer(maps:get(webhookID, Req)),
|
||||
case get_webhook(PartyID, WebhookID, ReqCtx) of
|
||||
{ok, Webhook} ->
|
||||
{ok, {200, [], decode_webhook(Webhook)}};
|
||||
{exception, Exception} ->
|
||||
process_exception(OperationID, Exception)
|
||||
end;
|
||||
|
||||
process_request(OperationID = 'DeleteWebhookByID', Req, Context, ReqCtx) ->
|
||||
PartyID = get_party_id(Context),
|
||||
WebhookID = binary_to_integer(maps:get(webhookID, Req)),
|
||||
case get_webhook(PartyID, WebhookID, ReqCtx) of
|
||||
{ok, #webhooker_Webhook{}} ->
|
||||
case service_call(webhook_manager, 'Delete', [WebhookID], ReqCtx) of
|
||||
{ok, _} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{exception, #webhooker_WebhookNotFound{}} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{exception, Exception} ->
|
||||
process_exception(OperationID, Exception)
|
||||
end;
|
||||
{exception, #webhooker_WebhookNotFound{}} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{exception, Exception} ->
|
||||
process_exception(OperationID, Exception)
|
||||
end;
|
||||
|
||||
process_request(_OperationID, _Req, _Context, _ReqCtx) ->
|
||||
{501, [], <<"Not implemented">>}.
|
||||
|
||||
validate_event_filter({invoice, #webhooker_InvoiceEventFilter{
|
||||
shop_id = ShopID
|
||||
}}, Context, ReqCtx) when ShopID /= undefined ->
|
||||
PartyID = get_party_id(Context),
|
||||
UserInfo = get_user_info(Context),
|
||||
service_call(party_management, 'GetShop', [UserInfo, PartyID, ShopID], ReqCtx).
|
||||
|
||||
get_webhook(PartyID, WebhookID, ReqCtx) ->
|
||||
Result = service_call(webhook_manager, 'Get', [WebhookID], ReqCtx),
|
||||
case Result of
|
||||
{ok, Webhook = #webhooker_Webhook{party_id = PartyID}} ->
|
||||
{ok, Webhook};
|
||||
{ok, _Webhook} ->
|
||||
{exception, #webhooker_WebhookNotFound{}};
|
||||
{exception, Exception} ->
|
||||
{exception, Exception}
|
||||
end.
|
||||
|
||||
%%%
|
||||
|
||||
service_call(ServiceName, Function, Args, Context) ->
|
||||
@ -1133,6 +1258,10 @@ decode_payment(InvoiceID, #domain_InvoicePayment{
|
||||
payment_tool = PaymentTool,
|
||||
session = PaymentSession,
|
||||
contact_info = ContactInfo
|
||||
},
|
||||
cost = #domain_Cash{
|
||||
amount = Amount,
|
||||
currency = Currency
|
||||
}
|
||||
}) ->
|
||||
genlib_map:compact(maps:merge(#{
|
||||
@ -1141,9 +1270,15 @@ decode_payment(InvoiceID, #domain_InvoicePayment{
|
||||
<<"createdAt">> => CreatedAt,
|
||||
<<"paymentToolToken">> => decode_payment_tool_token(PaymentTool),
|
||||
<<"contactInfo">> => decode_contact_info(ContactInfo),
|
||||
<<"paymentSession">> => PaymentSession
|
||||
<<"paymentSession">> => PaymentSession,
|
||||
<<"amount">> => Amount,
|
||||
<<"currency">> => decode_currency(Currency)
|
||||
}, decode_payment_status(Status))).
|
||||
|
||||
decode_payment_search_result(InvoiceID, PaymentSearchResult) ->
|
||||
decode_payment(InvoiceID, PaymentSearchResult).
|
||||
|
||||
|
||||
decode_payment_tool_token({bank_card, BankCard}) ->
|
||||
encode_bank_card(BankCard).
|
||||
|
||||
@ -1179,7 +1314,7 @@ decode_payment_status({Status, StatusInfo}) ->
|
||||
|
||||
decode_invoice(#domain_Invoice{
|
||||
id = InvoiceID,
|
||||
created_at = CreatedAt, %%@TODO add it to the swagger spec
|
||||
created_at = CreatedAt,
|
||||
status = InvoiceStatus,
|
||||
due = DueDate,
|
||||
details = #domain_InvoiceDetails{
|
||||
@ -1205,6 +1340,9 @@ decode_invoice(#domain_Invoice{
|
||||
<<"description">> => Description
|
||||
}, decode_invoice_status(InvoiceStatus))).
|
||||
|
||||
decode_invoice_search_result(InvoiceSearchResult) ->
|
||||
decode_invoice(InvoiceSearchResult).
|
||||
|
||||
decode_invoice_status({Status, StatusInfo}) ->
|
||||
Reason = case StatusInfo of
|
||||
#domain_InvoiceCancelled{details = Details} -> Details;
|
||||
@ -1723,6 +1861,125 @@ encode_currency(SymbolicCode) ->
|
||||
symbolic_code = SymbolicCode
|
||||
}.
|
||||
|
||||
encode_event_filter(#{
|
||||
<<"topic">> := <<"InvoicesTopic">>,
|
||||
<<"shopID">> := ShopID,
|
||||
<<"eventTypes">> := EventTypes
|
||||
}) ->
|
||||
{invoice, #webhooker_InvoiceEventFilter{
|
||||
shop_id = ShopID,
|
||||
types = ordsets:from_list([
|
||||
encode_event_type(invoices, V) || V <- EventTypes
|
||||
])
|
||||
}}.
|
||||
|
||||
-define(invpaid() , {paid, #webhooker_InvoicePaid{}}).
|
||||
-define(invcancelled() , {cancelled, #webhooker_InvoiceCancelled{}}).
|
||||
-define(invfulfilled() , {fulfilled, #webhooker_InvoiceFulfilled{}}).
|
||||
|
||||
-define(pmtprocessed() , {processed, #webhooker_InvoicePaymentProcessed{}}).
|
||||
-define(pmtcaptured() , {captured, #webhooker_InvoicePaymentCaptured{}}).
|
||||
-define(pmtcancelled() , {cancelled, #webhooker_InvoicePaymentCancelled{}}).
|
||||
-define(pmtfailed() , {failed, #webhooker_InvoicePaymentFailed{}}).
|
||||
|
||||
encode_event_type(invoices, <<"InvoiceCreated">>) ->
|
||||
{created, #webhooker_InvoiceCreated{}};
|
||||
encode_event_type(invoices, <<"InvoicePaid">>) ->
|
||||
{status_changed, #webhooker_InvoiceStatusChanged{value = ?invpaid()}};
|
||||
encode_event_type(invoices, <<"InvoiceCancelled">>) ->
|
||||
{status_changed, #webhooker_InvoiceStatusChanged{value = ?invcancelled()}};
|
||||
encode_event_type(invoices, <<"InvoiceFulfilled">>) ->
|
||||
{status_changed, #webhooker_InvoiceStatusChanged{value = ?invfulfilled()}};
|
||||
encode_event_type(invoices, <<"PaymentCreated">>) ->
|
||||
{payment, {created, #webhooker_InvoicePaymentCreated{}}};
|
||||
encode_event_type(invoices, <<"PaymentProcessed">>) ->
|
||||
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?pmtprocessed()}}};
|
||||
encode_event_type(invoices, <<"PaymentCaptured">>) ->
|
||||
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?pmtcaptured()}}};
|
||||
encode_event_type(invoices, <<"PaymentCancelled">>) ->
|
||||
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?pmtcancelled()}}};
|
||||
encode_event_type(invoices, <<"PaymentFailed">>) ->
|
||||
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?pmtfailed()}}}.
|
||||
|
||||
decode_event_filter({invoice, #webhooker_InvoiceEventFilter{
|
||||
shop_id = ShopID,
|
||||
types = EventTypes
|
||||
}}) ->
|
||||
#{
|
||||
<<"topic">> => <<"InvoicesTopic">>,
|
||||
<<"shopID">> => ShopID,
|
||||
<<"eventTypes">> => lists:flatmap(
|
||||
fun (V) -> decode_event_type(invoice, V) end, ordsets:to_list(EventTypes)
|
||||
)
|
||||
}.
|
||||
|
||||
decode_event_type(
|
||||
invoice,
|
||||
{created, #webhooker_InvoiceCreated{}}
|
||||
) ->
|
||||
[<<"InvoiceCreated">>];
|
||||
decode_event_type(
|
||||
invoice,
|
||||
{status_changed, #webhooker_InvoiceStatusChanged{value = undefined}}
|
||||
) ->
|
||||
% TODO seems unmaintainable
|
||||
[decode_invoice_status_event_type(V) || V <- [
|
||||
?invpaid(),
|
||||
?invcancelled(),
|
||||
?invfulfilled()
|
||||
]];
|
||||
decode_event_type(
|
||||
invoice,
|
||||
{status_changed, #webhooker_InvoiceStatusChanged{value = Value}}
|
||||
) ->
|
||||
[decode_invoice_status_event_type(Value)];
|
||||
decode_event_type(
|
||||
invoice,
|
||||
{payment, {created, #webhooker_InvoicePaymentCreated{}}}
|
||||
) ->
|
||||
[<<"PaymentCreated">>];
|
||||
decode_event_type(
|
||||
invoice,
|
||||
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = undefined}}}
|
||||
) ->
|
||||
% TODO seems unmaintainable
|
||||
[decode_payment_status_event_type(V) || V <- [
|
||||
?pmtprocessed(),
|
||||
?pmtcaptured(),
|
||||
?pmtcancelled(),
|
||||
?pmtfailed()
|
||||
]];
|
||||
decode_event_type(
|
||||
invoice,
|
||||
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = Value}}}
|
||||
) ->
|
||||
[decode_payment_status_event_type(Value)].
|
||||
|
||||
decode_invoice_status_event_type(?invpaid()) -> <<"InvoicePaid">>;
|
||||
decode_invoice_status_event_type(?invcancelled()) -> <<"InvoiceCancelled">>;
|
||||
decode_invoice_status_event_type(?invfulfilled()) -> <<"InvoiceFulfilled">>.
|
||||
|
||||
decode_payment_status_event_type(?pmtprocessed()) -> <<"PaymentProcessed">>;
|
||||
decode_payment_status_event_type(?pmtcaptured()) -> <<"PaymentCaptured">>;
|
||||
decode_payment_status_event_type(?pmtcancelled()) -> <<"PaymentCancelled">>;
|
||||
decode_payment_status_event_type(?pmtfailed()) -> <<"PaymentFailed">>.
|
||||
|
||||
decode_webhook(#webhooker_Webhook{
|
||||
id = ID,
|
||||
party_id = _PartyID,
|
||||
event_filter = EventFilter,
|
||||
url = URL,
|
||||
pub_key = PubKey,
|
||||
enabled = Enabled
|
||||
}) ->
|
||||
#{
|
||||
<<"id">> => integer_to_binary(ID),
|
||||
<<"active">> => Enabled,
|
||||
<<"scope">> => decode_event_filter(EventFilter),
|
||||
<<"url">> => URL,
|
||||
<<"publicKey">> => PubKey
|
||||
}.
|
||||
|
||||
encode_stat_request(Dsl) when is_map(Dsl) ->
|
||||
encode_stat_request(jsx:encode(Dsl));
|
||||
|
||||
@ -1810,12 +2067,12 @@ parse_rfc3339_datetime(DateTime) ->
|
||||
{ok, {DateFrom, TimeFrom, _, _}} = rfc3339:parse(DateTime),
|
||||
{DateFrom, TimeFrom}.
|
||||
|
||||
process_exception(_, #payproc_InvalidUser{}) ->
|
||||
{ok, {400, [], logic_error(invalidUser, <<"Invalid user">>)}};
|
||||
|
||||
process_exception(_, #'InvalidRequest'{errors = Errors}) ->
|
||||
{ok, {400, [], logic_error(invalidRequest, format_request_errors(Errors))}};
|
||||
|
||||
process_exception(_, #payproc_InvalidUser{}) ->
|
||||
{ok, {404, [], general_error(<<"Invoice not found">>)}};
|
||||
|
||||
process_exception(_, #payproc_UserInvoiceNotFound{}) ->
|
||||
{ok, {404, [], general_error(<<"Invoice not found">>)}};
|
||||
|
||||
@ -1825,6 +2082,9 @@ process_exception(_, #payproc_ClaimNotFound{}) ->
|
||||
process_exception(_, #payproc_ContractNotFound{}) ->
|
||||
{ok, {404, [], general_error(<<"Contract not found">>)}};
|
||||
|
||||
process_exception(_, #webhooker_WebhookNotFound{}) ->
|
||||
{ok, {404, [], general_error(<<"Webhook not found">>)}};
|
||||
|
||||
process_exception(_, #payproc_InvalidInvoiceStatus{}) ->
|
||||
{ok, {400, [], logic_error(invalidInvoiceStatus, <<"Invalid invoice status">>)}};
|
||||
|
||||
@ -1852,6 +2112,9 @@ process_exception(_, #'KeyringLocked'{}) ->
|
||||
process_exception(_, #payproc_EventNotFound{}) ->
|
||||
{ok, {404, [], general_error(<<"Event not found">>)}};
|
||||
|
||||
process_exception('CreateWebhook', #payproc_ShopNotFound{}) ->
|
||||
{ok, {400, [], general_error(<<"Shop not found">>)}};
|
||||
|
||||
process_exception(_, #payproc_ShopNotFound{}) ->
|
||||
{ok, {404, [], general_error(<<"Shop not found">>)}};
|
||||
|
||||
|
@ -38,7 +38,8 @@
|
||||
get_payments_ok_test/1,
|
||||
get_payment_by_id_ok_test/1,
|
||||
%%%%
|
||||
get_invoices_stats_ok_test/1,
|
||||
search_invoices_ok_test/1,
|
||||
search_payments_ok_test/1,
|
||||
get_payment_conversion_stats_ok_test/1,
|
||||
get_payment_revenue_stats_ok_test/1,
|
||||
get_payment_geo_stats_ok_test/1,
|
||||
@ -68,10 +69,9 @@
|
||||
create_payout_tool_ok_test/1,
|
||||
get_payout_tools_ok_test/1,
|
||||
%%%%
|
||||
get_locations_names_ok_test/1,
|
||||
%%%%
|
||||
set_merchant_callback_ok_test/1,
|
||||
get_merchant_callback_ok_test/1
|
||||
create_webhook_error_test/1,
|
||||
create_webhook_receive_events_test/1,
|
||||
get_locations_names_ok_test/1
|
||||
]).
|
||||
|
||||
-define(KEYCLOAK_HOST, "keycloak").
|
||||
@ -79,19 +79,20 @@
|
||||
-define(KEYCLOAK_USER, "demo_merchant").
|
||||
-define(KEYCLOAK_PASSWORD, "test").
|
||||
|
||||
-define(CAPI_IP, "::").
|
||||
-define(CAPI_HOST, "localhost").
|
||||
-define(CAPI_PORT, 8080).
|
||||
-define(CAPI_SERVICE_TYPE, real).
|
||||
-define(CAPI_CDS_STORAGE_URL, "http://cds:8022/v1/storage").
|
||||
-define(CAPI_INVOICING_URL, "http://hellgate:8022/v1/processing/invoicing").
|
||||
-define(CAPI_MERCHANT_STAT_URL, "http://magista:8022/stat").
|
||||
-define(CAPI_PARTY_MANAGEMENT_URL, "http://hellgate:8022/v1/processing/partymgmt").
|
||||
-define(CAPI_REPOSITORY_URL, "http://dominant:8022/v1/domain/repository").
|
||||
-define(CAPI_ACCOUNTER_URL, "http://shumway:8022/accounter").
|
||||
-define(GEO_IP_URL, "http://columbus:8022/repo").
|
||||
-define(MERCHANT_CONFIG_URL, "http://pimp:8022/capi").
|
||||
-define(CAPI_HOST_NAME, "capi").
|
||||
-define(CAPI_IP , "::").
|
||||
-define(CAPI_HOST , "localhost").
|
||||
-define(CAPI_PORT , 8080).
|
||||
-define(CAPI_SERVICE_TYPE , real).
|
||||
-define(CAPI_PARTY_MANAGEMENT_URL , "http://hellgate:8022/v1/processing/partymgmt").
|
||||
-define(CAPI_ACCOUNTER_URL , "http://shumway:8022/accounter").
|
||||
-define(CAPI_INVOICING_URL , "http://hellgate:8022/v1/processing/invoicing").
|
||||
-define(CAPI_MERCHANT_CONFIG_URL , "http://pimp:8022/capi").
|
||||
-define(CAPI_WEBHOOK_MGR_URL , "http://hooker:8022/hook").
|
||||
-define(CAPI_REPOSITORY_URL , "http://dominant:8022/v1/domain/repository").
|
||||
-define(CAPI_CDS_STORAGE_URL , "http://cds:8022/v1/storage").
|
||||
-define(CAPI_MERCHANT_STAT_URL , "http://magista:8022/stat").
|
||||
-define(CAPI_GEO_IP_URL , "http://columbus:8022/repo").
|
||||
-define(CAPI_HOST_NAME , "capi").
|
||||
|
||||
-define(MERCHANT_ID, <<"281220eb-a4ef-4d03-b666-bdec4b26c5f7">>).
|
||||
-define(LIVE_CATEGORY_ID, 100).
|
||||
@ -125,7 +126,7 @@ all() ->
|
||||
{group, claims_management},
|
||||
{group, shops_management},
|
||||
{group, accounts_management},
|
||||
{group, callback_management},
|
||||
{group, webhook_management},
|
||||
{group, geo_ip}
|
||||
].
|
||||
|
||||
@ -172,14 +173,9 @@ groups() ->
|
||||
create_payment_tool_token_w_access_token_ok_test,
|
||||
create_payment_ok_w_access_token_test
|
||||
]},
|
||||
{callback_management, [sequence], [
|
||||
get_categories_ok_test,
|
||||
get_category_by_id_ok_test,
|
||||
set_merchant_callback_ok_test,
|
||||
get_merchant_callback_ok_test
|
||||
]},
|
||||
{statistics, [sequence], [
|
||||
get_invoices_stats_ok_test,
|
||||
search_invoices_ok_test,
|
||||
search_payments_ok_test,
|
||||
get_payment_conversion_stats_ok_test,
|
||||
get_payment_revenue_stats_ok_test,
|
||||
get_payment_geo_stats_ok_test,
|
||||
@ -219,6 +215,10 @@ groups() ->
|
||||
create_shop_ok_test,
|
||||
get_account_by_id_ok_test
|
||||
]},
|
||||
{webhook_management, [sequence], [
|
||||
create_webhook_error_test,
|
||||
create_webhook_receive_events_test
|
||||
]},
|
||||
{geo_ip, [parallel], [
|
||||
get_locations_names_ok_test
|
||||
]}
|
||||
@ -231,7 +231,7 @@ groups() ->
|
||||
init_per_suite(Config) ->
|
||||
% _ = dbg:tracer(),
|
||||
% _ = dbg:p(all, c),
|
||||
% _ = dbg:tpl({'capi_authorizer_jwt', '_', '_'}, x),
|
||||
% _ = dbg:tpl({api_client_lib, 'handle_response', '_'}, x),
|
||||
Apps =
|
||||
capi_ct_helper:start_app(lager) ++
|
||||
capi_ct_helper:start_app(cowlib) ++
|
||||
@ -239,14 +239,15 @@ init_per_suite(Config) ->
|
||||
capi_ct_helper:start_app(api_client) ++
|
||||
capi_ct_helper:start_app(cp_proto, [
|
||||
{service_urls, #{
|
||||
cds_storage => ?CAPI_CDS_STORAGE_URL,
|
||||
invoicing => ?CAPI_INVOICING_URL,
|
||||
merchant_stat => ?CAPI_MERCHANT_STAT_URL,
|
||||
party_management => ?CAPI_PARTY_MANAGEMENT_URL,
|
||||
repository => ?CAPI_REPOSITORY_URL,
|
||||
accounter => ?CAPI_ACCOUNTER_URL,
|
||||
geo_ip_service => ?GEO_IP_URL,
|
||||
merchant_config => ?MERCHANT_CONFIG_URL
|
||||
accounter => ?CAPI_ACCOUNTER_URL,
|
||||
invoicing => ?CAPI_INVOICING_URL,
|
||||
merchant_config => ?CAPI_MERCHANT_CONFIG_URL,
|
||||
webhook_manager => ?CAPI_WEBHOOK_MGR_URL,
|
||||
repository => ?CAPI_REPOSITORY_URL,
|
||||
cds_storage => ?CAPI_CDS_STORAGE_URL,
|
||||
merchant_stat => ?CAPI_MERCHANT_STAT_URL,
|
||||
geo_ip_service => ?CAPI_GEO_IP_URL
|
||||
}}
|
||||
]),
|
||||
{ok, SupPid} = supervisor:start_link(?MODULE, []),
|
||||
@ -575,9 +576,9 @@ get_payment_by_id_ok_test(Config) ->
|
||||
{ok, _Body} = api_client_payments:get_payment_by_id(Context, InvoiceID, PaymentID),
|
||||
{save_config, Info}.
|
||||
|
||||
-spec get_invoices_stats_ok_test(config()) -> _.
|
||||
-spec search_invoices_ok_test(config()) -> _.
|
||||
|
||||
get_invoices_stats_ok_test(Config) ->
|
||||
search_invoices_ok_test(Config) ->
|
||||
Context = ?config(context, Config),
|
||||
ShopID = ?config(shop_id, Config),
|
||||
Query = [
|
||||
@ -585,10 +586,44 @@ get_invoices_stats_ok_test(Config) ->
|
||||
{offset, 2},
|
||||
{from_time, {{2015, 08, 11},{19, 42, 35}}},
|
||||
{to_time, {{2020, 08, 11},{19, 42, 35}}},
|
||||
{status, unpaid}
|
||||
{invoiceStatus, <<"fulfilled">>},
|
||||
{payerEmail, <<"test@test.ru">>},
|
||||
{payerIP, <<"192.168.0.0.1">>},
|
||||
{paymentStatus, <<"processed">>},
|
||||
{invoiceID, <<"testInvoiceID">>},
|
||||
{paymentID, <<"testPaymentID">>},
|
||||
{payerEmail, <<"test@test_rbk.ru">>},
|
||||
{payerIP, <<"192.168.0.1">>},
|
||||
{payerFingerprint, <<"blablablalbalbal">>},
|
||||
% {cardNumberMask, <<"222222**2222">>},
|
||||
{paymentAmount, 10000}
|
||||
],
|
||||
|
||||
{ok, _, _} = api_client_searches:get_invoices(Context, ShopID, Query).
|
||||
{ok, _, _} = api_client_searches:search_invoices(Context, ShopID, Query).
|
||||
|
||||
-spec search_payments_ok_test(config()) -> _.
|
||||
|
||||
search_payments_ok_test(Config) ->
|
||||
Context = ?config(context, Config),
|
||||
ShopID = ?config(shop_id, Config),
|
||||
Query = [
|
||||
{limit, 2},
|
||||
{offset, 2},
|
||||
{from_time, {{2015, 08, 11},{19, 42, 35}}},
|
||||
{to_time, {{2020, 08, 11},{19, 42, 35}}},
|
||||
{payerEmail, <<"test@test.ru">>},
|
||||
{payerIP, <<"192.168.0.0.1">>},
|
||||
{paymentStatus, <<"processed">>},
|
||||
{invoiceID, <<"testInvoiceID">>},
|
||||
{paymentID, <<"testPaymentID">>},
|
||||
{payerEmail, <<"test@test_rbk.ru">>},
|
||||
{payerIP, <<"192.168.0.1">>},
|
||||
{payerFingerprint, <<"blablablalbalbal">>},
|
||||
% {cardNumberMask, <<"222222**2222">>},
|
||||
{paymentAmount, 10000}
|
||||
],
|
||||
|
||||
{ok, _, _} = api_client_searches:search_payments(Context, ShopID, Query).
|
||||
|
||||
-spec get_payment_conversion_stats_ok_test(config()) -> _.
|
||||
|
||||
@ -922,46 +957,6 @@ activate_shop_idempotent_ok_test(Config) ->
|
||||
} = default_get_shop_by_id(ShopID, Config),
|
||||
{save_config, ShopID}.
|
||||
|
||||
-spec set_merchant_callback_ok_test(config()) -> _.
|
||||
|
||||
set_merchant_callback_ok_test(Config) ->
|
||||
{get_category_by_id_ok_test,
|
||||
CategoryID
|
||||
} = ?config(saved_config, Config),
|
||||
CallbackUrl = <<"http://www.test.com">>,
|
||||
ClaimID = default_create_shop(CategoryID, CallbackUrl, Config),
|
||||
{ok, _} = default_approve_claim(ClaimID),
|
||||
#{
|
||||
<<"id">> := ClaimID,
|
||||
<<"status">> := #{<<"status">> := <<"ClaimAccepted">>},
|
||||
<<"changeset">> := [
|
||||
#{
|
||||
<<"partyModificationType">> := <<"ShopCreation">>,
|
||||
<<"shop">> := #{
|
||||
<<"id">> := ShopID
|
||||
}
|
||||
} | _
|
||||
]
|
||||
} = default_get_claim_by_id(ClaimID, Config),
|
||||
|
||||
{save_config, #{shop_id => ShopID, callback_url => CallbackUrl}}.
|
||||
|
||||
-spec get_merchant_callback_ok_test(config()) -> _.
|
||||
get_merchant_callback_ok_test(Config) ->
|
||||
{set_merchant_callback_ok_test,
|
||||
#{
|
||||
shop_id := ShopID,
|
||||
callback_url := CallbackUrl
|
||||
}
|
||||
} = ?config(saved_config, Config),
|
||||
#{
|
||||
<<"id">> := ShopID,
|
||||
<<"callbackHandler">> := #{
|
||||
<<"url">> := CallbackUrl,
|
||||
<<"publicKey">> := _
|
||||
}
|
||||
} = default_get_shop_by_id(ShopID, Config).
|
||||
|
||||
-spec get_account_by_id_ok_test(config()) -> _.
|
||||
|
||||
get_account_by_id_ok_test(Config) ->
|
||||
@ -982,6 +977,47 @@ get_account_by_id_ok_test(Config) ->
|
||||
%% @FIXME changin Account ID to string is not ok
|
||||
} = default_get_shop_account_by_id(GuaranteeID, ShopID, Config).
|
||||
|
||||
-spec create_webhook_error_test(config()) -> _.
|
||||
create_webhook_error_test(Config) ->
|
||||
Context = ?config(context, Config),
|
||||
ShopID = -1, % nonexistent
|
||||
{error, _} = api_client_webhooks:create_webhook(Context, #{
|
||||
<<"url">> => <<"http://localhost:8080/TODO">>,
|
||||
<<"scope">> => construct_invoices_scope(ShopID)
|
||||
}).
|
||||
|
||||
-spec create_webhook_receive_events_test(config()) -> _.
|
||||
create_webhook_receive_events_test(Config) ->
|
||||
Context = ?config(context, Config),
|
||||
% % list is empty?
|
||||
% [] = api_client_webhooks:get_webhooks(Context),
|
||||
% create successful?
|
||||
Shop = get_latest(get_shops(Config)),
|
||||
ShopID = maps:get(<<"id">>, Shop),
|
||||
WebhookParams = #{
|
||||
<<"url">> => <<"http://localhost:8080/TODO">>,
|
||||
<<"scope">> => construct_invoices_scope(ShopID, ['InvoiceCancelled'])
|
||||
},
|
||||
{ok, Webhook = #{<<"id">> := WebhookID}} = api_client_webhooks:create_webhook(Context, WebhookParams),
|
||||
{ok, Webhook} = api_client_webhooks:get_webhook_by_id(Context, WebhookID),
|
||||
% list is not empty then?
|
||||
true = lists:member(Webhook, api_client_webhooks:get_webhooks(Context)),
|
||||
% delete succeeded idempotently?
|
||||
ok = api_client_webhooks:delete_webhook_by_id(Context, WebhookID),
|
||||
ok = api_client_webhooks:delete_webhook_by_id(Context, WebhookID),
|
||||
[] = [W || #{<<"id">> := W} <- api_client_webhooks:get_webhooks(Context), W =:= WebhookID],
|
||||
ok.
|
||||
|
||||
construct_invoices_scope(ShopID) ->
|
||||
construct_invoices_scope(ShopID, []).
|
||||
|
||||
construct_invoices_scope(ShopID, EventTypes) ->
|
||||
#{
|
||||
<<"topic">> => <<"InvoicesTopic">>,
|
||||
<<"shopID">> => ShopID,
|
||||
<<"eventTypes">> => lists:map(fun genlib:to_binary/1, EventTypes)
|
||||
}.
|
||||
|
||||
-spec get_locations_names_ok_test(config()) -> _.
|
||||
get_locations_names_ok_test(Config) ->
|
||||
{TestGeoID, TestName} = {53654, <<"Могадишо"/utf8>>},
|
||||
@ -1225,9 +1261,6 @@ default_get_shop_by_id(ShopID, Config) ->
|
||||
R.
|
||||
|
||||
default_create_shop(CategoryID, Config) ->
|
||||
default_create_shop(CategoryID, undefined, Config).
|
||||
|
||||
default_create_shop(CategoryID, CallbackUrl, Config) ->
|
||||
#{
|
||||
<<"claimID">> := ClaimID0
|
||||
} = default_create_contract(Config),
|
||||
@ -1239,10 +1272,10 @@ default_create_shop(CategoryID, CallbackUrl, Config) ->
|
||||
default_approve_claim(ClaimID1),
|
||||
#{<<"id">> := PayoutToolID} = get_latest(get_payout_tools(ContractID, Config)),
|
||||
|
||||
default_create_shop(CategoryID, ContractID, PayoutToolID, CallbackUrl, Config).
|
||||
default_create_shop(CategoryID, ContractID, PayoutToolID, Config).
|
||||
|
||||
|
||||
default_create_shop(CategoryID, ContractID, PayoutToolID, CallbackUrl, Config) ->
|
||||
default_create_shop(CategoryID, ContractID, PayoutToolID, Config) ->
|
||||
Context = ?config(context, Config),
|
||||
Req = genlib_map:compact(#{
|
||||
<<"categoryID">> => CategoryID,
|
||||
@ -1251,8 +1284,7 @@ default_create_shop(CategoryID, ContractID, PayoutToolID, CallbackUrl, Config) -
|
||||
<<"description">> => <<"Goods for education">>
|
||||
},
|
||||
<<"contractID">> => ContractID,
|
||||
<<"payoutToolID">> => PayoutToolID,
|
||||
<<"callbackUrl">> => CallbackUrl
|
||||
<<"payoutToolID">> => PayoutToolID
|
||||
}),
|
||||
{ok, ClaimID} = api_client_shops:create_shop(Context, Req),
|
||||
ClaimID.
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 6ba6971bad2a64104c7e89abc5269dca1c029d38
|
||||
Subproject commit 4018c4162f55c9d2e3a6b7224915404f4bce8915
|
@ -21,7 +21,8 @@
|
||||
"accounter.thrift",
|
||||
"geo_ip.thrift",
|
||||
"domain_config.thrift",
|
||||
"proxy_merch_config.thrift"
|
||||
"proxy_merch_config.thrift",
|
||||
"webhooker.thrift"
|
||||
]},
|
||||
{gen, "erlang:app_prefix=cp,scoped_typenames"}
|
||||
]}.
|
||||
|
@ -34,5 +34,7 @@ get_service_modname(geo_ip_service) ->
|
||||
{cp_geo_ip_thrift, 'GeoIpService'};
|
||||
get_service_modname(merchant_config) ->
|
||||
{cp_proxy_merch_config_thrift, 'ConfigureMerchantProxy'};
|
||||
get_service_modname(webhook_manager) ->
|
||||
{cp_webhooker_thrift, 'WebhookManager'};
|
||||
get_service_modname(party_management) ->
|
||||
{cp_payment_processing_thrift, 'PartyManagement'}.
|
||||
|
@ -30,13 +30,15 @@
|
||||
|
||||
{cp_proto, [
|
||||
{service_urls, #{
|
||||
invoicing => "http://hellgate:8022/v1/processing/invoicing",
|
||||
cds_storage => "http://cds:8022/v1/storage",
|
||||
merchant_stat => "http://magista:8022/stat",
|
||||
party_management => "http://hellgate:8022/v1/processing/partymgmt",
|
||||
geo_ip_service => "http://columbus:8022/repo",
|
||||
repository => "http://dominant:8022/v1/domain/repository",
|
||||
merchant_config => "http://pimp:8022/capi"
|
||||
accounter => "http://shumway:8022/accounter",
|
||||
invoicing => "http://hellgate:8022/v1/processing/invoicing",
|
||||
merchant_config => "http://pimp:8022/capi",
|
||||
webhook_manager => "http://hooker:8022/hook",
|
||||
repository => "http://dominant:8022/v1/domain/repository",
|
||||
cds_storage => "http://cds:8022/v1/storage",
|
||||
merchant_stat => "http://magista:8022/stat",
|
||||
geo_ip_service => "http://columbus:8022/repo"
|
||||
}}
|
||||
]},
|
||||
|
||||
|
@ -28,6 +28,8 @@ services:
|
||||
condition: service_started
|
||||
pimp:
|
||||
condition: service_started
|
||||
hooker:
|
||||
condition: service_healthy
|
||||
|
||||
hellgate:
|
||||
image: dr.rbkmoney.com/rbkmoney/hellgate:bf50fbffda6c65ebf055446dfb27ab31392a4881
|
||||
@ -62,7 +64,7 @@ services:
|
||||
retries: 12
|
||||
|
||||
magista:
|
||||
image: dr.rbkmoney.com/rbkmoney/magista:74e1bbf7dde05b8af66ce62c8c55dc035b655f99
|
||||
image: dr.rbkmoney.com/rbkmoney/magista:872cd681a5a26e986763897518afa5d30f80f187
|
||||
restart: always
|
||||
entrypoint:
|
||||
- java
|
||||
@ -198,6 +200,36 @@ services:
|
||||
-Xmx512m
|
||||
-jar /opt/pimp/pimp.jar
|
||||
|
||||
hooker:
|
||||
image: dr.rbkmoney.com/rbkmoney/hooker:799d6994c9abc761b66a352c39b3287d59839b98
|
||||
healthcheck:
|
||||
test: "curl -sS -o /dev/null http://localhost:8022/"
|
||||
interval: 5s
|
||||
timeout: 2s
|
||||
retries: 10
|
||||
entrypoint:
|
||||
- java
|
||||
- -jar
|
||||
- /opt/hooker/hooker.jar
|
||||
- --spring.datasource.url=jdbc:postgresql://hooker-db:5432/hook
|
||||
- --spring.datasource.username=postgres
|
||||
- --spring.datasource.password=postgres
|
||||
- --flyway.url=jdbc:postgresql://hooker-db:5432/hook
|
||||
- --flyway.user=postgres
|
||||
- --flyway.password=postgres
|
||||
- --flyway.schemas=hook
|
||||
- --bm.pooling.url=http://bustermaze:8022/repo
|
||||
depends_on:
|
||||
- hooker-db
|
||||
- bustermaze
|
||||
|
||||
hooker-db:
|
||||
image: dr.rbkmoney.com/rbkmoney/postgres:9.6
|
||||
environment:
|
||||
- POSTGRES_DB=hook
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
|
||||
keycloak:
|
||||
image: dr.rbkmoney.com/rbkmoney/keycloak:a4c082f48695cb02e0624deb559f9ec0378abdb4
|
||||
healthcheck:
|
||||
|
@ -1,7 +1,7 @@
|
||||
{"1.1.0",
|
||||
[{<<"api_client">>,
|
||||
{git,"git@github.com:rbkmoney/api_client.git",
|
||||
{ref,"8dbbdffa8e5583e98067ee97343286dd76ec8381"}},
|
||||
{ref,"c135f8c4e8302e6eb51c4e4a6fd9997503a196ed"}},
|
||||
0},
|
||||
{<<"base64url">>,{pkg,<<"base64url">>,<<"0.0.1">>},0},
|
||||
{<<"certifi">>,{pkg,<<"certifi">>,<<"0.4.0">>},1},
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 7fb63e90f3a622357da9781b0f9e410169db8bdb
|
||||
Subproject commit 8e5f8583c3a95bc0722f12034c67bfb440fd240d
|
Loading…
Reference in New Issue
Block a user