TD-124: Setup CI/CD with GH Actions (#1)

* Drop proprietary CI stuff
* Stop including default secret in release
* Fix io encoding w/ iosetopts
* Bump to valitydev/damsel@dcd92dd
* Implement and test `GetServiceProviderByID` op
* Depend on valitydev/swag-payments@a639270
* Drop geo api handler and tests
* Switch to valitydev upstream
  * valitydev/cowboy_access_log@04da359
  * valitydev/damsel@b25d336
  * valitydev/dmt_client@e9b1961
  * valitydev/dmt_core@910e20e
  * valitydev/party_client_erlang@8fc5595
  * valitydev/woody_erlang@0c2e16d
  * valitydev/woody_api_hay@4c39134
* Drop client url logging
* Setup CI/CD with GH Actions
* Drop dead links

Co-authored-by: ndiezel0 <ndiezel0@gmail.com>
This commit is contained in:
Andrew Mayorov 2022-02-04 19:28:33 +03:00 committed by GitHub
parent 8381da653a
commit 14369d48f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 1194 additions and 1305 deletions

7
.dockerignore Normal file
View File

@ -0,0 +1,7 @@
/_build/
/.git/
/.github/
/.vscode/
/.idea/
erl_crash.dump
rebar3.crashdump

7
.env Normal file
View File

@ -0,0 +1,7 @@
# NOTE
# You SHOULD specify point releases here so that build time and run time Erlang/OTPs
# are the same. See: https://github.com/erlware/relx/pull/902
SERVICE_NAME=capi
OTP_VERSION=24.2.0
REBAR_VERSION=3.18
THRIFT_VERSION=0.14.2.2

53
.github/workflows/build-image.yml vendored Normal file
View File

@ -0,0 +1,53 @@
name: Build Docker image
on:
push:
branches:
- 'master'
- 'epic/**'
pull_request:
branches: [ '**' ]
env:
REGISTRY: ghcr.io
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Buildx
uses: docker/setup-buildx-action@v1
# https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#setting-an-environment-variable
- name: Update environment variables
run: grep -v '^#' .env >> $GITHUB_ENV
- name: Log in to the Container registry
uses: docker/login-action@v1.12.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Construct tags / labels for an image
id: meta
uses: docker/metadata-action@v3.6.2
with:
images: |
${{ env.REGISTRY }}/${{ github.repository }}
tags: |
type=sha
- name: Build and push Docker image
uses: docker/build-push-action@v2.9.0
with:
push: ${{ github.event_name == 'push' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
SERVICE_NAME=${{ env.SERVICE_NAME }}
OTP_VERSION=${{ env.OTP_VERSION }}
THRIFT_VERSION=${{ env.THRIFT_VERSION }}

38
.github/workflows/erlang-checks.yml vendored Normal file
View File

@ -0,0 +1,38 @@
name: Erlang CI Checks
on:
push:
branches:
- 'master'
- 'epic/**'
pull_request:
branches: [ '**' ]
jobs:
setup:
name: Load .env
runs-on: ubuntu-latest
outputs:
otp-version: ${{ steps.otp-version.outputs.version }}
rebar-version: ${{ steps.rebar-version.outputs.version }}
thrift-version: ${{ steps.thrift-version.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@v2
- run: grep -v '^#' .env >> $GITHUB_ENV
- id: otp-version
run: echo "::set-output name=version::$OTP_VERSION"
- id: rebar-version
run: echo "::set-output name=version::$REBAR_VERSION"
- id: thrift-version
run: echo "::set-output name=version::$THRIFT_VERSION"
run:
name: Run checks
needs: setup
uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.1
with:
otp-version: ${{ needs.setup.outputs.otp-version }}
rebar-version: ${{ needs.setup.outputs.rebar-version }}
use-thrift: true
thrift-version: ${{ needs.setup.outputs.thrift-version }}

5
.gitignore vendored
View File

@ -12,13 +12,10 @@ erl_crash.dump
/_checkouts/ /_checkouts/
# generated # generated
apps/swag_server/*
apps/swag_client/*
*.beam *.beam
.image.dev
# containerization # containerization
\#* \#*
.\#* .\#*
Dockerfile
docker-compose.yml
tags tags

8
.gitmodules vendored
View File

@ -1,8 +0,0 @@
[submodule "schemes/swag"]
path = schemes/swag
branch = release/v2
url = git@github.com:rbkmoney/swag.git
[submodule "build_utils"]
path = build_utils
url = git@github.com:rbkmoney/build_utils.git
branch = master

40
Dockerfile Normal file
View File

@ -0,0 +1,40 @@
ARG OTP_VERSION
# Build the release
FROM docker.io/library/erlang:${OTP_VERSION} AS builder
ARG BUILDARCH
# Install thrift compiler
ARG THRIFT_VERSION
RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${BUILDARCH}.tar.gz" \
| tar -xvz -C /usr/local/bin/
# Copy sources
RUN mkdir /build
COPY . /build/
# Build the release
WORKDIR /build
RUN rebar3 compile
RUN rebar3 as prod release
# Make a runner image
FROM docker.io/library/erlang:${OTP_VERSION}-slim
ARG SERVICE_NAME
# Set env
ENV CHARSET=UTF-8
ENV LANG=C.UTF-8
# Set runtime
WORKDIR /opt/${SERVICE_NAME}
COPY --from=builder /build/_build/prod/rel/${SERVICE_NAME} /opt/${SERVICE_NAME}
ENTRYPOINT []
CMD /opt/${SERVICE_NAME}/bin/${SERVICE_NAME} foreground
EXPOSE 8022

18
Dockerfile.dev Normal file
View File

@ -0,0 +1,18 @@
ARG OTP_VERSION
FROM docker.io/library/erlang:${OTP_VERSION}
ARG BUILDARCH
# Install thrift compiler
ARG THRIFT_VERSION
RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${BUILDARCH}.tar.gz" \
| tar -xvz -C /usr/local/bin/
# Set env
ENV CHARSET=UTF-8
ENV LANG=C.UTF-8
# Set runtime
CMD /bin/bash

View File

@ -1,26 +0,0 @@
#!/bin/bash
cat <<EOF
FROM $BASE_IMAGE
MAINTAINER Artem Ocheredko <a.ocheredko@rbkmoney.com>
COPY ./_build/prod/rel/capi /opt/capi
WORKDIR /opt/capi
CMD /opt/capi/bin/capi foreground
EXPOSE 8080
# A bit of magic below to get a proper branch name
# even when the HEAD is detached (Hey Jenkins!
# BRANCH_NAME is available in Jenkins env).
LABEL com.rbkmoney.$SERVICE_NAME.parent=$BASE_IMAGE_NAME \
com.rbkmoney.$SERVICE_NAME.parent_tag=$BASE_IMAGE_TAG \
com.rbkmoney.$SERVICE_NAME.build_img=build \
com.rbkmoney.$SERVICE_NAME.build_img_tag=$BUILD_IMAGE_TAG \
com.rbkmoney.$SERVICE_NAME.commit_id=$(git rev-parse HEAD) \
com.rbkmoney.$SERVICE_NAME.commit_number=$(git rev-list --count HEAD) \
com.rbkmoney.$SERVICE_NAME.branch=$( \
if [ "HEAD" != $(git rev-parse --abbrev-ref HEAD) ]; then \
echo $(git rev-parse --abbrev-ref HEAD); \
elif [ -n "$BRANCH_NAME" ]; then \
echo $BRANCH_NAME; \
else \
echo $(git name-rev --name-only HEAD); \
fi)
EOF

22
Jenkinsfile vendored
View File

@ -1,22 +0,0 @@
#!groovy
// -*- mode: groovy -*-
def finalHook = {
runStage('store CT logs') {
archive '_build/test/logs/'
}
}
build('capi', 'docker-host', finalHook) {
checkoutRepo()
loadBuildUtils()
def pipeErlangService
runStage('load pipeline') {
env.JENKINS_LIB = "build_utils/jenkins_lib"
env.SH_TOOLS = "build_utils/sh"
pipeErlangService = load("${env.JENKINS_LIB}/pipeErlangService.groovy")
}
pipeErlangService.runPipe(false, false, 'test')
}

174
Makefile
View File

@ -1,138 +1,92 @@
REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) # HINT
SUBMODULES = schemes/swag build_utils # Use this file to override variables here.
SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) # For example, to run with podman put `DOCKER=podman` there.
-include Makefile.env
COMPOSE_HTTP_TIMEOUT := 300 # NOTE
export COMPOSE_HTTP_TIMEOUT # Variables specified in `.env` file are used to pick and setup specific
# component versions, both when building a development image and when running
# CI workflows on GH Actions. This ensures that tasks run with `wc-` prefix
# (like `wc-dialyze`) are reproducible between local machine and CI runners.
DOTENV := $(shell grep -v '^\#' .env)
UTILS_PATH := build_utils # Development images
TEMPLATES_PATH := . DEV_IMAGE_TAG = capi-dev
DEV_IMAGE_ID = $(file < .image.dev)
# Name of the service DOCKER ?= docker
SERVICE_NAME := capi-v2 REBAR ?= rebar3
# Service image default tag
SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD)
# The tag for service image to be pushed with
SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG)
# Base image for the service
BASE_IMAGE_NAME := service-erlang
BASE_IMAGE_TAG := fe43cb7176f34abcde7b101755600ecd8be635e3
# Build image tag to be used
BUILD_IMAGE_NAME := build-erlang
BUILD_IMAGE_TAG := 117a2e28e18d41d4c3eb76f5d00af117872af5ac
CALL_ANYWHERE := \
submodules \
all compile xref lint dialyze update_plt test cover \
start devrel release clean distclean \
generate regenerate swag_server.regenerate swag_client.regenerate \
check_format format
CALL_W_CONTAINER := $(CALL_ANYWHERE)
.PHONY: $(CALL_W_CONTAINER) all
all: compile all: compile
-include $(UTILS_PATH)/make_lib/utils_container.mk .PHONY: dev-image clean-dev-image wc-shell test
-include $(UTILS_PATH)/make_lib/utils_image.mk
$(SUBTARGETS): %/.git: % dev-image: .image.dev
git submodule update --init $<
touch $@
submodules: $(SUBTARGETS) .image.dev: Dockerfile.dev .env
$(DOCKER) build $(DOTENV:%=--build-arg %) -f Dockerfile.dev -t $(DEV_IMAGE_TAG) .
$(DOCKER) image ls -q -f "reference=$(DEV_IMAGE_ID)" | head -n1 > $@
generate: swag_server.generate swag_client.generate clean-dev-image:
ifneq ($(DEV_IMAGE_ID),)
$(DOCKER) image rm -f $(DEV_IMAGE_TAG)
rm .image.dev
endif
regenerate: swag_server.regenerate swag_client.regenerate DOCKER_WC_OPTIONS := -v $(PWD):$(PWD) --workdir $(PWD)
DOCKER_WC_EXTRA_OPTIONS ?= --rm
DOCKER_RUN = $(DOCKER) run -t $(DOCKER_WC_OPTIONS) $(DOCKER_WC_EXTRA_OPTIONS)
compile: submodules generate # Utility tasks
wc-shell: dev-image
$(DOCKER_RUN) --interactive --tty $(DEV_IMAGE_TAG)
wc-%: dev-image
$(DOCKER_RUN) $(DEV_IMAGE_TAG) make $*
# Rebar tasks
rebar-shell:
$(REBAR) shell
compile:
$(REBAR) compile $(REBAR) compile
xref: xref:
$(REBAR) xref $(REBAR) xref
lint: generate lint:
elvis rock -V $(REBAR) lint
check_format: check-format:
$(REBAR) fmt -c $(REBAR) fmt -c
format:
$(REBAR) fmt -w
dialyze: dialyze:
$(REBAR) as test dialyzer $(REBAR) as test dialyzer
update_plt: release:
$(REBAR) dialyzer -u true -s false
start: submodules
$(REBAR) run
release: submodules generate
$(REBAR) as prod release $(REBAR) as prod release
clean: eunit:
$(REBAR) cover -r $(REBAR) eunit --cover
$(REBAR) clean
distclean: swag_server.distclean swag_client.distclean common-test:
rm -rf _build $(REBAR) ct --cover
cover: cover:
$(REBAR) covertool generate
format:
$(REBAR) fmt -w
clean:
$(REBAR) clean
distclean: clean-build-image
rm -rf _build
test: eunit common-test
cover-report:
$(REBAR) cover $(REBAR) cover
# CALL_W_CONTAINER
test: submodules generate
$(REBAR) do eunit, ct
# Swagger stuff
SWAGGER_CODEGEN = $(call which, swagger-codegen)
SWAGGER_SCHEME_PATH = schemes/swag
SWAGGER_SCHEME = $(SWAGGER_SCHEME_PATH)/swagger.yaml
$(SWAGGER_SCHEME): $(SWAGGER_SCHEME_PATH)/.git
# Swagger server
SWAG_SERVER_PREFIX = swag_server
SWAG_SERVER_APP_PATH = apps/$(SWAG_SERVER_PREFIX)
SWAG_SERVER_APP_TARGET = $(SWAG_SERVER_APP_PATH)/rebar.config
swag_server.generate: $(SWAG_SERVER_APP_TARGET)
swag_server.distclean:
rm -rf $(SWAG_SERVER_APP_PATH)
swag_server.regenerate: swag_server.distclean swag_server.generate
$(SWAG_SERVER_APP_TARGET): $(SWAGGER_SCHEME)
$(SWAGGER_CODEGEN) generate \
-i $(SWAGGER_SCHEME) \
-l erlang-server \
-o $(SWAG_SERVER_APP_PATH) \
--additional-properties \
packageName=$(SWAG_SERVER_PREFIX)
# Swagger client
SWAG_CLIENT_PREFIX = swag_client
SWAG_CLIENT_APP_PATH = apps/$(SWAG_CLIENT_PREFIX)
SWAG_CLIENT_APP_TARGET = $(SWAG_CLIENT_APP_PATH)/rebar.config
swag_client.generate: $(SWAG_CLIENT_APP_TARGET)
swag_client.distclean:
rm -rf $(SWAG_CLIENT_APP_PATH)
swag_client.regenerate: swag_client.distclean swag_client.generate
$(SWAG_CLIENT_APP_TARGET): $(SWAGGER_SCHEME)
$(SWAGGER_CODEGEN) generate \
-i $(SWAGGER_SCHEME) \
-l erlang-client \
-o $(SWAG_CLIENT_APP_PATH) \
--additional-properties \
packageName=$(SWAG_CLIENT_PREFIX)

View File

@ -1,8 +1,8 @@
{application, capi , [ {application, capi, [
{description, "A service that does something"}, {description, "Implementation of swag-payments openapi specification"},
{vsn, "0.1.0"}, {vsn, "0.1.0"},
{registered, []}, {registered, []},
{mod, {capi , []}}, {mod, {capi, []}},
{applications, [ {applications, [
kernel, kernel,
stdlib, stdlib,
@ -26,8 +26,6 @@
woody_user_identity, woody_user_identity,
payproc_errors, payproc_errors,
erl_health, erl_health,
prometheus,
prometheus_cowboy,
bouncer_client, bouncer_client,
token_keeper_client, token_keeper_client,
party_client, party_client,

View File

@ -37,8 +37,8 @@
%% Internal types %% Internal types
-define(authorized(Ctx), {authorized, Ctx}). -define(AUTHORIZED(Ctx), {authorized, Ctx}).
-define(unauthorized(Ctx), {unauthorized, Ctx}). -define(UNAUTHORIZED(Ctx), {unauthorized, Ctx}).
%% %%
%% API functions %% API functions
@ -54,19 +54,19 @@ get_subject_id(AuthContext) ->
end. end.
-spec get_party_id(auth_context()) -> binary() | undefined. -spec get_party_id(auth_context()) -> binary() | undefined.
get_party_id(?authorized(AuthData)) -> get_party_id(?AUTHORIZED(AuthData)) ->
get_metadata(get_metadata_mapped_key(party_id), token_keeper_auth_data:get_metadata(AuthData)). get_metadata(get_metadata_mapped_key(party_id), token_keeper_auth_data:get_metadata(AuthData)).
-spec get_user_id(auth_context()) -> binary() | undefined. -spec get_user_id(auth_context()) -> binary() | undefined.
get_user_id(?authorized(AuthData)) -> get_user_id(?AUTHORIZED(AuthData)) ->
get_metadata(get_metadata_mapped_key(user_id), token_keeper_auth_data:get_metadata(AuthData)). get_metadata(get_metadata_mapped_key(user_id), token_keeper_auth_data:get_metadata(AuthData)).
-spec get_user_email(auth_context()) -> binary() | undefined. -spec get_user_email(auth_context()) -> binary() | undefined.
get_user_email(?authorized(AuthData)) -> get_user_email(?AUTHORIZED(AuthData)) ->
get_metadata(get_metadata_mapped_key(user_email), token_keeper_auth_data:get_metadata(AuthData)). get_metadata(get_metadata_mapped_key(user_email), token_keeper_auth_data:get_metadata(AuthData)).
-spec get_consumer(auth_context()) -> consumer(). -spec get_consumer(auth_context()) -> consumer().
get_consumer(?authorized(AuthData)) -> get_consumer(?AUTHORIZED(AuthData)) ->
case get_metadata(get_metadata_mapped_key(token_consumer), token_keeper_auth_data:get_metadata(AuthData)) of case get_metadata(get_metadata_mapped_key(token_consumer), token_keeper_auth_data:get_metadata(AuthData)) of
<<"merchant">> -> merchant; <<"merchant">> -> merchant;
<<"client">> -> client; <<"client">> -> client;
@ -80,14 +80,14 @@ get_consumer(?authorized(AuthData)) ->
preauthorize_api_key(ApiKey) -> preauthorize_api_key(ApiKey) ->
case parse_api_key(ApiKey) of case parse_api_key(ApiKey) of
{ok, Token} -> {ok, Token} ->
{ok, ?unauthorized(Token)}; {ok, ?UNAUTHORIZED(Token)};
{error, Error} -> {error, Error} ->
{error, Error} {error, Error}
end. end.
-spec authorize_api_key(preauth_context(), token_keeper_client:source_context(), woody_context:ctx()) -> -spec authorize_api_key(preauth_context(), token_keeper_client:source_context(), woody_context:ctx()) ->
{ok, auth_context()} | {error, _Reason}. {ok, auth_context()} | {error, _Reason}.
authorize_api_key(?unauthorized({TokenType, Token}), TokenContext, WoodyContext) -> authorize_api_key(?UNAUTHORIZED({TokenType, Token}), TokenContext, WoodyContext) ->
authorize_token_by_type(TokenType, Token, TokenContext, WoodyContext). authorize_token_by_type(TokenType, Token, TokenContext, WoodyContext).
-spec authorize_operation( -spec authorize_operation(
@ -197,13 +197,13 @@ create_metadata(TokenSpec) ->
extract_auth_context(#{swagger_context := #{auth_context := AuthContext}}) -> extract_auth_context(#{swagger_context := #{auth_context := AuthContext}}) ->
AuthContext. AuthContext.
get_token_keeper_fragment(?authorized(AuthData)) -> get_token_keeper_fragment(?AUTHORIZED(AuthData)) ->
token_keeper_auth_data:get_context_fragment(AuthData). token_keeper_auth_data:get_context_fragment(AuthData).
authorize_token_by_type(bearer, Token, TokenContext, WoodyContext) -> authorize_token_by_type(bearer, Token, TokenContext, WoodyContext) ->
case token_keeper_client:get_by_token(Token, TokenContext, WoodyContext) of case token_keeper_client:get_by_token(Token, TokenContext, WoodyContext) of
{ok, AuthData} -> {ok, AuthData} ->
{ok, ?authorized(AuthData)}; {ok, ?AUTHORIZED(AuthData)};
{error, TokenKeeperError} -> {error, TokenKeeperError} ->
_ = logger:warning("Token keeper authorization failed: ~p", [TokenKeeperError]), _ = logger:warning("Token keeper authorization failed: ~p", [TokenKeeperError]),
{error, {auth_failed, TokenKeeperError}} {error, {auth_failed, TokenKeeperError}}

View File

@ -104,7 +104,6 @@ get_handlers() ->
capi_handler_contracts, capi_handler_contracts,
capi_handler_countries, capi_handler_countries,
capi_handler_customers, capi_handler_customers,
capi_handler_geo,
capi_handler_invoice_templates, capi_handler_invoice_templates,
capi_handler_invoices, capi_handler_invoices,
capi_handler_parties, capi_handler_parties,
@ -162,7 +161,7 @@ handle_function_(OperationID, Req, SwagContext0, HandlerOpts) ->
throw:{handler_respond, HandlerResponse} -> throw:{handler_respond, HandlerResponse} ->
{ok, HandlerResponse}; {ok, HandlerResponse};
throw:{bad_deadline, _Deadline} -> throw:{bad_deadline, _Deadline} ->
{ok, logic_error(invalidDeadline, <<"Invalid data in X-Request-Deadline header">>)}; {ok, logic_error('invalidDeadline', <<"Invalid data in X-Request-Deadline header">>)};
throw:{handler_function_clause, _OperationID} -> throw:{handler_function_clause, _OperationID} ->
_ = logger:error("Operation ~p failed due to missing handler", [OperationID]), _ = logger:error("Operation ~p failed due to missing handler", [OperationID]),
{error, {501, #{}, undefined}}; {error, {501, #{}, undefined}};
@ -300,13 +299,13 @@ set_context_meta(Context) ->
-spec set_request_meta(operation_id(), request_data()) -> ok. -spec set_request_meta(operation_id(), request_data()) -> ok.
set_request_meta(OperationID, Req) -> set_request_meta(OperationID, Req) ->
InterestParams = [ InterestParams = [
invoiceID, 'invoiceID',
invoiceTemplateID, 'invoiceTemplateID',
contractID, 'contractID',
webhookID, 'webhookID',
reportID, 'reportID',
shopID, 'shopID',
customerID 'customerID'
], ],
Meta = #{ Meta = #{
operation_id => OperationID, operation_id => OperationID,

View File

@ -44,7 +44,7 @@ process_request('GetPaymentGeoStats', Context, Req) ->
process_request('GetPaymentRateStats', Context, Req) -> process_request('GetPaymentRateStats', Context, Req) ->
process_merchant_stat(customers_rate_stat, Req, Context); process_merchant_stat(customers_rate_stat, Req, Context);
process_request('GetPaymentMethodStats', Context, Req) -> process_request('GetPaymentMethodStats', Context, Req) ->
bankCard = maps:get(paymentMethod, Req), 'bankCard' = maps:get('paymentMethod', Req),
StatType = payments_pmt_cards_stat, StatType = payments_pmt_cards_stat,
process_merchant_stat(StatType, Req, Context). process_merchant_stat(StatType, Req, Context).
@ -90,9 +90,9 @@ process_merchant_stat_result(StatType, Result) ->
{ok, {200, #{}, Resp}}; {ok, {200, #{}, Resp}};
{exception, #'InvalidRequest'{errors = Errors}} -> {exception, #'InvalidRequest'{errors = Errors}} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors), FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidRequest', FormattedErrors)};
{exception, #merchstat_BadToken{}} -> {exception, #merchstat_BadToken{}} ->
{ok, logic_error(invalidRequest, <<"Invalid token">>)} {ok, logic_error('invalidRequest', <<"Invalid token">>)}
end. end.
decode_stat_info(payments_conversion_stat, Response) -> decode_stat_info(payments_conversion_stat, Response) ->

View File

@ -29,7 +29,7 @@ prepare(OperationID = 'GetCategoryByRef', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end, end,
Process = fun() -> Process = fun() ->
case get_category_by_id(genlib:to_int(maps:get(categoryID, Req)), Context) of case get_category_by_id(genlib:to_int(maps:get('categoryID', Req)), Context) of
{ok, Category} -> {ok, Category} ->
{ok, {200, #{}, decode_category(Category)}}; {ok, {200, #{}, decode_category(Category)}};
{error, not_found} -> {error, not_found} ->

View File

@ -38,13 +38,9 @@ prepare(OperationID = 'GetClaimByID', Req, Context) ->
Process = fun() -> Process = fun() ->
case capi_party:get_claim(PartyID, genlib:to_int(ClaimID), Context) of case capi_party:get_claim(PartyID, genlib:to_int(ClaimID), Context) of
{ok, Claim} -> {ok, Claim} ->
case is_wallet_claim(Claim) of %% filter this out
true -> _ = is_wallet_claim(Claim) andalso capi_handler:respond(general_error(404, <<"Claim not found">>)),
%% filter this out {ok, {200, #{}, decode_claim(Claim)}};
{ok, general_error(404, <<"Claim not found">>)};
false ->
{ok, {200, #{}, decode_claim(Claim)}}
end;
{error, #payproc_ClaimNotFound{}} -> {error, #payproc_ClaimNotFound{}} ->
{ok, general_error(404, <<"Claim not found">>)} {ok, general_error(404, <<"Claim not found">>)}
end end
@ -64,30 +60,27 @@ prepare(OperationID = 'CreateClaim', Req, Context) ->
case capi_party:create_claim(PartyID, Changeset, Context) of case capi_party:create_claim(PartyID, Changeset, Context) of
{ok, Claim} -> {ok, Claim} ->
{ok, {201, #{}, decode_claim(Claim)}}; {ok, {201, #{}, decode_claim(Claim)}};
{error, Exception} -> {error, #payproc_InvalidPartyStatus{}} ->
case Exception of {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
#payproc_InvalidPartyStatus{} -> {error, #payproc_ChangesetConflict{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('changesetConflict', <<"Changeset conflict">>)};
#payproc_ChangesetConflict{} -> {error, #payproc_InvalidChangeset{}} ->
{ok, logic_error(changesetConflict, <<"Changeset conflict">>)}; {ok, logic_error('invalidChangeset', <<"Invalid changeset">>)};
#payproc_InvalidChangeset{} -> {error, #'InvalidRequest'{errors = Errors}} ->
{ok, logic_error(invalidChangeset, <<"Invalid changeset">>)}; FormattedErrors = capi_handler_utils:format_request_errors(Errors),
#'InvalidRequest'{errors = Errors} -> {ok, logic_error('invalidRequest', FormattedErrors)}
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error(invalidRequest, FormattedErrors)}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}} {ok, #{authorize => Authorize, process => Process}}
catch catch
throw:{encode_contract_modification, adjustment_creation_not_supported} -> throw:{encode_contract_modification, adjustment_creation_not_supported} ->
ErrorResp = logic_error( ErrorResp = logic_error(
invalidChangeset, 'invalidChangeset',
<<"Contract adjustment creation not supported">> <<"Contract adjustment creation not supported">>
), ),
capi_handler:respond(ErrorResp); capi_handler:respond(ErrorResp);
throw:{encode_residence, invalid_residence} -> throw:{encode_residence, invalid_residence} ->
capi_handler:respond(logic_error(invalidRequest, <<"Invalid residence">>)) capi_handler:respond(logic_error('invalidRequest', <<"Invalid residence">>))
end; end;
% TODO disabled temporary, exception handling must be fixed befor enabling % TODO disabled temporary, exception handling must be fixed befor enabling
% prepare(OperationID = 'UpdateClaimByID', Req, Context) -> % prepare(OperationID = 'UpdateClaimByID', Req, Context) ->
@ -130,17 +123,14 @@ prepare(OperationID = 'RevokeClaimByID', Req, Context) ->
case Result of case Result of
ok -> ok ->
{ok, {204, #{}, undefined}}; {ok, {204, #{}, undefined}};
{error, Exception} -> {error, #payproc_InvalidPartyStatus{}} ->
case Exception of {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
#payproc_InvalidPartyStatus{} -> {error, #payproc_ClaimNotFound{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, general_error(404, <<"Claim not found">>)};
#payproc_ClaimNotFound{} -> {error, #payproc_InvalidClaimStatus{}} ->
{ok, general_error(404, <<"Claim not found">>)}; {ok, logic_error('invalidClaimStatus', <<"Invalid claim status">>)};
#payproc_InvalidClaimStatus{} -> {error, #payproc_InvalidClaimRevision{}} ->
{ok, logic_error(invalidClaimStatus, <<"Invalid claim status">>)}; {ok, logic_error('invalidClaimRevision', <<"Invalid claim revision">>)}
#payproc_InvalidClaimRevision{} ->
{ok, logic_error(invalidClaimRevision, <<"Invalid claim revision">>)}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};

View File

@ -56,13 +56,9 @@ prepare(OperationID = 'GetContractAdjustments', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end, end,
Process = fun() -> Process = fun() ->
case capi_party:get_contract(PartyID, ContractID, Context) of Contract = get_contract_or_fail(PartyID, ContractID, Context),
{ok, #domain_Contract{adjustments = Adjustments}} -> Resp = [decode_contract_adjustment(A) || A <- Contract#domain_Contract.adjustments],
Resp = [decode_contract_adjustment(A) || A <- Adjustments], {ok, {200, #{}, Resp}}
{ok, {200, #{}, Resp}};
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetContractAdjustmentByID', Req, Context) -> prepare(OperationID = 'GetContractAdjustmentByID', Req, Context) ->
@ -75,17 +71,14 @@ prepare(OperationID = 'GetContractAdjustmentByID', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end, end,
Process = fun() -> Process = fun() ->
case capi_party:get_contract(PartyID, ContractID, Context) of Contract = get_contract_or_fail(PartyID, ContractID, Context),
{ok, #domain_Contract{adjustments = Adjustments}} -> AdjustmentID = maps:get('adjustmentID', Req),
AdjustmentID = maps:get('adjustmentID', Req), Adjustments = Contract#domain_Contract.adjustments,
case lists:keyfind(AdjustmentID, #domain_ContractAdjustment.id, Adjustments) of case lists:keyfind(AdjustmentID, #domain_ContractAdjustment.id, Adjustments) of
#domain_ContractAdjustment{} = A -> #domain_ContractAdjustment{} = A ->
{ok, {200, #{}, decode_contract_adjustment(A)}}; {ok, {200, #{}, decode_contract_adjustment(A)}};
false -> false ->
{ok, general_error(404, <<"Adjustment not found">>)} {ok, general_error(404, <<"Adjustment not found">>)}
end;
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -118,14 +111,10 @@ prepare(OperationID = 'GetContractByIDForParty', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end, end,
Process = fun() -> Process = fun() ->
case capi_party:get_contract(PartyID, ContractID, Context) of Contract = get_contract_or_fail(PartyID, ContractID, Context),
{ok, Contract} -> % Получение Party требуется для извлечения domain_Party.contractors
% Получение Party требуется для извлечения domain_Party.contractors {ok, Party} = capi_party:get_party(PartyID, Context),
{ok, Party} = capi_party:get_party(PartyID, Context), {ok, {200, #{}, decode_contract(Contract, Party#domain_Party.contractors)}}
{ok, {200, #{}, decode_contract(Contract, Party#domain_Party.contractors)}};
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetContractAdjustmentsForParty', Req, Context) -> prepare(OperationID = 'GetContractAdjustmentsForParty', Req, Context) ->
@ -138,17 +127,9 @@ prepare(OperationID = 'GetContractAdjustmentsForParty', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end, end,
Process = fun() -> Process = fun() ->
case capi_party:get_contract(PartyID, ContractID, Context) of Contract = get_contract_or_fail(PartyID, ContractID, Context),
{ok, #domain_Contract{adjustments = Adjustments}} -> Resp = [decode_contract_adjustment(A) || A <- Contract#domain_Contract.adjustments],
Resp = [decode_contract_adjustment(A) || A <- Adjustments], {ok, {200, #{}, Resp}}
{ok, {200, #{}, Resp}};
{error, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)};
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetContractAdjustmentByIDForParty', Req, Context) -> prepare(OperationID = 'GetContractAdjustmentByIDForParty', Req, Context) ->
@ -161,27 +142,32 @@ prepare(OperationID = 'GetContractAdjustmentByIDForParty', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end, end,
Process = fun() -> Process = fun() ->
case capi_party:get_contract(PartyID, ContractID, Context) of Contract = get_contract_or_fail(PartyID, ContractID, Context),
{ok, #domain_Contract{adjustments = Adjustments}} -> AdjustmentID = maps:get('adjustmentID', Req),
AdjustmentID = maps:get('adjustmentID', Req), Adjustments = Contract#domain_Contract.adjustments,
case lists:keyfind(AdjustmentID, #domain_ContractAdjustment.id, Adjustments) of case lists:keyfind(AdjustmentID, #domain_ContractAdjustment.id, Adjustments) of
#domain_ContractAdjustment{} = A -> #domain_ContractAdjustment{} = A ->
{ok, {200, #{}, decode_contract_adjustment(A)}}; {ok, {200, #{}, decode_contract_adjustment(A)}};
false -> false ->
{ok, general_error(404, <<"Adjustment not found">>)} {ok, general_error(404, <<"Adjustment not found">>)}
end;
{error, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)};
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(_OperationID, _Req, _Context) -> prepare(_OperationID, _Req, _Context) ->
{error, noimpl}. {error, noimpl}.
get_contract_or_fail(PartyID, ContractID, Context) ->
case capi_party:get_contract(PartyID, ContractID, Context) of
{ok, Contract} ->
Contract;
{error, #payproc_InvalidUser{}} ->
capi_handler:respond(general_error(404, <<"Party not found">>));
{error, #payproc_PartyNotFound{}} ->
capi_handler:respond(general_error(404, <<"Party not found">>));
{error, #payproc_ContractNotFound{}} ->
capi_handler:respond(general_error(404, <<"Contract not found">>))
end.
%% %%
decode_contracts_map(Contracts, Contractors) -> decode_contracts_map(Contracts, Contractors) ->

View File

@ -28,7 +28,7 @@ process_request('GetCountries', _Req, Context) ->
Countries = unwrap(capi_domain:get_objects_by_type(country, Context)), Countries = unwrap(capi_domain:get_objects_by_type(country, Context)),
{ok, {200, #{}, lists:map(fun decode_country_object/1, Countries)}}; {ok, {200, #{}, lists:map(fun decode_country_object/1, Countries)}};
process_request('GetCountryByID', Req, Context) -> process_request('GetCountryByID', Req, Context) ->
CountryCode = capi_coder_utils:encode_country_code(maps:get(countryID, Req)), CountryCode = capi_coder_utils:encode_country_code(maps:get('countryID', Req)),
Ref = {country, #domain_CountryRef{id = CountryCode}}, Ref = {country, #domain_CountryRef{id = CountryCode}},
case capi_domain:get(Ref, Context) of case capi_domain:get(Ref, Context) of
{ok, CountryObject} -> {ok, CountryObject} ->

View File

@ -31,21 +31,21 @@ prepare('CreateCustomer' = OperationID, Req, Context) ->
{ok, Customer} -> {ok, Customer} ->
{ok, {201, #{}, make_customer_and_token(Customer, Context)}}; {ok, {201, #{}, make_customer_and_token(Customer, Context)}};
{exception, #payproc_InvalidUser{}} -> {exception, #payproc_InvalidUser{}} ->
{ok, logic_error(invalidPartyID, <<"Party not found">>)}; {ok, logic_error('invalidPartyID', <<"Party not found">>)};
{exception, #payproc_InvalidPartyStatus{}} -> {exception, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error(<<"invalidPartyStatus">>, <<"Invalid party status">>)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
{exception, #payproc_InvalidShopStatus{}} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
{exception, #payproc_ShopNotFound{}} -> {exception, #payproc_ShopNotFound{}} ->
{ok, logic_error(invalidShopID, <<"Shop not found">>)}; {ok, logic_error('invalidShopID', <<"Shop not found">>)};
{exception, #payproc_PartyNotFound{}} -> {exception, #payproc_PartyNotFound{}} ->
{ok, logic_error(<<"invalidPartyID">>, <<"Party not found">>)}; {ok, logic_error('invalidPartyID', <<"Party not found">>)};
{exception, #payproc_OperationNotPermitted{}} -> {exception, #payproc_OperationNotPermitted{}} ->
{ok, logic_error(operationNotPermitted, <<"Operation not permitted">>)} {ok, logic_error('operationNotPermitted', <<"Operation not permitted">>)}
end end
catch catch
throw:{external_id_conflict, ID, UsedExternalID, _Schema} -> throw:{external_id_conflict, ID, UsedExternalID, _Schema} ->
{ok, logic_error(externalIDConflict, {ID, UsedExternalID})} {ok, logic_error('externalIDConflict', {ID, UsedExternalID})}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -87,9 +87,9 @@ prepare('DeleteCustomer' = OperationID, Req, Context) ->
{exception, #payproc_CustomerNotFound{}} -> {exception, #payproc_CustomerNotFound{}} ->
{ok, general_error(404, <<"Customer not found">>)}; {ok, general_error(404, <<"Customer not found">>)};
{exception, #payproc_InvalidPartyStatus{}} -> {exception, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
{exception, #payproc_InvalidShopStatus{}} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)} {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -114,7 +114,7 @@ prepare('CreateCustomerAccessToken' = OperationID, Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('CreateBinding' = OperationID, Req, Context) -> prepare('CreateBinding' = OperationID, Req, Context) ->
CustomerID = maps:get(customerID, Req), CustomerID = maps:get('customerID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
{operation, #{id => OperationID, customer => CustomerID}}, {operation, #{id => OperationID, customer => CustomerID}},
@ -149,28 +149,28 @@ prepare('CreateBinding' = OperationID, Req, Context) ->
end, end,
case Result of case Result of
{ok, CustomerBinding} -> {ok, CustomerBinding} ->
{ok, {201, #{}, decode_customer_binding(CustomerBinding, Context)}}; {ok, {201, #{}, decode_customer_binding(CustomerBinding)}};
{exception, #payproc_InvalidUser{}} -> {exception, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Customer not found">>)}; {ok, general_error(404, <<"Customer not found">>)};
{exception, #payproc_CustomerNotFound{}} -> {exception, #payproc_CustomerNotFound{}} ->
{ok, general_error(404, <<"Customer not found">>)}; {ok, general_error(404, <<"Customer not found">>)};
{exception, #payproc_InvalidPartyStatus{}} -> {exception, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
{exception, #payproc_InvalidShopStatus{}} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
{exception, #payproc_InvalidContractStatus{}} -> {exception, #payproc_InvalidContractStatus{}} ->
{ok, logic_error(invalidRequest, <<"Invalid contract status">>)}; {ok, logic_error('invalidRequest', <<"Invalid contract status">>)};
{exception, #payproc_OperationNotPermitted{}} -> {exception, #payproc_OperationNotPermitted{}} ->
{ok, logic_error(operationNotPermitted, <<"Operation not permitted">>)}; {ok, logic_error('operationNotPermitted', <<"Operation not permitted">>)};
{error, invalid_payment_session} -> {error, invalid_payment_session} ->
{ok, logic_error(invalidPaymentSession, <<"Specified payment session is invalid">>)}; {ok, logic_error('invalidPaymentSession', <<"Specified payment session is invalid">>)};
{error, {external_id_conflict, ID, UsedExternalID, _Schema}} -> {error, {external_id_conflict, ID, UsedExternalID, _Schema}} ->
{ok, logic_error(externalIDConflict, {ID, UsedExternalID})} {ok, logic_error('externalIDConflict', {ID, UsedExternalID})}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('GetBindings' = OperationID, Req, Context) -> prepare('GetBindings' = OperationID, Req, Context) ->
CustomerID = maps:get(customerID, Req), CustomerID = maps:get('customerID', Req),
Customer = map_service_result(get_customer_by_id(CustomerID, Context)), Customer = map_service_result(get_customer_by_id(CustomerID, Context)),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -180,17 +180,13 @@ prepare('GetBindings' = OperationID, Req, Context) ->
{ok, mask_customer_notfound(capi_auth:authorize_operation(Prototypes, Context))} {ok, mask_customer_notfound(capi_auth:authorize_operation(Prototypes, Context))}
end, end,
Process = fun() -> Process = fun() ->
case Customer of _ = capi_handler:respond_if_undefined(Customer, general_error(404, <<"Customer not found">>)),
#payproc_Customer{bindings = Bindings} -> {ok, {200, #{}, [decode_customer_binding(B) || B <- Customer#payproc_Customer.bindings]}}
{ok, {200, #{}, [decode_customer_binding(B, Context) || B <- Bindings]}};
undefined ->
{ok, general_error(404, <<"Customer not found">>)}
end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('GetBinding' = OperationID, Req, Context) -> prepare('GetBinding' = OperationID, Req, Context) ->
CustomerID = maps:get(customerID, Req), CustomerID = maps:get('customerID', Req),
CustomerBindingID = maps:get(customerBindingID, Req), CustomerBindingID = maps:get('customerBindingID', Req),
Customer = map_service_result(get_customer_by_id(CustomerID, Context)), Customer = map_service_result(get_customer_by_id(CustomerID, Context)),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -200,21 +196,18 @@ prepare('GetBinding' = OperationID, Req, Context) ->
{ok, mask_customer_notfound(capi_auth:authorize_operation(Prototypes, Context))} {ok, mask_customer_notfound(capi_auth:authorize_operation(Prototypes, Context))}
end, end,
Process = fun() -> Process = fun() ->
case Customer of _ = capi_handler:respond_if_undefined(Customer, general_error(404, <<"Customer not found">>)),
#payproc_Customer{bindings = Bindings} -> Bindings = Customer#payproc_Customer.bindings,
case lists:keyfind(CustomerBindingID, #payproc_CustomerBinding.id, Bindings) of case lists:keyfind(CustomerBindingID, #payproc_CustomerBinding.id, Bindings) of
#payproc_CustomerBinding{} = B -> #payproc_CustomerBinding{} = B ->
{ok, {200, #{}, decode_customer_binding(B, Context)}}; {ok, {200, #{}, decode_customer_binding(B)}};
false -> false ->
{ok, general_error(404, <<"Customer binding not found">>)} {ok, general_error(404, <<"Customer binding not found">>)}
end;
undefined ->
{ok, general_error(404, <<"Customer not found">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('GetCustomerEvents' = OperationID, Req, Context) -> prepare('GetCustomerEvents' = OperationID, Req, Context) ->
CustomerID = maps:get(customerID, Req), CustomerID = maps:get('customerID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
{operation, #{id => OperationID, customer => CustomerID}}, {operation, #{id => OperationID, customer => CustomerID}},
@ -230,11 +223,10 @@ prepare('GetCustomerEvents' = OperationID, Req, Context) ->
) )
end, end,
Result = capi_handler_utils:collect_events( Result = capi_handler_utils:collect_events(
maps:get(limit, Req), maps:get('limit', Req),
genlib_map:get(eventID, Req), genlib_map:get('eventID', Req),
GetterFun, GetterFun,
fun decode_customer_event/2, fun decode_customer_event/1
undefined
), ),
case Result of case Result of
{ok, Events} when is_list(Events) -> {ok, Events} when is_list(Events) ->
@ -249,7 +241,7 @@ prepare('GetCustomerEvents' = OperationID, Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('GetCustomerPaymentMethods' = OperationID, Req, Context) -> prepare('GetCustomerPaymentMethods' = OperationID, Req, Context) ->
CustomerID = maps:get(customerID, Req), CustomerID = maps:get('customerID', Req),
Customer = map_service_result(get_customer_by_id(CustomerID, Context)), Customer = map_service_result(get_customer_by_id(CustomerID, Context)),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -270,13 +262,10 @@ prepare('GetCustomerPaymentMethods' = OperationID, Req, Context) ->
PaymentMethods1 = capi_utils:deduplicate_payment_methods(PaymentMethods0), PaymentMethods1 = capi_utils:deduplicate_payment_methods(PaymentMethods0),
PaymentMethods = capi_handler_utils:emplace_token_provider_data(Customer, PaymentMethods1, Context), PaymentMethods = capi_handler_utils:emplace_token_provider_data(Customer, PaymentMethods1, Context),
{ok, {200, #{}, PaymentMethods}}; {ok, {200, #{}, PaymentMethods}};
{exception, Exception} -> {exception, #payproc_InvalidUser{}} ->
case Exception of {ok, general_error(404, <<"Customer not found">>)};
#payproc_InvalidUser{} -> {exception, #payproc_CustomerNotFound{}} ->
{ok, general_error(404, <<"Customer not found">>)}; {ok, general_error(404, <<"Customer not found">>)}
#payproc_CustomerNotFound{} ->
{ok, general_error(404, <<"Customer not found">>)}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -377,7 +366,7 @@ encode_payment_tool_token(Token) ->
case capi_utils:deadline_is_reached(ValidUntil) of case capi_utils:deadline_is_reached(ValidUntil) of
true -> true ->
logger:warning("Payment tool token expired: ~p", [capi_utils:deadline_to_binary(ValidUntil)]), logger:warning("Payment tool token expired: ~p", [capi_utils:deadline_to_binary(ValidUntil)]),
capi_handler:respond(logic_error(invalidPaymentToolToken)); capi_handler:respond(logic_error('invalidPaymentToolToken'));
_ -> _ ->
PaymentTool PaymentTool
end; end;
@ -385,7 +374,7 @@ encode_payment_tool_token(Token) ->
encode_legacy_payment_tool_token(Token); encode_legacy_payment_tool_token(Token);
{error, {decryption_failed, Error}} -> {error, {decryption_failed, Error}} ->
logger:warning("Payment tool token decryption failed: ~p", [Error]), logger:warning("Payment tool token decryption failed: ~p", [Error]),
capi_handler:respond(logic_error(invalidPaymentToolToken)) capi_handler:respond(logic_error('invalidPaymentToolToken'))
end. end.
encode_legacy_payment_tool_token(Token) -> encode_legacy_payment_tool_token(Token) ->
@ -393,7 +382,7 @@ encode_legacy_payment_tool_token(Token) ->
capi_handler_encoder:encode_payment_tool(capi_utils:base64url_to_map(Token)) capi_handler_encoder:encode_payment_tool(capi_utils:base64url_to_map(Token))
catch catch
error:badarg -> error:badarg ->
capi_handler:respond(logic_error(invalidPaymentToolToken)) capi_handler:respond(logic_error('invalidPaymentToolToken'))
end. end.
make_customer_and_token(Customer, ProcessingContext) -> make_customer_and_token(Customer, ProcessingContext) ->
@ -418,7 +407,7 @@ decode_customer_status({Status, _}) ->
decode_customer_metadata(Meta) -> decode_customer_metadata(Meta) ->
capi_json_marshalling:unmarshal(Meta). capi_json_marshalling:unmarshal(Meta).
decode_customer_binding(CustomerBinding, Context) -> decode_customer_binding(CustomerBinding) ->
capi_handler_utils:merge_and_compact( capi_handler_utils:merge_and_compact(
#{ #{
<<"id">> => CustomerBinding#payproc_CustomerBinding.id, <<"id">> => CustomerBinding#payproc_CustomerBinding.id,
@ -427,14 +416,14 @@ decode_customer_binding(CustomerBinding, Context) ->
CustomerBinding#payproc_CustomerBinding.payment_resource CustomerBinding#payproc_CustomerBinding.payment_resource
) )
}, },
decode_customer_binding_status(CustomerBinding#payproc_CustomerBinding.status, Context) decode_customer_binding_status(CustomerBinding#payproc_CustomerBinding.status)
). ).
decode_customer_binding_status({Status, StatusInfo}, Context) -> decode_customer_binding_status({Status, StatusInfo}) ->
Error = Error =
case StatusInfo of case StatusInfo of
#payproc_CustomerBindingFailed{failure = OperationFailure} -> #payproc_CustomerBindingFailed{failure = OperationFailure} ->
capi_handler_decoder_utils:decode_operation_failure(OperationFailure, Context); capi_handler_decoder_utils:decode_operation_failure(OperationFailure);
_ -> _ ->
undefined undefined
end, end,
@ -443,8 +432,8 @@ decode_customer_binding_status({Status, StatusInfo}, Context) ->
<<"error">> => Error <<"error">> => Error
}. }.
decode_customer_event(Event = #payproc_Event{source = {customer_id, _}, payload = Payload}, Context) -> decode_customer_event(Event = #payproc_Event{source = {customer_id, _}, payload = Payload}) ->
case decode_customer_changes(Payload, Context) of case decode_customer_changes(Payload) of
[_Something | _] = Changes -> [_Something | _] = Changes ->
{true, #{ {true, #{
<<"id">> => Event#payproc_Event.id, <<"id">> => Event#payproc_Event.id,
@ -455,25 +444,22 @@ decode_customer_event(Event = #payproc_Event{source = {customer_id, _}, payload
false false
end. end.
decode_customer_changes({customer_changes, CustomerChanges}, Context) -> decode_customer_changes({customer_changes, CustomerChanges}) ->
lists:filtermap( lists:filtermap(fun decode_customer_change/1, CustomerChanges).
fun(V) -> decode_customer_change(V, Context) end,
CustomerChanges
).
decode_customer_change({customer_binding_changed, CustomerBindingChanged}, Context) -> decode_customer_change({customer_binding_changed, CustomerBindingChanged}) ->
#payproc_CustomerBindingChanged{id = BindingID, payload = Payload} = CustomerBindingChanged, #payproc_CustomerBindingChanged{id = BindingID, payload = Payload} = CustomerBindingChanged,
decode_customer_binding_change(BindingID, Payload, Context); decode_customer_binding_change(BindingID, Payload);
decode_customer_change(_, _) -> decode_customer_change(_) ->
false. false.
decode_customer_binding_change(_, {started, Start}, Context) -> decode_customer_binding_change(_, {started, Start}) ->
#payproc_CustomerBindingStarted{binding = CustomerBinding} = Start, #payproc_CustomerBindingStarted{binding = CustomerBinding} = Start,
{true, #{ {true, #{
<<"changeType">> => <<"CustomerBindingStarted">>, <<"changeType">> => <<"CustomerBindingStarted">>,
<<"customerBinding">> => decode_customer_binding(CustomerBinding, Context) <<"customerBinding">> => decode_customer_binding(CustomerBinding)
}}; }};
decode_customer_binding_change(BindingID, {status_changed, StatusChange}, Context) -> decode_customer_binding_change(BindingID, {status_changed, StatusChange}) ->
#payproc_CustomerBindingStatusChanged{status = Status} = StatusChange, #payproc_CustomerBindingStatusChanged{status = Status} = StatusChange,
{true, {true,
capi_handler_utils:merge_and_compact( capi_handler_utils:merge_and_compact(
@ -481,9 +467,9 @@ decode_customer_binding_change(BindingID, {status_changed, StatusChange}, Contex
<<"changeType">> => <<"CustomerBindingStatusChanged">>, <<"changeType">> => <<"CustomerBindingStatusChanged">>,
<<"customerBindingID">> => BindingID <<"customerBindingID">> => BindingID
}, },
decode_customer_binding_status(Status, Context) decode_customer_binding_status(Status)
)}; )};
decode_customer_binding_change(BindingID, {interaction_requested, InteractionRequest}, _) -> decode_customer_binding_change(BindingID, {interaction_requested, InteractionRequest}) ->
#payproc_CustomerBindingInteractionRequested{interaction = UserInteraction} = InteractionRequest, #payproc_CustomerBindingInteractionRequested{interaction = UserInteraction} = InteractionRequest,
{true, #{ {true, #{
<<"changeType">> => <<"CustomerBindingInteractionRequested">>, <<"changeType">> => <<"CustomerBindingInteractionRequested">>,

View File

@ -8,7 +8,7 @@
-export([decode_invoice_payment/3]). -export([decode_invoice_payment/3]).
-export([decode_payment/3]). -export([decode_payment/3]).
-export([decode_chargeback/2]). -export([decode_chargeback/2]).
-export([decode_refund/2]). -export([decode_refund/1]).
-export([decode_invoice/1]). -export([decode_invoice/1]).
-export([decode_invoice_cart/1]). -export([decode_invoice_cart/1]).
-export([decode_invoice_bank_account/1]). -export([decode_invoice_bank_account/1]).
@ -16,7 +16,7 @@
-export([decode_payment_methods/1]). -export([decode_payment_methods/1]).
-export([decode_payment_status/2]). -export([decode_payment_status/2]).
-export([decode_payment_operation_failure/2]). -export([decode_payment_operation_failure/2]).
-export([decode_refund_status/2]). -export([decode_refund_status/1]).
-export([decode_recurrent_parent/1]). -export([decode_recurrent_parent/1]).
-export([decode_make_recurrent/1]). -export([decode_make_recurrent/1]).
@ -317,9 +317,9 @@ payment_error_client_maping({authorization_failed, {insufficient_funds, _}}) ->
payment_error_client_maping(_) -> payment_error_client_maping(_) ->
<<"PaymentRejected">>. <<"PaymentRejected">>.
-spec decode_refund(capi_handler_encoder:encode_data(), processing_context()) -> -spec decode_refund(capi_handler_encoder:encode_data()) ->
decode_data(). decode_data().
decode_refund(Refund, Context) -> decode_refund(Refund) ->
#domain_Cash{amount = Amount, currency = Currency} = Refund#domain_InvoicePaymentRefund.cash, #domain_Cash{amount = Amount, currency = Currency} = Refund#domain_InvoicePaymentRefund.cash,
capi_handler_utils:merge_and_compact( capi_handler_utils:merge_and_compact(
#{ #{
@ -331,15 +331,15 @@ decode_refund(Refund, Context) ->
<<"externalID">> => Refund#domain_InvoicePaymentRefund.external_id, <<"externalID">> => Refund#domain_InvoicePaymentRefund.external_id,
<<"allocation">> => capi_allocation:decode(Refund#domain_InvoicePaymentRefund.allocation) <<"allocation">> => capi_allocation:decode(Refund#domain_InvoicePaymentRefund.allocation)
}, },
decode_refund_status(Refund#domain_InvoicePaymentRefund.status, Context) decode_refund_status(Refund#domain_InvoicePaymentRefund.status)
). ).
-spec decode_refund_status({atom(), _}, processing_context()) -> decode_data(). -spec decode_refund_status({atom(), _}) -> decode_data().
decode_refund_status({Status, StatusInfo}, Context) -> decode_refund_status({Status, StatusInfo}) ->
Error = Error =
case StatusInfo of case StatusInfo of
#domain_InvoicePaymentRefundFailed{failure = OperationFailure} -> #domain_InvoicePaymentRefundFailed{failure = OperationFailure} ->
capi_handler_decoder_utils:decode_operation_failure(OperationFailure, Context); capi_handler_decoder_utils:decode_operation_failure(OperationFailure);
_ -> _ ->
undefined undefined
end, end,
@ -452,8 +452,6 @@ decode_invoice_bank_account(undefined) ->
-spec decode_invoice_line_tax_mode(map()) -> decode_data() | undefined. -spec decode_invoice_line_tax_mode(map()) -> decode_data() | undefined.
decode_invoice_line_tax_mode(#{<<"TaxMode">> := {str, TM}}) -> decode_invoice_line_tax_mode(#{<<"TaxMode">> := {str, TM}}) ->
%% for more info about taxMode look here:
%% https://github.com/rbkmoney/starrys/blob/master/docs/settings.md
#{ #{
<<"type">> => <<"InvoiceLineTaxVAT">>, <<"type">> => <<"InvoiceLineTaxVAT">>,
<<"rate">> => TM <<"rate">> => TM

View File

@ -10,10 +10,13 @@
-export([decode_bank_card_bin/1]). -export([decode_bank_card_bin/1]).
-export([decode_last_digits/1]). -export([decode_last_digits/1]).
-export([decode_masked_pan/2]). -export([decode_masked_pan/2]).
-export([decode_operation_failure/2]). -export([decode_operation_failure/1]).
-export([decode_category_ref/1]). -export([decode_category_ref/1]).
-export([decode_context/1]). -export([decode_context/1]).
-export([decode_optional/2]). -export([decode_optional/2]).
-export([decode_metadata/1]).
-export([decode_namespaced_metadata/1]).
-export([convert_crypto_currency_to_swag/1]). -export([convert_crypto_currency_to_swag/1]).
-export_type([decode_data/0]). -export_type([decode_data/0]).
@ -61,10 +64,10 @@ decode_last_digits(MaskedPan) when byte_size(MaskedPan) > ?MASKED_PAN_MAX_LENGTH
decode_last_digits(MaskedPan) -> decode_last_digits(MaskedPan) ->
MaskedPan. MaskedPan.
-spec decode_operation_failure(_, _) -> decode_data(). -spec decode_operation_failure(_) -> decode_data().
decode_operation_failure({operation_timeout, _}, _) -> decode_operation_failure({operation_timeout, _}) ->
logic_error(timeout, <<"timeout">>); logic_error(timeout, <<"timeout">>);
decode_operation_failure({failure, #domain_Failure{code = Code, reason = Reason}}, _) -> decode_operation_failure({failure, #domain_Failure{code = Code, reason = Reason}}) ->
logic_error(Code, Reason). logic_error(Code, Reason).
logic_error(Code, Message) -> logic_error(Code, Message) ->
@ -87,6 +90,17 @@ decode_optional(Arg, DecodeFun) when Arg /= undefined ->
decode_optional(undefined, _) -> decode_optional(undefined, _) ->
undefined. undefined.
-spec decode_metadata(dmsl_domain_thrift:'Metadata'()) -> capi_json_marshalling:value().
decode_metadata(MD) ->
capi_json_marshalling:unmarshal(MD).
-spec decode_namespaced_metadata(#{NS => dmsl_domain_thrift:'Metadata'()}) ->
#{NS => capi_json_marshalling:value()}
when
NS :: binary().
decode_namespaced_metadata(NamespacedMD) ->
maps:map(fun(_NS, MD) -> decode_metadata(MD) end, NamespacedMD).
-spec convert_crypto_currency_to_swag(atom()) -> binary(). -spec convert_crypto_currency_to_swag(atom()) -> binary().
convert_crypto_currency_to_swag(bitcoin_cash) -> convert_crypto_currency_to_swag(bitcoin_cash) ->
<<"bitcoinCash">>; <<"bitcoinCash">>;

View File

@ -204,8 +204,6 @@ encode_invoice_line_meta(Line) ->
end. end.
encode_invoice_line_tax_mode(#{<<"type">> := <<"InvoiceLineTaxVAT">>} = TaxMode) -> encode_invoice_line_tax_mode(#{<<"type">> := <<"InvoiceLineTaxVAT">>} = TaxMode) ->
%% for more info about taxMode look here:
%% https://github.com/rbkmoney/starrys/blob/master/docs/settings.md
genlib_map:get(<<"rate">>, TaxMode). genlib_map:get(<<"rate">>, TaxMode).
-spec encode_invoice_bank_account(request_data()) -> dmsl_domain_thrift:'InvoiceBankAccount'() | undefined. -spec encode_invoice_bank_account(request_data()) -> dmsl_domain_thrift:'InvoiceBankAccount'() | undefined.

View File

@ -1,48 +0,0 @@
-module(capi_handler_geo).
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-behaviour(capi_handler).
-export([prepare/3]).
-import(capi_handler_utils, [logic_error/2]).
-spec prepare(
OperationID :: capi_handler:operation_id(),
Req :: capi_handler:request_data(),
Context :: capi_handler:processing_context()
) -> {ok, capi_handler:request_state()} | {error, noimpl}.
prepare('GetLocationsNames' = OperationID, Req, Context) ->
Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID}}],
{ok, capi_auth:authorize_operation(Prototypes, Context)}
end,
Process = fun() ->
GeoIDs = ordsets:from_list(maps:get('geoIDs', Req)),
Language = maps:get('language', Req),
Call = {geo_ip_service, 'GetLocationName', {GeoIDs, Language}},
case capi_handler_utils:service_call(Call, Context) of
{ok, LocationNames} ->
PreparedLocationNames = maps:fold(
fun(GeoID, Name, Acc) -> [decode_location_name(GeoID, Name) | Acc] end,
[],
LocationNames
),
{ok, {200, #{}, PreparedLocationNames}};
{exception, #'InvalidRequest'{errors = Errors}} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error(invalidRequest, FormattedErrors)}
end
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(_OperationID, _Req, _Context) ->
{error, noimpl}.
%%
decode_location_name(GeoID, Name) ->
#{
<<"geoID">> => GeoID,
<<"name">> => Name
}.

View File

@ -36,27 +36,24 @@ prepare('CreateInvoiceTemplate' = OperationID, Req, Context) ->
of of
{ok, InvoiceTpl} -> {ok, InvoiceTpl} ->
{ok, {201, #{}, make_invoice_tpl_and_token(InvoiceTpl, Context)}}; {ok, {201, #{}, make_invoice_tpl_and_token(InvoiceTpl, Context)}};
{exception, Exception} -> {exception, #'InvalidRequest'{errors = Errors}} ->
case Exception of FormattedErrors = capi_handler_utils:format_request_errors(Errors),
#'InvalidRequest'{errors = Errors} -> {ok, logic_error('invalidRequest', FormattedErrors)};
FormattedErrors = capi_handler_utils:format_request_errors(Errors), {exception, #payproc_InvalidUser{}} ->
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidPartyID', <<"Party not found">>)};
#payproc_InvalidUser{} -> {exception, #payproc_ShopNotFound{}} ->
{ok, logic_error(invalidPartyID, <<"Party not found">>)}; {ok, logic_error('invalidShopID', <<"Shop not found">>)};
#payproc_ShopNotFound{} -> {exception, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error(invalidShopID, <<"Shop not found">>)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
#payproc_InvalidPartyStatus{} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)}
#payproc_InvalidShopStatus{} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}
end
catch catch
throw:invoice_cart_empty -> throw:invoice_cart_empty ->
{ok, logic_error(invalidInvoiceCart, <<"Wrong size. Path to item: cart">>)}; {ok, logic_error('invalidInvoiceCart', <<"Wrong size. Path to item: cart">>)};
throw:zero_invoice_lifetime -> throw:zero_invoice_lifetime ->
{ok, logic_error(invalidRequest, <<"Lifetime cannot be zero">>)}; {ok, logic_error('invalidRequest', <<"Lifetime cannot be zero">>)};
throw:{external_id_conflict, ID, UsedExternalID, _Schema} -> throw:{external_id_conflict, ID, UsedExternalID, _Schema} ->
{ok, logic_error(externalIDConflict, {ID, UsedExternalID})} {ok, logic_error('externalIDConflict', {ID, UsedExternalID})}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -94,22 +91,19 @@ prepare('UpdateInvoiceTemplate' = OperationID, Req, Context) ->
of of
{ok, UpdatedInvoiceTpl} -> {ok, UpdatedInvoiceTpl} ->
{ok, {200, #{}, decode_invoice_tpl(UpdatedInvoiceTpl)}}; {ok, {200, #{}, decode_invoice_tpl(UpdatedInvoiceTpl)}};
{exception, Exception} -> {exception, #payproc_InvalidUser{}} ->
case Exception of {ok, general_error(404, <<"Invoice Template not found">>)};
#payproc_InvalidUser{} -> {exception, #'InvalidRequest'{errors = Errors}} ->
{ok, general_error(404, <<"Invoice Template not found">>)}; FormattedErrors = capi_handler_utils:format_request_errors(Errors),
#'InvalidRequest'{errors = Errors} -> {ok, logic_error('invalidRequest', FormattedErrors)};
FormattedErrors = capi_handler_utils:format_request_errors(Errors), {exception, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
#payproc_InvalidPartyStatus{} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
#payproc_InvalidShopStatus{} -> {exception, #payproc_InvoiceTemplateNotFound{}} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; {ok, general_error(404, <<"Invoice Template not found">>)};
#payproc_InvoiceTemplateNotFound{} -> {exception, #payproc_InvoiceTemplateRemoved{}} ->
{ok, general_error(404, <<"Invoice Template not found">>)}; {ok, general_error(404, <<"Invoice Template not found">>)}
#payproc_InvoiceTemplateRemoved{} ->
{ok, general_error(404, <<"Invoice Template not found">>)}
end
catch catch
throw:#payproc_InvalidUser{} -> throw:#payproc_InvalidUser{} ->
{ok, general_error(404, <<"Invoice Template not found">>)}; {ok, general_error(404, <<"Invoice Template not found">>)};
@ -118,9 +112,9 @@ prepare('UpdateInvoiceTemplate' = OperationID, Req, Context) ->
throw:#payproc_InvoiceTemplateRemoved{} -> throw:#payproc_InvoiceTemplateRemoved{} ->
{ok, general_error(404, <<"Invoice Template not found">>)}; {ok, general_error(404, <<"Invoice Template not found">>)};
throw:invoice_cart_empty -> throw:invoice_cart_empty ->
{ok, logic_error(invalidInvoiceCart, <<"Wrong size. Path to item: cart">>)}; {ok, logic_error('invalidInvoiceCart', <<"Wrong size. Path to item: cart">>)};
throw:zero_invoice_lifetime -> throw:zero_invoice_lifetime ->
{ok, logic_error(invalidRequest, <<"Lifetime cannot be zero">>)} {ok, logic_error('invalidRequest', <<"Lifetime cannot be zero">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -139,19 +133,16 @@ prepare('DeleteInvoiceTemplate' = OperationID, Req, Context) ->
case capi_handler_utils:service_call_with([user_info], Call, Context) of case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _R} -> {ok, _R} ->
{ok, {204, #{}, undefined}}; {ok, {204, #{}, undefined}};
{exception, Exception} -> {exception, #payproc_InvalidUser{}} ->
case Exception of {ok, general_error(404, <<"Invoice Template not found">>)};
#payproc_InvalidUser{} -> {exception, #payproc_InvalidPartyStatus{}} ->
{ok, general_error(404, <<"Invoice Template not found">>)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
#payproc_InvalidPartyStatus{} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
#payproc_InvalidShopStatus{} -> {exception, #payproc_InvoiceTemplateNotFound{}} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; {ok, general_error(404, <<"Invoice Template not found">>)};
#payproc_InvoiceTemplateNotFound{} -> {exception, #payproc_InvoiceTemplateRemoved{}} ->
{ok, general_error(404, <<"Invoice Template not found">>)}; {ok, general_error(404, <<"Invoice Template not found">>)}
#payproc_InvoiceTemplateRemoved{} ->
{ok, general_error(404, <<"Invoice Template not found">>)}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -173,31 +164,28 @@ prepare('CreateInvoiceWithTemplate' = OperationID, Req, Context) ->
try create_invoice(PartyID, InvoiceTplID, InvoiceParams, Context, OperationID) of try create_invoice(PartyID, InvoiceTplID, InvoiceParams, Context, OperationID) of
{ok, #'payproc_Invoice'{invoice = Invoice}} -> {ok, #'payproc_Invoice'{invoice = Invoice}} ->
{ok, {201, #{}, capi_handler_decoder_invoicing:make_invoice_and_token(Invoice, Context)}}; {ok, {201, #{}, capi_handler_decoder_invoicing:make_invoice_and_token(Invoice, Context)}};
{exception, Reason} -> {exception, #payproc_InvalidUser{}} ->
case Reason of {ok, general_error(404, <<"Invoice Template not found">>)};
#payproc_InvalidUser{} -> {exception, #'InvalidRequest'{errors = Errors}} ->
{ok, general_error(404, <<"Invoice Template not found">>)}; FormattedErrors = capi_handler_utils:format_request_errors(Errors),
#'InvalidRequest'{errors = Errors} -> {ok, logic_error('invalidRequest', FormattedErrors)};
FormattedErrors = capi_handler_utils:format_request_errors(Errors), {exception, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
#payproc_InvalidPartyStatus{} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
#payproc_InvalidShopStatus{} -> {exception, #payproc_InvoiceTemplateNotFound{}} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; {ok, general_error(404, <<"Invoice Template not found">>)};
#payproc_InvoiceTemplateNotFound{} -> {exception, #payproc_InvoiceTemplateRemoved{}} ->
{ok, general_error(404, <<"Invoice Template not found">>)}; {ok, general_error(404, <<"Invoice Template not found">>)};
#payproc_InvoiceTemplateRemoved{} -> {exception, #payproc_InvoiceTermsViolated{}} ->
{ok, general_error(404, <<"Invoice Template not found">>)}; {ok, logic_error('invoiceTermsViolated', <<"Invoice parameters violate contract terms">>)}
#payproc_InvoiceTermsViolated{} ->
{ok, logic_error(invoiceTermsViolated, <<"Invoice parameters violate contract terms">>)}
end
catch catch
throw:{bad_invoice_params, currency_no_amount} -> throw:{bad_invoice_params, currency_no_amount} ->
{ok, logic_error(invalidRequest, <<"Amount is required for the currency">>)}; {ok, logic_error('invalidRequest', <<"Amount is required for the currency">>)};
throw:{bad_invoice_params, amount_no_currency} -> throw:{bad_invoice_params, amount_no_currency} ->
{ok, logic_error(invalidRequest, <<"Currency is required for the amount">>)}; {ok, logic_error('invalidRequest', <<"Currency is required for the amount">>)};
throw:{external_id_conflict, InvoiceID, ExternalID, _Schema} -> throw:{external_id_conflict, InvoiceID, ExternalID, _Schema} ->
{ok, logic_error(externalIDConflict, {InvoiceID, ExternalID})} {ok, logic_error('externalIDConflict', {InvoiceID, ExternalID})}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};

View File

@ -34,46 +34,43 @@ prepare('CreateInvoice' = OperationID, Req, Context) ->
case create_invoice(PartyID, InvoiceParams, Context, OperationID) of case create_invoice(PartyID, InvoiceParams, Context, OperationID) of
{ok, #'payproc_Invoice'{invoice = Invoice}} -> {ok, #'payproc_Invoice'{invoice = Invoice}} ->
{ok, {201, #{}, capi_handler_decoder_invoicing:make_invoice_and_token(Invoice, Context)}}; {ok, {201, #{}, capi_handler_decoder_invoicing:make_invoice_and_token(Invoice, Context)}};
{exception, Exception} -> {exception, #'payproc_InvalidUser'{}} ->
case Exception of {ok, logic_error('invalidPartyID', <<"Party not found">>)};
#'payproc_InvalidUser'{} -> {exception, #'InvalidRequest'{errors = Errors}} ->
{ok, logic_error(invalidPartyID, <<"Party not found">>)}; FormattedErrors = capi_handler_utils:format_request_errors(Errors),
#'InvalidRequest'{errors = Errors} -> {ok, logic_error('invalidRequest', FormattedErrors)};
FormattedErrors = capi_handler_utils:format_request_errors(Errors), {exception, #payproc_ShopNotFound{}} ->
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidShopID', <<"Shop not found">>)};
#payproc_ShopNotFound{} -> {exception, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error(invalidShopID, <<"Shop not found">>)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
#payproc_InvalidPartyStatus{} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
#payproc_InvalidShopStatus{} -> {exception, #payproc_InvoiceTermsViolated{}} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; {ok, logic_error('invoiceTermsViolated', <<"Invoice parameters violate contract terms">>)};
#payproc_InvoiceTermsViolated{} -> {exception, #payproc_AllocationNotAllowed{}} ->
{ok, logic_error(invoiceTermsViolated, <<"Invoice parameters violate contract terms">>)}; {ok, logic_error('allocationNotPermitted', <<"Not allowed">>)};
#payproc_AllocationNotAllowed{} -> {exception, #payproc_AllocationExceededPaymentAmount{}} ->
{ok, logic_error(allocationNotPermitted, <<"Not allowed">>)}; {ok, logic_error('invalidAllocation', <<"Exceeded payment amount">>)};
#payproc_AllocationExceededPaymentAmount{} -> {exception, #payproc_AllocationInvalidTransaction{} = InvalidTransaction} ->
{ok, logic_error(invalidAllocation, <<"Exceeded payment amount">>)}; Message = capi_allocation:transaction_error(InvalidTransaction),
#payproc_AllocationInvalidTransaction{} = InvalidTransaction -> {ok, logic_error('invalidAllocation', Message)}
Message = capi_allocation:transaction_error(InvalidTransaction),
{ok, logic_error(invalidAllocation, Message)}
end
end end
catch catch
throw:invoice_cart_empty -> throw:invoice_cart_empty ->
{ok, logic_error(invalidInvoiceCart, <<"Wrong size. Path to item: cart">>)}; {ok, logic_error('invalidInvoiceCart', <<"Wrong size. Path to item: cart">>)};
throw:invalid_invoice_cost -> throw:invalid_invoice_cost ->
{ok, logic_error(invalidInvoiceCost, <<"Invalid invoice amount">>)}; {ok, logic_error('invalidInvoiceCost', <<"Invalid invoice amount">>)};
throw:{external_id_conflict, InvoiceID, ExternalID, _Schema} -> throw:{external_id_conflict, InvoiceID, ExternalID, _Schema} ->
{ok, logic_error(externalIDConflict, {InvoiceID, ExternalID})}; {ok, logic_error('externalIDConflict', {InvoiceID, ExternalID})};
throw:allocation_wrong_cart -> throw:allocation_wrong_cart ->
{ok, logic_error(invalidAllocation, <<"Wrong cart">>)}; {ok, logic_error('invalidAllocation', <<"Wrong cart">>)};
throw:allocation_duplicate -> throw:allocation_duplicate ->
{ok, logic_error(invalidAllocation, <<"Duplicate shop">>)} {ok, logic_error('invalidAllocation', <<"Duplicate shop">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('CreateInvoiceAccessToken' = OperationID, Req, Context) -> prepare('CreateInvoiceAccessToken' = OperationID, Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
ResultInvoice = map_service_result(capi_handler_utils:get_invoice_by_id(InvoiceID, Context)), ResultInvoice = map_service_result(capi_handler_utils:get_invoice_by_id(InvoiceID, Context)),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -91,7 +88,7 @@ prepare('CreateInvoiceAccessToken' = OperationID, Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('GetInvoiceByID' = OperationID, Req, Context) -> prepare('GetInvoiceByID' = OperationID, Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
ResultInvoice = map_service_result(capi_handler_utils:get_invoice_by_id(InvoiceID, Context)), ResultInvoice = map_service_result(capi_handler_utils:get_invoice_by_id(InvoiceID, Context)),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -108,7 +105,7 @@ prepare('GetInvoiceByID' = OperationID, Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('GetInvoiceByExternalID' = OperationID, Req, Context) -> prepare('GetInvoiceByExternalID' = OperationID, Req, Context) ->
ExternalID = maps:get(externalID, Req), ExternalID = maps:get('externalID', Req),
{InvoiceID, ResultInvoice} = {InvoiceID, ResultInvoice} =
case get_invoice_by_external_id(ExternalID, Context) of case get_invoice_by_external_id(ExternalID, Context) of
{ok, Result} -> {ok, Result} ->
@ -133,7 +130,7 @@ prepare('GetInvoiceByExternalID' = OperationID, Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('FulfillInvoice' = OperationID, Req, Context) -> prepare('FulfillInvoice' = OperationID, Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
{operation, #{id => OperationID, invoice => InvoiceID}}, {operation, #{id => OperationID, invoice => InvoiceID}},
@ -148,24 +145,21 @@ prepare('FulfillInvoice' = OperationID, Req, Context) ->
case capi_handler_utils:service_call_with([user_info], Call, Context) of case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _} -> {ok, _} ->
{ok, {204, #{}, undefined}}; {ok, {204, #{}, undefined}};
{exception, Exception} -> {exception, #payproc_InvalidInvoiceStatus{}} ->
case Exception of {ok, logic_error('invalidInvoiceStatus', <<"Invalid invoice status">>)};
#payproc_InvalidInvoiceStatus{} -> {exception, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error(invalidInvoiceStatus, <<"Invalid invoice status">>)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
#payproc_InvalidPartyStatus{} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
#payproc_InvalidShopStatus{} -> {exception, #payproc_InvalidUser{}} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; {ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvalidUser{} -> {exception, #payproc_InvoiceNotFound{}} ->
{ok, general_error(404, <<"Invoice not found">>)}; {ok, general_error(404, <<"Invoice not found">>)}
#payproc_InvoiceNotFound{} ->
{ok, general_error(404, <<"Invoice not found">>)}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('RescindInvoice' = OperationID, Req, Context) -> prepare('RescindInvoice' = OperationID, Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
{operation, #{id => OperationID, invoice => InvoiceID}}, {operation, #{id => OperationID, invoice => InvoiceID}},
@ -180,27 +174,23 @@ prepare('RescindInvoice' = OperationID, Req, Context) ->
case capi_handler_utils:service_call_with([user_info], Call, Context) of case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _} -> {ok, _} ->
{ok, {204, #{}, undefined}}; {ok, {204, #{}, undefined}};
{exception, Exception} -> {exception, #payproc_InvalidInvoiceStatus{}} ->
case Exception of {ok, logic_error('invalidInvoiceStatus', <<"Invalid invoice status">>)};
#payproc_InvalidInvoiceStatus{} -> {exception, #payproc_InvoicePaymentPending{}} ->
{ok, logic_error(invalidInvoiceStatus, <<"Invalid invoice status">>)}; {ok, logic_error('invoicePaymentPending', <<"Invoice payment pending">>)};
#payproc_InvoicePaymentPending{} -> {exception, #payproc_InvalidPartyStatus{}} ->
ErrorResp = logic_error(invoicePaymentPending, <<"Invoice payment pending">>), {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
{ok, ErrorResp}; {exception, #payproc_InvalidShopStatus{}} ->
#payproc_InvalidPartyStatus{} -> {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {exception, #payproc_InvalidUser{}} ->
#payproc_InvalidShopStatus{} -> {ok, general_error(404, <<"Invoice not found">>)};
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; {exception, #payproc_InvoiceNotFound{}} ->
#payproc_InvalidUser{} -> {ok, general_error(404, <<"Invoice not found">>)}
{ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvoiceNotFound{} ->
{ok, general_error(404, <<"Invoice not found">>)}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('GetInvoiceEvents' = OperationID, Req, Context) -> prepare('GetInvoiceEvents' = OperationID, Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
{operation, #{id => OperationID, invoice => InvoiceID}}, {operation, #{id => OperationID, invoice => InvoiceID}},
@ -212,38 +202,34 @@ prepare('GetInvoiceEvents' = OperationID, Req, Context) ->
Process = fun() -> Process = fun() ->
Result = Result =
capi_handler_utils:collect_events( capi_handler_utils:collect_events(
maps:get(limit, Req), maps:get('limit', Req),
genlib_map:get(eventID, Req), genlib_map:get('eventID', Req),
fun(Range) -> fun(Range) ->
capi_handler_utils:service_call_with( capi_handler_utils:service_call_with(
[user_info], [user_info],
{invoicing, 'GetEvents', {maps:get(invoiceID, Req), Range}}, {invoicing, 'GetEvents', {maps:get('invoiceID', Req), Range}},
Context Context
) )
end, end,
fun decode_invoice_event/2, fun(E) -> decode_invoice_event(E, Context) end
Context
), ),
case Result of case Result of
{ok, Events} when is_list(Events) -> {ok, Events} when is_list(Events) ->
{ok, {200, #{}, Events}}; {ok, {200, #{}, Events}};
{exception, Exception} -> {exception, #payproc_InvalidUser{}} ->
case Exception of {ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvalidUser{} -> {exception, #payproc_InvoiceNotFound{}} ->
{ok, general_error(404, <<"Invoice not found">>)}; {ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvoiceNotFound{} -> {exception, #payproc_EventNotFound{}} ->
{ok, general_error(404, <<"Invoice not found">>)}; {ok, general_error(404, <<"Event not found">>)};
#payproc_EventNotFound{} -> {exception, #'InvalidRequest'{errors = Errors}} ->
{ok, general_error(404, <<"Event not found">>)}; FormattedErrors = capi_handler_utils:format_request_errors(Errors),
#'InvalidRequest'{errors = Errors} -> {ok, logic_error('invalidRequest', FormattedErrors)}
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error(invalidRequest, FormattedErrors)}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('GetInvoicePaymentMethods' = OperationID, Req, Context) -> prepare('GetInvoicePaymentMethods' = OperationID, Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
ResultInvoice = map_service_result(capi_handler_utils:get_invoice_by_id(InvoiceID, Context)), ResultInvoice = map_service_result(capi_handler_utils:get_invoice_by_id(InvoiceID, Context)),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -266,13 +252,10 @@ prepare('GetInvoicePaymentMethods' = OperationID, Req, Context) ->
PaymentMethods1 = capi_utils:deduplicate_payment_methods(PaymentMethods0), PaymentMethods1 = capi_utils:deduplicate_payment_methods(PaymentMethods0),
PaymentMethods = capi_handler_utils:emplace_token_provider_data(Invoice, PaymentMethods1, Context), PaymentMethods = capi_handler_utils:emplace_token_provider_data(Invoice, PaymentMethods1, Context),
{ok, {200, #{}, PaymentMethods}}; {ok, {200, #{}, PaymentMethods}};
{exception, Exception} -> {exception, #payproc_InvalidUser{}} ->
case Exception of {ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvalidUser{} -> {exception, #payproc_InvoiceNotFound{}} ->
{ok, general_error(404, <<"Invoice not found">>)}; {ok, general_error(404, <<"Invoice not found">>)}
#payproc_InvoiceNotFound{} ->
{ok, general_error(404, <<"Invoice not found">>)}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -448,7 +431,7 @@ decode_refund_change(InvoiceID, PaymentID, _RefundID, {invoice_payment_refund_cr
<<"paymentID">> => PaymentID, <<"paymentID">> => PaymentID,
<<"refund">> => decode_refund_for_event(Refund, InvoiceID, PaymentID, Context) <<"refund">> => decode_refund_for_event(Refund, InvoiceID, PaymentID, Context)
}; };
decode_refund_change(_, PaymentID, RefundID, {invoice_payment_refund_status_changed, StatusChanged}, Context) -> decode_refund_change(_, PaymentID, RefundID, {invoice_payment_refund_status_changed, StatusChanged}, _Context) ->
#payproc_InvoicePaymentRefundStatusChanged{status = Status} = StatusChanged, #payproc_InvoicePaymentRefundStatusChanged{status = Status} = StatusChanged,
capi_handler_utils:merge_and_compact( capi_handler_utils:merge_and_compact(
#{ #{
@ -456,18 +439,18 @@ decode_refund_change(_, PaymentID, RefundID, {invoice_payment_refund_status_chan
<<"paymentID">> => PaymentID, <<"paymentID">> => PaymentID,
<<"refundID">> => RefundID <<"refundID">> => RefundID
}, },
capi_handler_decoder_invoicing:decode_refund_status(Status, Context) capi_handler_decoder_invoicing:decode_refund_status(Status)
); );
decode_refund_change(_, _, _, _, _) -> decode_refund_change(_, _, _, _, _) ->
undefined. undefined.
decode_refund_for_event(#domain_InvoicePaymentRefund{cash = #domain_Cash{}} = Refund, _, _, Context) -> decode_refund_for_event(#domain_InvoicePaymentRefund{cash = #domain_Cash{}} = Refund, _, _, _Context) ->
capi_handler_decoder_invoicing:decode_refund(Refund, Context); capi_handler_decoder_invoicing:decode_refund(Refund);
decode_refund_for_event(#domain_InvoicePaymentRefund{cash = undefined} = Refund, InvoiceID, PaymentID, Context) -> decode_refund_for_event(#domain_InvoicePaymentRefund{cash = undefined} = Refund, InvoiceID, PaymentID, Context) ->
% Need to fix it! % Need to fix it!
{ok, #payproc_InvoicePayment{payment = #domain_InvoicePayment{cost = Cash}}} = {ok, #payproc_InvoicePayment{payment = #domain_InvoicePayment{cost = Cash}}} =
capi_handler_utils:get_payment_by_id(InvoiceID, PaymentID, Context), capi_handler_utils:get_payment_by_id(InvoiceID, PaymentID, Context),
capi_handler_decoder_invoicing:decode_refund(Refund#domain_InvoicePaymentRefund{cash = Cash}, Context). capi_handler_decoder_invoicing:decode_refund(Refund#domain_InvoicePaymentRefund{cash = Cash}).
get_invoice_by_external_id(ExternalID, #{woody_context := WoodyContext} = Context) -> get_invoice_by_external_id(ExternalID, #{woody_context := WoodyContext} = Context) ->
PartyID = capi_handler_utils:get_party_id(Context), PartyID = capi_handler_utils:get_party_id(Context),

View File

@ -72,7 +72,7 @@ prepare('SuspendMyParty' = OperationID, _Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('GetPartyByID' = OperationID, Req, Context) -> prepare('GetPartyByID' = OperationID, Req, Context) ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID, party => PartyID}}], Prototypes = [{operation, #{id => OperationID, party => PartyID}}],
{ok, mask_party_notfound(capi_auth:authorize_operation(Prototypes, Context))} {ok, mask_party_notfound(capi_auth:authorize_operation(Prototypes, Context))}
@ -90,7 +90,7 @@ prepare('GetPartyByID' = OperationID, Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('ActivatePartyByID' = OperationID, Req, Context) -> prepare('ActivatePartyByID' = OperationID, Req, Context) ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID, party => PartyID}}], Prototypes = [{operation, #{id => OperationID, party => PartyID}}],
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
@ -109,7 +109,7 @@ prepare('ActivatePartyByID' = OperationID, Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('SuspendPartyByID' = OperationID, Req, Context) -> prepare('SuspendPartyByID' = OperationID, Req, Context) ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID, party => PartyID}}], Prototypes = [{operation, #{id => OperationID, party => PartyID}}],
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}

View File

@ -8,7 +8,7 @@
-import(capi_handler_utils, [general_error/2, logic_error/2]). -import(capi_handler_utils, [general_error/2, logic_error/2]).
-define(payment_institution_ref(PaymentInstitutionID), #domain_PaymentInstitutionRef{id = PaymentInstitutionID}). -define(PAYMENT_INSTITUTION_REF(PaymentInstitutionID), #domain_PaymentInstitutionRef{id = PaymentInstitutionID}).
-spec prepare( -spec prepare(
OperationID :: capi_handler:operation_id(), OperationID :: capi_handler:operation_id(),
@ -22,33 +22,22 @@ prepare(OperationID = 'GetPaymentInstitutions', Req, Context) ->
Residence = capi_handler_encoder:encode_residence(genlib_map:get(residence, Req)), Residence = capi_handler_encoder:encode_residence(genlib_map:get(residence, Req)),
Realm = genlib_map:get(realm, Req), Realm = genlib_map:get(realm, Req),
{ok, PaymentInstObjects} = capi_domain:get_payment_institutions(Context), {ok, PaymentInstObjects} = capi_domain:get_payment_institutions(Context),
Resp = Resp = filter_payment_institutions(Realm, Residence, PaymentInstObjects),
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}} {ok, {200, #{}, Resp}}
catch catch
throw:{encode_residence, invalid_residence} -> throw:{encode_residence, invalid_residence} ->
{ok, logic_error(invalidRequest, <<"Invalid residence">>)} {ok, logic_error('invalidRequest', <<"Invalid residence">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetPaymentInstitutionByRef', Req, Context) -> prepare(OperationID = 'GetPaymentInstitutionByRef', Req, Context) ->
Authorize = mk_authorize_operation(OperationID, Context), Authorize = mk_authorize_operation(OperationID, Context),
Process = fun() -> Process = fun() ->
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)), PaymentInstitutionID = genlib:to_int(maps:get('paymentInstitutionID', Req)),
PaymentInstitutionRef = ?payment_institution_ref(PaymentInstitutionID), PaymentInstitutionRef = ?PAYMENT_INSTITUTION_REF(PaymentInstitutionID),
case capi_domain:get({payment_institution, PaymentInstitutionRef}, Context) of case capi_domain:get({payment_institution, PaymentInstitutionRef}, Context) of
{ok, PaymentInstitution} -> {ok, PaymentInstitution} ->
{ok, {200, #{}, decode_payment_institution_obj(PaymentInstitution)}}; {ok, {200, #{}, decode_payment_institution(PaymentInstitution)}};
{error, not_found} -> {error, not_found} ->
{ok, general_error(404, <<"Payment institution not found">>)} {ok, general_error(404, <<"Payment institution not found">>)}
end end
@ -57,7 +46,7 @@ prepare(OperationID = 'GetPaymentInstitutionByRef', Req, Context) ->
prepare(OperationID = 'GetPaymentInstitutionPaymentTerms', Req, Context) -> prepare(OperationID = 'GetPaymentInstitutionPaymentTerms', Req, Context) ->
Authorize = mk_authorize_operation(OperationID, Context), Authorize = mk_authorize_operation(OperationID, Context),
Process = fun() -> Process = fun() ->
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)), PaymentInstitutionID = genlib:to_int(maps:get('paymentInstitutionID', Req)),
case compute_payment_institution_terms(PaymentInstitutionID, #payproc_Varset{}, Context) of case compute_payment_institution_terms(PaymentInstitutionID, #payproc_Varset{}, Context) of
{ok, #domain_TermSet{payments = PaymentTerms}} -> {ok, #domain_TermSet{payments = PaymentTerms}} ->
{ok, {200, #{}, decode_payment_terms(PaymentTerms)}}; {ok, {200, #{}, decode_payment_terms(PaymentTerms)}};
@ -69,7 +58,7 @@ prepare(OperationID = 'GetPaymentInstitutionPaymentTerms', Req, Context) ->
prepare(OperationID = 'GetPaymentInstitutionPayoutMethods', Req, Context) -> prepare(OperationID = 'GetPaymentInstitutionPayoutMethods', Req, Context) ->
Authorize = mk_authorize_operation(OperationID, Context), Authorize = mk_authorize_operation(OperationID, Context),
Process = fun() -> Process = fun() ->
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)), PaymentInstitutionID = genlib:to_int(maps:get('paymentInstitutionID', Req)),
case compute_payment_institution_terms(PaymentInstitutionID, prepare_request_varset(Req, Context), Context) of case compute_payment_institution_terms(PaymentInstitutionID, prepare_request_varset(Req, Context), Context) of
{ok, #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_methods = PayoutMethods}}} -> {ok, #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_methods = PayoutMethods}}} ->
{ok, {200, #{}, decode_payout_methods_selector(PayoutMethods)}}; {ok, {200, #{}, decode_payout_methods_selector(PayoutMethods)}};
@ -83,7 +72,7 @@ prepare(OperationID = 'GetPaymentInstitutionPayoutMethods', Req, Context) ->
prepare(OperationID = 'GetPaymentInstitutionPayoutSchedules', Req, Context) -> prepare(OperationID = 'GetPaymentInstitutionPayoutSchedules', Req, Context) ->
Authorize = mk_authorize_operation(OperationID, Context), Authorize = mk_authorize_operation(OperationID, Context),
Process = fun() -> Process = fun() ->
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)), PaymentInstitutionID = genlib:to_int(maps:get('paymentInstitutionID', Req)),
case compute_payment_institution_terms(PaymentInstitutionID, prepare_request_varset(Req, Context), Context) of case compute_payment_institution_terms(PaymentInstitutionID, prepare_request_varset(Req, Context), Context) of
{ok, #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_schedules = Schedules}}} -> {ok, #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_schedules = Schedules}}} ->
{ok, {200, #{}, decode_business_schedules_selector(Schedules)}}; {ok, {200, #{}, decode_business_schedules_selector(Schedules)}};
@ -94,6 +83,19 @@ prepare(OperationID = 'GetPaymentInstitutionPayoutSchedules', Req, Context) ->
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetServiceProviderByID', Req, Context) ->
Authorize = mk_authorize_operation(OperationID, Context),
Process = fun() ->
ServiceProviderID = maps:get('serviceProviderID', Req),
PaymentServiceRef = {payment_service, #domain_PaymentServiceRef{id = ServiceProviderID}},
case capi_domain:get(PaymentServiceRef, Context) of
{ok, #domain_PaymentServiceObject{data = PaymentService}} ->
{ok, {200, #{}, decode_payment_service(ServiceProviderID, PaymentService)}};
{error, not_found} ->
{ok, general_error(404, <<"Service provider not found">>)}
end
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(_OperationID, _Req, _Context) -> prepare(_OperationID, _Req, _Context) ->
{error, noimpl}. {error, noimpl}.
@ -107,6 +109,19 @@ mk_authorize_operation(OperationID, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end. end.
filter_payment_institutions(Realm, Residence, PaymentInstObjects) ->
lists:filtermap(
fun(P) ->
case check_payment_institution(Realm, Residence, P) of
true ->
{true, decode_payment_institution(P)};
false ->
false
end
end,
PaymentInstObjects
).
check_payment_institution(Realm, Residence, PaymentInstitution) -> check_payment_institution(Realm, Residence, PaymentInstitution) ->
check_payment_institution_realm(Realm, PaymentInstitution) andalso check_payment_institution_realm(Realm, PaymentInstitution) andalso
check_payment_institution_residence(Residence, PaymentInstitution). check_payment_institution_residence(Residence, PaymentInstitution).
@ -126,13 +141,13 @@ check_payment_institution_residence(Residence, #domain_PaymentInstitutionObject{
ordsets:is_element(Residence, Residences). ordsets:is_element(Residence, Residences).
compute_payment_institution_terms(PaymentInstitutionID, VS, Context) -> compute_payment_institution_terms(PaymentInstitutionID, VS, Context) ->
Ref = ?payment_institution_ref(PaymentInstitutionID), Ref = ?PAYMENT_INSTITUTION_REF(PaymentInstitutionID),
capi_party:compute_payment_institution_terms(Ref, VS, Context). capi_party:compute_payment_institution_terms(Ref, VS, Context).
prepare_request_varset(Req, Context) -> prepare_request_varset(Req, Context) ->
#payproc_Varset{ #payproc_Varset{
currency = encode_optional_currency(genlib_map:get(currency, Req)), currency = encode_optional_currency(genlib_map:get('currency', Req)),
payout_method = encode_optional_payout_method(genlib_map:get(payoutMethod, Req)), payout_method = encode_optional_payout_method(genlib_map:get('payoutMethod', Req)),
party_id = capi_handler_utils:get_party_id(Context) party_id = capi_handler_utils:get_party_id(Context)
}. }.
@ -154,7 +169,7 @@ encode_optional_currency(SymbolicCode) -> capi_handler_encoder:encode_currency(S
% %
decode_payment_institution_obj(#domain_PaymentInstitutionObject{ref = Ref, data = Data}) -> decode_payment_institution(#domain_PaymentInstitutionObject{ref = Ref, data = Data}) ->
genlib_map:compact(#{ genlib_map:compact(#{
<<"id">> => Ref#domain_PaymentInstitutionRef.id, <<"id">> => Ref#domain_PaymentInstitutionRef.id,
<<"name">> => Data#domain_PaymentInstitution.name, <<"name">> => Data#domain_PaymentInstitution.name,
@ -197,3 +212,16 @@ decode_business_schedules_selector({value, Val}) when is_list(Val) ->
lists:map(fun capi_handler_decoder_utils:decode_business_schedule_ref/1, Val); lists:map(fun capi_handler_decoder_utils:decode_business_schedule_ref/1, Val);
decode_business_schedules_selector(_) -> decode_business_schedules_selector(_) ->
[]. [].
%%
decode_payment_service(ID, PaymentService = #domain_PaymentService{}) ->
genlib_map:compact(#{
<<"id">> => ID,
<<"brandName">> => PaymentService#domain_PaymentService.brand_name,
<<"category">> => PaymentService#domain_PaymentService.category,
<<"metadata">> => capi_utils:maybe(
PaymentService#domain_PaymentService.metadata,
fun capi_handler_decoder_utils:decode_namespaced_metadata/1
)
}).

View File

@ -16,7 +16,7 @@
Context :: capi_handler:processing_context() Context :: capi_handler:processing_context()
) -> {ok, capi_handler:request_state()} | {error, noimpl}. ) -> {ok, capi_handler:request_state()} | {error, noimpl}.
prepare(OperationID = 'CreatePayment', Req, Context) -> prepare(OperationID = 'CreatePayment', Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
Invoice = get_invoice_by_id(InvoiceID, Context), Invoice = get_invoice_by_id(InvoiceID, Context),
PaymentParams = maps:get('PaymentParams', Req), PaymentParams = maps:get('PaymentParams', Req),
Authorize = fun() -> Authorize = fun() ->
@ -35,26 +35,20 @@ prepare(OperationID = 'CreatePayment', Req, Context) ->
{ok, Payment} -> {ok, Payment} ->
{ok, {201, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}}; {ok, {201, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}};
{exception, #payproc_InvalidInvoiceStatus{}} -> {exception, #payproc_InvalidInvoiceStatus{}} ->
{ok, logic_error(invalidInvoiceStatus, <<"Invalid invoice status">>)}; {ok, logic_error('invalidInvoiceStatus', <<"Invalid invoice status">>)};
{exception, #payproc_InvoicePaymentPending{}} -> {exception, #payproc_InvoicePaymentPending{}} ->
ErrorResp = logic_error( {ok, logic_error('invoicePaymentPending', <<"Invoice payment pending">>)};
invoicePaymentPending,
<<"Invoice payment pending">>
),
{ok, ErrorResp};
{exception, #'InvalidRequest'{errors = Errors}} -> {exception, #'InvalidRequest'{errors = Errors}} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors), FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidRequest', FormattedErrors)};
{exception, #payproc_InvalidPartyStatus{}} -> {exception, #payproc_InvalidPartyStatus{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
{exception, #payproc_InvalidShopStatus{}} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
{exception, #payproc_InvalidContractStatus{}} -> {exception, #payproc_InvalidContractStatus{}} ->
ErrorResp = logic_error(invalidContractStatus, <<"Invalid contract status">>), {ok, logic_error('invalidContractStatus', <<"Invalid contract status">>)};
{ok, ErrorResp};
{exception, #payproc_InvalidRecurrentParentPayment{}} -> {exception, #payproc_InvalidRecurrentParentPayment{}} ->
ErrorResp = logic_error(invalidRecurrentParent, <<"Specified recurrent parent is invalid">>), {ok, logic_error('invalidRecurrentParent', <<"Specified recurrent parent is invalid">>)};
{ok, ErrorResp};
{exception, #payproc_InvalidUser{}} -> {exception, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Invoice not found">>)}; {ok, general_error(404, <<"Invoice not found">>)};
{exception, #payproc_InvoiceNotFound{}} -> {exception, #payproc_InvoiceNotFound{}} ->
@ -62,24 +56,16 @@ prepare(OperationID = 'CreatePayment', Req, Context) ->
end end
catch catch
throw:invalid_payment_session -> throw:invalid_payment_session ->
{ok, {ok, logic_error('invalidPaymentSession', <<"Specified payment session is invalid">>)};
logic_error(
invalidPaymentSession,
<<"Specified payment session is invalid">>
)};
throw:invalid_processing_deadline -> throw:invalid_processing_deadline ->
{ok, {ok, logic_error('invalidProcessingDeadline', <<"Specified processing deadline is invalid">>)};
logic_error(
invalidProcessingDeadline,
<<"Specified processing deadline is invalid">>
)};
throw:{external_id_conflict, PaymentID, ExternalID, _Schema} -> throw:{external_id_conflict, PaymentID, ExternalID, _Schema} ->
{ok, logic_error(externalIDConflict, {PaymentID, ExternalID})} {ok, logic_error('externalIDConflict', {PaymentID, ExternalID})}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetPayments', Req, Context) -> prepare(OperationID = 'GetPayments', Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
Invoice = get_invoice_by_id(InvoiceID, Context), Invoice = get_invoice_by_id(InvoiceID, Context),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -95,8 +81,8 @@ prepare(OperationID = 'GetPayments', Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetPaymentByID', Req, Context) -> prepare(OperationID = 'GetPaymentByID', Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
PaymentID = maps:get(paymentID, Req), PaymentID = maps:get('paymentID', Req),
Invoice = get_invoice_by_id(InvoiceID, Context), Invoice = get_invoice_by_id(InvoiceID, Context),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -116,7 +102,7 @@ prepare(OperationID = 'GetPaymentByID', Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetPaymentByExternalID', Req, Context) -> prepare(OperationID = 'GetPaymentByExternalID', Req, Context) ->
ExternalID = maps:get(externalID, Req), ExternalID = maps:get('externalID', Req),
InternalID = get_payment_by_external_id(ExternalID, Context), InternalID = get_payment_by_external_id(ExternalID, Context),
Invoice = maybe( Invoice = maybe(
InternalID, InternalID,
@ -150,8 +136,8 @@ prepare(OperationID = 'GetPaymentByExternalID', Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'CapturePayment', Req, Context) -> prepare(OperationID = 'CapturePayment', Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
PaymentID = maps:get(paymentID, Req), PaymentID = maps:get('paymentID', Req),
PartyID = capi_handler_utils:get_party_id(Context), PartyID = capi_handler_utils:get_party_id(Context),
Invoice = get_invoice_by_id(InvoiceID, Context), Invoice = get_invoice_by_id(InvoiceID, Context),
Authorize = fun() -> Authorize = fun() ->
@ -178,62 +164,55 @@ prepare(OperationID = 'CapturePayment', Req, Context) ->
of of
{ok, _} -> {ok, _} ->
{ok, {202, #{}, undefined}}; {ok, {202, #{}, undefined}};
{exception, Exception} -> {exception, #payproc_InvoicePaymentNotFound{}} ->
case Exception of {ok, general_error(404, <<"Payment not found">>)};
#payproc_InvoicePaymentNotFound{} -> {exception, #payproc_InvalidPaymentStatus{}} ->
{ok, general_error(404, <<"Payment not found">>)}; {ok, logic_error('invalidPaymentStatus', <<"Invalid payment status">>)};
#payproc_InvalidPaymentStatus{} -> {exception, #payproc_InvalidUser{}} ->
{ok, logic_error(invalidPaymentStatus, <<"Invalid payment status">>)}; {ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvalidUser{} -> {exception, #payproc_InvoiceNotFound{}} ->
{ok, general_error(404, <<"Invoice not found">>)}; {ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvoiceNotFound{} -> {exception, #'InvalidRequest'{errors = Errors}} ->
{ok, general_error(404, <<"Invoice not found">>)}; FormattedErrors = capi_handler_utils:format_request_errors(Errors),
#'InvalidRequest'{errors = Errors} -> {ok, logic_error('invalidRequest', FormattedErrors)};
FormattedErrors = capi_handler_utils:format_request_errors(Errors), {exception, #payproc_OperationNotPermitted{}} ->
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('operationNotPermitted', <<"Operation not permitted">>)};
#payproc_OperationNotPermitted{} -> {exception, #payproc_InvalidPartyStatus{}} ->
ErrorResp = logic_error( {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
operationNotPermitted, {exception, #payproc_InvalidShopStatus{}} ->
<<"Operation not permitted">> {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
), {exception, #payproc_InconsistentCaptureCurrency{payment_currency = PaymentCurrency}} ->
{ok, ErrorResp}; {ok,
#payproc_InvalidPartyStatus{} -> logic_error(
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; 'inconsistentCaptureCurrency',
#payproc_InvalidShopStatus{} -> io_lib:format("Correct currency: ~p", [PaymentCurrency])
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; )};
#payproc_InconsistentCaptureCurrency{payment_currency = PaymentCurrency} -> {exception, #payproc_AmountExceededCaptureBalance{payment_amount = PaymentAmount}} ->
{ok, {ok,
logic_error( logic_error(
inconsistentCaptureCurrency, 'amountExceededCaptureBalance',
io_lib:format("Correct currency: ~p", [PaymentCurrency]) io_lib:format("Max amount: ~p", [PaymentAmount])
)}; )};
#payproc_AmountExceededCaptureBalance{payment_amount = PaymentAmount} -> {exception, #payproc_AllocationNotAllowed{}} ->
{ok, {ok, logic_error('allocationNotPermitted', <<"Not allowed">>)};
logic_error( {exception, #payproc_AllocationExceededPaymentAmount{}} ->
amountExceededCaptureBalance, {ok, logic_error('invalidAllocation', <<"Exceeded payment amount">>)};
io_lib:format("Max amount: ~p", [PaymentAmount]) {exception, #payproc_AllocationInvalidTransaction{} = InvalidTransaction} ->
)}; Message = capi_allocation:transaction_error(InvalidTransaction),
#payproc_AllocationNotAllowed{} -> {ok, logic_error('invalidAllocation', Message)}
{ok, logic_error(allocationNotPermitted, <<"Not allowed">>)};
#payproc_AllocationExceededPaymentAmount{} ->
{ok, logic_error(invalidAllocation, <<"Exceeded payment amount">>)};
#payproc_AllocationInvalidTransaction{} = InvalidTransaction ->
Message = capi_allocation:transaction_error(InvalidTransaction),
{ok, logic_error(invalidAllocation, Message)}
end
catch catch
throw:invoice_cart_empty -> throw:invoice_cart_empty ->
{ok, logic_error(invalidInvoiceCart, <<"Wrong size. Path to item: cart">>)}; {ok, logic_error('invalidInvoiceCart', <<"Wrong size. Path to item: cart">>)};
throw:allocation_wrong_cart -> throw:allocation_wrong_cart ->
{ok, logic_error(invalidAllocation, <<"Wrong cart">>)}; {ok, logic_error('invalidAllocation', <<"Wrong cart">>)};
throw:allocation_duplicate -> throw:allocation_duplicate ->
{ok, logic_error(invalidAllocation, <<"Duplicate shop">>)} {ok, logic_error('invalidAllocation', <<"Duplicate shop">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'CancelPayment', Req, Context) -> prepare(OperationID = 'CancelPayment', Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
PaymentID = maps:get(paymentID, Req), PaymentID = maps:get('paymentID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
{operation, #{id => OperationID, invoice => InvoiceID, payment => PaymentID}}, {operation, #{id => OperationID, invoice => InvoiceID, payment => PaymentID}},
@ -248,36 +227,29 @@ prepare(OperationID = 'CancelPayment', Req, Context) ->
case capi_handler_utils:service_call_with([user_info], Call, Context) of case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _} -> {ok, _} ->
{ok, {202, #{}, undefined}}; {ok, {202, #{}, undefined}};
{exception, Exception} -> {exception, #payproc_InvoicePaymentNotFound{}} ->
case Exception of {ok, general_error(404, <<"Payment not found">>)};
#payproc_InvoicePaymentNotFound{} -> {exception, #payproc_InvalidPaymentStatus{}} ->
{ok, general_error(404, <<"Payment not found">>)}; {ok, logic_error('invalidPaymentStatus', <<"Invalid payment status">>)};
#payproc_InvalidPaymentStatus{} -> {exception, #payproc_InvalidUser{}} ->
{ok, logic_error(invalidPaymentStatus, <<"Invalid payment status">>)}; {ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvalidUser{} -> {exception, #payproc_InvoiceNotFound{}} ->
{ok, general_error(404, <<"Invoice not found">>)}; {ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvoiceNotFound{} -> {exception, #'InvalidRequest'{errors = Errors}} ->
{ok, general_error(404, <<"Invoice not found">>)}; FormattedErrors = capi_handler_utils:format_request_errors(Errors),
#'InvalidRequest'{errors = Errors} -> {ok, logic_error('invalidRequest', FormattedErrors)};
FormattedErrors = capi_handler_utils:format_request_errors(Errors), {exception, #payproc_OperationNotPermitted{}} ->
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('operationNotPermitted', <<"Operation not permitted">>)};
#payproc_OperationNotPermitted{} -> {exception, #payproc_InvalidPartyStatus{}} ->
ErrorResp = logic_error( {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
operationNotPermitted, {exception, #payproc_InvalidShopStatus{}} ->
<<"Operation not permitted">> {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)}
),
{ok, ErrorResp};
#payproc_InvalidPartyStatus{} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)};
#payproc_InvalidShopStatus{} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'CreateRefund', Req, Context) -> prepare(OperationID = 'CreateRefund', Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
PaymentID = maps:get(paymentID, Req), PaymentID = maps:get('paymentID', Req),
RefundParams = maps:get('RefundParams', Req), RefundParams = maps:get('RefundParams', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -292,85 +264,62 @@ prepare(OperationID = 'CreateRefund', Req, Context) ->
create_refund(InvoiceID, PaymentID, RefundParams, Context, OperationID) create_refund(InvoiceID, PaymentID, RefundParams, Context, OperationID)
of of
{ok, Refund} -> {ok, Refund} ->
{ok, {201, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}}; {ok, {201, #{}, capi_handler_decoder_invoicing:decode_refund(Refund)}};
{exception, Exception} -> {exception, #payproc_InvalidUser{}} ->
case Exception of {ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvalidUser{} -> {exception, #payproc_InvoicePaymentNotFound{}} ->
{ok, general_error(404, <<"Invoice not found">>)}; {ok, general_error(404, <<"Payment not found">>)};
#payproc_InvoicePaymentNotFound{} -> {exception, #payproc_InvoiceNotFound{}} ->
{ok, general_error(404, <<"Payment not found">>)}; {ok, general_error(404, <<"Invoice not found">>)};
#payproc_InvoiceNotFound{} -> {exception, #payproc_InvalidPartyStatus{}} ->
{ok, general_error(404, <<"Invoice not found">>)}; {ok, logic_error('invalidPartyStatus', <<"Invalid party status">>)};
#payproc_InvalidPartyStatus{} -> {exception, #payproc_InvalidShopStatus{}} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)}; {ok, logic_error('invalidShopStatus', <<"Invalid shop status">>)};
#payproc_InvalidShopStatus{} -> {exception, #payproc_InvalidContractStatus{}} ->
{ok, logic_error(invalidShopStatus, <<"Invalid shop status">>)}; {ok, logic_error('invalidContractStatus', <<"Invalid contract status">>)};
#payproc_InvalidContractStatus{} -> {exception, #payproc_OperationNotPermitted{}} ->
ErrorResp = logic_error( {ok, logic_error('operationNotPermitted', <<"Operation not permitted">>)};
invalidContractStatus, {exception, #payproc_InvalidPaymentStatus{}} ->
<<"Invalid contract status">> {ok, logic_error('invalidPaymentStatus', <<"Invalid invoice payment status">>)};
), {exception, #payproc_InsufficientAccountBalance{}} ->
{ok, ErrorResp}; ErrResp = logic_error(
#payproc_OperationNotPermitted{} -> 'insufficentAccountBalance',
ErrorResp = logic_error( <<"Operation can not be conducted because of insufficient funds on the merchant account">>
operationNotPermitted, ),
<<"Operation not permitted">> {ok, ErrResp};
), {exception, #payproc_InvoicePaymentAmountExceeded{}} ->
{ok, ErrorResp}; {ok, logic_error('invoicePaymentAmountExceeded', <<"Payment amount exceeded">>)};
#payproc_InvalidPaymentStatus{} -> {exception, #payproc_InconsistentRefundCurrency{}} ->
ErrorResp = logic_error( {ok, logic_error('inconsistentRefundCurrency', <<"Inconsistent refund currency">>)};
invalidPaymentStatus, {exception, #'InvalidRequest'{errors = Errors}} ->
<<"Invalid invoice payment status">> FormattedErrors = capi_handler_utils:format_request_errors(Errors),
), {ok, logic_error('invalidRequest', FormattedErrors)};
{ok, ErrorResp}; {exception, #payproc_AllocationNotAllowed{}} ->
#payproc_InsufficientAccountBalance{} -> {ok, logic_error('allocationNotPermitted', <<"Not allowed">>)};
ErrResp = logic_error( {exception, #payproc_AllocationExceededPaymentAmount{}} ->
insufficentAccountBalance, {ok, logic_error('invalidAllocation', <<"Exceeded payment amount">>)};
<<"Operation can not be conducted because of insufficient funds on the merchant account">> {exception, #payproc_AllocationInvalidTransaction{} = InvalidTransaction} ->
), Message = capi_allocation:transaction_error(InvalidTransaction),
{ok, ErrResp}; {ok, logic_error('invalidAllocation', Message)};
#payproc_InvoicePaymentAmountExceeded{} -> {exception, #payproc_AllocationNotFound{}} ->
ErrorResp = logic_error( {ok, logic_error('invalidAllocation', <<"Not found">>)}
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)};
#payproc_AllocationNotAllowed{} ->
{ok, logic_error(allocationNotPermitted, <<"Not allowed">>)};
#payproc_AllocationExceededPaymentAmount{} ->
{ok, logic_error(invalidAllocation, <<"Exceeded payment amount">>)};
#payproc_AllocationInvalidTransaction{} = InvalidTransaction ->
Message = capi_allocation:transaction_error(InvalidTransaction),
{ok, logic_error(invalidAllocation, Message)};
#payproc_AllocationNotFound{} ->
{ok, logic_error(invalidAllocation, <<"Not found">>)}
end
catch catch
throw:invoice_cart_empty -> throw:invoice_cart_empty ->
{ok, logic_error(invalidInvoiceCart, <<"Wrong size. Path to item: cart">>)}; {ok, logic_error('invalidInvoiceCart', <<"Wrong size. Path to item: cart">>)};
throw:{external_id_conflict, RefundID, ExternalID, _Schema} -> throw:{external_id_conflict, RefundID, ExternalID, _Schema} ->
{ok, logic_error(externalIDConflict, {RefundID, ExternalID})}; {ok, logic_error('externalIDConflict', {RefundID, ExternalID})};
throw:allocation_duplicate -> throw:allocation_duplicate ->
{ok, logic_error(invalidAllocation, <<"Duplicate shop">>)}; {ok, logic_error('invalidAllocation', <<"Duplicate shop">>)};
throw:allocation_wrong_cart -> throw:allocation_wrong_cart ->
{ok, logic_error(invalidAllocation, <<"Wrong cart">>)}; {ok, logic_error('invalidAllocation', <<"Wrong cart">>)};
throw:refund_cart_conflict -> throw:refund_cart_conflict ->
{ok, logic_error(refundCartConflict, <<"Inconsistent Refund Cart">>)} {ok, logic_error('refundCartConflict', <<"Inconsistent Refund Cart">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetRefunds', Req, Context) -> prepare(OperationID = 'GetRefunds', Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
PaymentID = maps:get(paymentID, Req), PaymentID = maps:get('paymentID', Req),
Invoice = get_invoice_by_id(InvoiceID, Context), Invoice = get_invoice_by_id(InvoiceID, Context),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -385,7 +334,7 @@ prepare(OperationID = 'GetRefunds', Req, Context) ->
#payproc_InvoicePayment{refunds = Refunds} -> #payproc_InvoicePayment{refunds = Refunds} ->
{ok, {ok,
{200, #{}, [ {200, #{}, [
capi_handler_decoder_invoicing:decode_refund(R, Context) capi_handler_decoder_invoicing:decode_refund(R)
|| #payproc_InvoicePaymentRefund{refund = R} <- Refunds || #payproc_InvoicePaymentRefund{refund = R} <- Refunds
]}}; ]}};
undefined -> undefined ->
@ -394,9 +343,9 @@ prepare(OperationID = 'GetRefunds', Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetRefundByID', Req, Context) -> prepare(OperationID = 'GetRefundByID', Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
PaymentID = maps:get(paymentID, Req), PaymentID = maps:get('paymentID', Req),
RefundID = maps:get(refundID, Req), RefundID = maps:get('refundID', Req),
Invoice = get_invoice_by_id(InvoiceID, Context), Invoice = get_invoice_by_id(InvoiceID, Context),
Payment = find_payment_by_id(PaymentID, Invoice), Payment = find_payment_by_id(PaymentID, Invoice),
Authorize = fun() -> Authorize = fun() ->
@ -410,17 +359,16 @@ prepare(OperationID = 'GetRefundByID', Req, Context) ->
Process = fun() -> Process = fun() ->
capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)), capi_handler:respond_if_undefined(Invoice, general_error(404, <<"Invoice not found">>)),
capi_handler:respond_if_undefined(Payment, general_error(404, <<"Payment not found">>)), capi_handler:respond_if_undefined(Payment, general_error(404, <<"Payment not found">>)),
case find_refund_by_id(RefundID, Payment) of case find_refund_by_id(RefundID, Payment) of
#payproc_InvoicePaymentRefund{refund = Refund} -> #payproc_InvoicePaymentRefund{refund = Refund} ->
{ok, {200, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}}; {ok, {200, #{}, capi_handler_decoder_invoicing:decode_refund(Refund)}};
undefined -> undefined ->
{ok, general_error(404, <<"Invoice payment refund not found">>)} {ok, general_error(404, <<"Invoice payment refund not found">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetRefundByExternalID', Req, Context) -> prepare(OperationID = 'GetRefundByExternalID', Req, Context) ->
ExternalID = maps:get(externalID, Req), ExternalID = maps:get('externalID', Req),
InternalID = get_refund_by_external_id(ExternalID, Context), InternalID = get_refund_by_external_id(ExternalID, Context),
Invoice = maybe( Invoice = maybe(
InternalID, InternalID,
@ -449,15 +397,15 @@ prepare(OperationID = 'GetRefundByExternalID', Req, Context) ->
capi_handler:respond_if_undefined(Payment, general_error(404, <<"Payment not found">>)), capi_handler:respond_if_undefined(Payment, general_error(404, <<"Payment not found">>)),
case find_refund_by_id(RefundID, Payment) of case find_refund_by_id(RefundID, Payment) of
#payproc_InvoicePaymentRefund{refund = Refund} -> #payproc_InvoicePaymentRefund{refund = Refund} ->
{ok, {200, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}}; {ok, {200, #{}, capi_handler_decoder_invoicing:decode_refund(Refund)}};
undefined -> undefined ->
{ok, general_error(404, <<"Invoice payment refund not found">>)} {ok, general_error(404, <<"Invoice payment refund not found">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetChargebacks', Req, Context) -> prepare(OperationID = 'GetChargebacks', Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
PaymentID = maps:get(paymentID, Req), PaymentID = maps:get('paymentID', Req),
Invoice = get_invoice_by_id(InvoiceID, Context), Invoice = get_invoice_by_id(InvoiceID, Context),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [ Prototypes = [
@ -480,9 +428,9 @@ prepare(OperationID = 'GetChargebacks', Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetChargebackByID', Req, Context) -> prepare(OperationID = 'GetChargebackByID', Req, Context) ->
InvoiceID = maps:get(invoiceID, Req), InvoiceID = maps:get('invoiceID', Req),
PaymentID = maps:get(paymentID, Req), PaymentID = maps:get('paymentID', Req),
ChargebackID = maps:get(chargebackID, Req), ChargebackID = maps:get('chargebackID', Req),
Invoice = get_invoice_by_id(InvoiceID, Context), Invoice = get_invoice_by_id(InvoiceID, Context),
Payment = find_payment_by_id(PaymentID, Invoice), Payment = find_payment_by_id(PaymentID, Invoice),
Authorize = fun() -> Authorize = fun() ->
@ -541,10 +489,6 @@ create_payment_id(Invoice, PaymentParams0, Context, OperationID, PaymentToolThri
Payer = maps:get(<<"payer">>, PaymentParams0), Payer = maps:get(<<"payer">>, PaymentParams0),
PaymentTool = capi_utils:maybe(PaymentToolThrift, fun capi_handler_decoder_party:decode_payment_tool/1), PaymentTool = capi_utils:maybe(PaymentToolThrift, fun capi_handler_decoder_party:decode_payment_tool/1),
% Temporary decision for analytics team
% TODO: delete this after analytics research will be down
_ = log_payer_client_url(Payer, InvoiceID),
PaymentParams = PaymentParams0#{ PaymentParams = PaymentParams0#{
% Требуется для последующей кодировки параметров плательщика % Требуется для последующей кодировки параметров плательщика
<<"invoiceID">> => InvoiceID, <<"invoiceID">> => InvoiceID,
@ -563,20 +507,6 @@ create_payment_id(Invoice, PaymentParams0, Context, OperationID, PaymentToolThri
CtxData = #{<<"invoice_id">> => InvoiceID}, CtxData = #{<<"invoice_id">> => InvoiceID},
capi_bender:try_gen_sequence(IdempotentKey, Identity, SequenceID, SequenceParams, WoodyCtx, CtxData). capi_bender:try_gen_sequence(IdempotentKey, Identity, SequenceID, SequenceParams, WoodyCtx, CtxData).
log_payer_client_url(#{<<"payerType">> := <<"PaymentResourcePayer">>} = Payer, InvoiceID) ->
EncodedSession = maps:get(<<"paymentSession">>, Payer),
{ClientInfo, _} = capi_handler_utils:unwrap_payment_session(EncodedSession),
ClientUrl = maps:get(<<"url">>, ClientInfo, undefined),
ClientIP = maps:get(<<"ip">>, ClientInfo, undefined),
MetaInfo = genlib_map:compact(#{
invoice_id => InvoiceID,
ip => ClientIP,
client_url => ClientUrl
}),
logger:info("Request location info.", [], MetaInfo);
log_payer_client_url(_, _) ->
skipped.
find_payment_by_id(PaymentID, #payproc_Invoice{payments = Payments}) -> find_payment_by_id(PaymentID, #payproc_Invoice{payments = Payments}) ->
Fun = fun(#payproc_InvoicePayment{payment = #domain_InvoicePayment{id = ID}}) -> Fun = fun(#payproc_InvoicePayment{payment = #domain_InvoicePayment{id = ID}}) ->
PaymentID == ID PaymentID == ID
@ -717,15 +647,15 @@ decode_payment_token(#{<<"paymentToolToken">> := Token}) ->
case capi_utils:deadline_is_reached(ValidUntil) of case capi_utils:deadline_is_reached(ValidUntil) of
true -> true ->
logger:warning("Payment tool token expired: ~p", [capi_utils:deadline_to_binary(ValidUntil)]), logger:warning("Payment tool token expired: ~p", [capi_utils:deadline_to_binary(ValidUntil)]),
capi_handler:respond(logic_error(invalidPaymentToolToken)); capi_handler:respond(logic_error('invalidPaymentToolToken'));
_ -> _ ->
TokenData TokenData
end; end;
unrecognized -> unrecognized ->
capi_handler:respond(logic_error(invalidPaymentToolToken)); capi_handler:respond(logic_error('invalidPaymentToolToken'));
{error, {decryption_failed, Error}} -> {error, {decryption_failed, Error}} ->
logger:warning("Payment tool token decryption failed: ~p", [Error]), logger:warning("Payment tool token decryption failed: ~p", [Error]),
capi_handler:respond(logic_error(invalidPaymentToolToken)) capi_handler:respond(logic_error('invalidPaymentToolToken'))
end; end;
decode_payment_token(_Other) -> decode_payment_token(_Other) ->
undefined. undefined.

View File

@ -1,6 +1,5 @@
-module(capi_handler_payouts). -module(capi_handler_payouts).
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl").
-include_lib("payout_manager_proto/include/payouts_payout_manager_thrift.hrl"). -include_lib("payout_manager_proto/include/payouts_payout_manager_thrift.hrl").
@ -16,7 +15,7 @@
Context :: capi_handler:processing_context() Context :: capi_handler:processing_context()
) -> {ok, capi_handler:request_state()} | {error, noimpl}. ) -> {ok, capi_handler:request_state()} | {error, noimpl}.
prepare(OperationID, Req, Context) when OperationID =:= 'GetPayout' -> prepare(OperationID, Req, Context) when OperationID =:= 'GetPayout' ->
PayoutID = maps:get(payoutID, Req), PayoutID = maps:get('payoutID', Req),
PartyID = capi_handler_utils:get_party_id(Context), PartyID = capi_handler_utils:get_party_id(Context),
OperationContext = #{ OperationContext = #{
id => OperationID, id => OperationID,
@ -69,18 +68,15 @@ prepare(OperationID, Req, Context) when OperationID =:= 'CreatePayout' ->
{ok, Payout} -> {ok, Payout} ->
{ok, PayoutTool} = get_payout_tool(Payout, Context), {ok, PayoutTool} = get_payout_tool(Payout, Context),
{ok, {201, #{}, decode_payout(Payout, PayoutTool)}}; {ok, {201, #{}, decode_payout(Payout, PayoutTool)}};
{exception, Exception} -> {exception, #payouts_InsufficientFunds{}} ->
case Exception of {ok, logic_error('invalidCash', <<"Invalid amount or currency">>)};
#payouts_InsufficientFunds{} -> {exception, #payouts_InvalidRequest{errors = Errors}} ->
{ok, logic_error(invalidCash, <<"Invalid amount or currency">>)}; FormattedErrors = capi_handler_utils:format_request_errors(Errors),
#payouts_InvalidRequest{errors = Errors} -> {ok, logic_error('invalidRequest', FormattedErrors)};
FormattedErrors = capi_handler_utils:format_request_errors(Errors), {exception, #payouts_PayoutAlreadyExists{}} ->
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidRequest', <<"Payout already exists">>)};
#payouts_PayoutAlreadyExists{} -> {exception, #payouts_NotFound{message = Message}} ->
{ok, logic_error(invalidRequest, <<"Payout already exists">>)}; {ok, logic_error('invalidRequest', Message)}
#payouts_NotFound{message = Message} ->
{ok, logic_error(invalidRequest, Message)}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -173,7 +169,7 @@ prepare(OperationID, Req, Context) when OperationID =:= 'GetScheduleByRef' ->
{ok, capi_auth:authorize_operation([{operation, OperationContext}], Context)} {ok, capi_auth:authorize_operation([{operation, OperationContext}], Context)}
end, end,
Process = fun() -> Process = fun() ->
case get_schedule_by_id(genlib:to_int(maps:get(scheduleID, Req)), Context) of case get_schedule_by_id(genlib:to_int(maps:get('scheduleID', Req)), Context) of
{ok, Schedule} -> {ok, Schedule} ->
{ok, {200, #{}, decode_business_schedule(Schedule)}}; {ok, {200, #{}, decode_business_schedule(Schedule)}};
{error, not_found} -> {error, not_found} ->

View File

@ -27,14 +27,14 @@ prepare(OperationID = 'GetReports', Req, Context) ->
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetReportsForParty', Req, Context) -> prepare(OperationID = 'GetReportsForParty', Req, Context) ->
Authorize = fun() -> Authorize = fun() ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
Prototypes = build_prototypes(OperationID, PartyID, undefined, Req), Prototypes = build_prototypes(OperationID, PartyID, undefined, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end, end,
Process = fun() -> process_request(OperationID, Context, Req) end, Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetReport', Req, Context) -> prepare(OperationID = 'GetReport', Req, Context) ->
ReportID = maps:get(reportID, Req), ReportID = maps:get('reportID', Req),
Report = Report =
case get_report_by_id(ReportID, Context) of case get_report_by_id(ReportID, Context) of
{ok, R} -> {ok, R} ->
@ -50,7 +50,7 @@ prepare(OperationID = 'GetReport', Req, Context) ->
Process = fun() -> process_request(OperationID, Context, Req) end, Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetReportForParty', Req, Context) -> prepare(OperationID = 'GetReportForParty', Req, Context) ->
ReportID = maps:get(reportID, Req), ReportID = maps:get('reportID', Req),
Report = Report =
case get_report_by_id(ReportID, Context) of case get_report_by_id(ReportID, Context) of
{ok, R} -> {ok, R} ->
@ -59,7 +59,7 @@ prepare(OperationID = 'GetReportForParty', Req, Context) ->
undefined undefined
end, end,
Authorize = fun() -> Authorize = fun() ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
Prototypes = build_prototypes(OperationID, PartyID, Report, Req), Prototypes = build_prototypes(OperationID, PartyID, Report, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end, end,
@ -75,14 +75,14 @@ prepare(OperationID = 'CreateReport', Req, Context) ->
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'CreateReportForParty', Req, Context) -> prepare(OperationID = 'CreateReportForParty', Req, Context) ->
Authorize = fun() -> Authorize = fun() ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
Prototypes = build_prototypes(OperationID, PartyID, undefined, Req), Prototypes = build_prototypes(OperationID, PartyID, undefined, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end, end,
Process = fun() -> process_request(OperationID, Context, Req) end, Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'DownloadFile', Req, Context) -> prepare(OperationID = 'DownloadFile', Req, Context) ->
ReportID = maps:get(reportID, Req), ReportID = maps:get('reportID', Req),
Report = Report =
case get_report_by_id(ReportID, Context) of case get_report_by_id(ReportID, Context) of
{ok, R} -> {ok, R} ->
@ -98,7 +98,7 @@ prepare(OperationID = 'DownloadFile', Req, Context) ->
Process = fun() -> process_request(OperationID, Context, Req) end, Process = fun() -> process_request(OperationID, Context, Req) end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'DownloadFileForParty', Req, Context) -> prepare(OperationID = 'DownloadFileForParty', Req, Context) ->
ReportID = maps:get(reportID, Req), ReportID = maps:get('reportID', Req),
Report = Report =
case get_report_by_id(ReportID, Context) of case get_report_by_id(ReportID, Context) of
{ok, R} -> {ok, R} ->
@ -107,7 +107,7 @@ prepare(OperationID = 'DownloadFileForParty', Req, Context) ->
undefined undefined
end, end,
Authorize = fun() -> Authorize = fun() ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
Prototypes = build_prototypes(OperationID, PartyID, Report, Req), Prototypes = build_prototypes(OperationID, PartyID, Report, Req),
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
end, end,
@ -126,7 +126,7 @@ process_request('GetReports', Context, Req) ->
get_reports(PartyID, Req, Context); get_reports(PartyID, Req, Context);
process_request('GetReportsForParty', Context, Req) -> process_request('GetReportsForParty', Context, Req) ->
UserID = capi_handler_utils:get_user_id(Context), UserID = capi_handler_utils:get_user_id(Context),
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() -> capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() ->
get_reports(PartyID, Req, Context) get_reports(PartyID, Req, Context)
end); end);
@ -135,7 +135,7 @@ process_request('GetReport', Context, Req) ->
get_report(PartyID, Req, Context); get_report(PartyID, Req, Context);
process_request('GetReportForParty', Context, Req) -> process_request('GetReportForParty', Context, Req) ->
UserID = capi_handler_utils:get_user_id(Context), UserID = capi_handler_utils:get_user_id(Context),
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() -> capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() ->
get_report(PartyID, Req, Context) get_report(PartyID, Req, Context)
end); end);
@ -144,7 +144,7 @@ process_request('CreateReport', Context, Req) ->
create_report(PartyID, Req, Context); create_report(PartyID, Req, Context);
process_request('CreateReportForParty', Context, Req) -> process_request('CreateReportForParty', Context, Req) ->
UserID = capi_handler_utils:get_user_id(Context), UserID = capi_handler_utils:get_user_id(Context),
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() -> capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() ->
create_report(PartyID, Req, Context) create_report(PartyID, Req, Context)
end); end);
@ -153,7 +153,7 @@ process_request('DownloadFile', Context, Req) ->
download_file(PartyID, Req, Context); download_file(PartyID, Req, Context);
process_request('DownloadFileForParty', Context, Req) -> process_request('DownloadFileForParty', Context, Req) ->
UserID = capi_handler_utils:get_user_id(Context), UserID = capi_handler_utils:get_user_id(Context),
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() -> capi_handler_utils:run_if_party_accessible(UserID, PartyID, fun() ->
download_file(PartyID, Req, Context) download_file(PartyID, Req, Context)
end). end).
@ -161,7 +161,7 @@ process_request('DownloadFileForParty', Context, Req) ->
%% %%
create_report(PartyID, Req, Context) -> create_report(PartyID, Req, Context) ->
ShopID = maps:get(shopID, Req), ShopID = maps:get('shopID', Req),
ReportParams = maps:get('ReportParams', Req), ReportParams = maps:get('ReportParams', Req),
ReportRequest = #reports_ReportRequest{ ReportRequest = #reports_ReportRequest{
party_id = PartyID, party_id = PartyID,
@ -183,15 +183,15 @@ create_report(PartyID, Req, Context) ->
case Exception of case Exception of
#reporter_base_InvalidRequest{errors = Errors} -> #reporter_base_InvalidRequest{errors = Errors} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors), FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidRequest', FormattedErrors)};
#reports_ShopNotFound{} -> #reports_ShopNotFound{} ->
{ok, logic_error(invalidShopID, <<"Shop not found">>)} {ok, logic_error('invalidShopID', <<"Shop not found">>)}
end end
end. end.
get_report(PartyID, Req, Context) -> get_report(PartyID, Req, Context) ->
ShopID = maps:get(shopID, Req), ShopID = maps:get('shopID', Req),
ReportID = maps:get(reportID, Req), ReportID = maps:get('reportID', Req),
Call = {reporting, 'GetReport', {ReportID}}, Call = {reporting, 'GetReport', {ReportID}},
case capi_handler_utils:service_call(Call, Context) of case capi_handler_utils:service_call(Call, Context) of
{ok, Report = #'reports_Report'{party_id = PartyID, shop_id = ShopID}} -> {ok, Report = #'reports_Report'{party_id = PartyID, shop_id = ShopID}} ->
@ -203,7 +203,7 @@ get_report(PartyID, Req, Context) ->
end. end.
get_reports(PartyID, Req, Context) -> get_reports(PartyID, Req, Context) ->
ShopID = maps:get(shopID, Req), ShopID = maps:get('shopID', Req),
FromTime = capi_handler_utils:get_time('fromTime', Req), FromTime = capi_handler_utils:get_time('fromTime', Req),
ToTime = capi_handler_utils:get_time('toTime', Req), ToTime = capi_handler_utils:get_time('toTime', Req),
ReportRequest = #reports_ReportRequest{ ReportRequest = #reports_ReportRequest{
@ -225,18 +225,18 @@ get_reports(PartyID, Req, Context) ->
case Exception of case Exception of
#reporter_base_InvalidRequest{errors = Errors} -> #reporter_base_InvalidRequest{errors = Errors} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors), FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidRequest', FormattedErrors)};
#reports_DatasetTooBig{limit = Limit} -> #reports_DatasetTooBig{limit = Limit} ->
{ok, logic_error(<<"limitExceeded">>, io_lib:format("Max limit: ~p", [Limit]))} {ok, logic_error('limitExceeded', io_lib:format("Max limit: ~p", [Limit]))}
end end
end. end.
download_file(PartyID, Req, Context) -> download_file(PartyID, Req, Context) ->
ShopID = maps:get(shopID, Req), ShopID = maps:get('shopID', Req),
ReportID = maps:get(reportID, Req), ReportID = maps:get('reportID', Req),
case get_report_by_id(ReportID, Context) of case get_report_by_id(ReportID, Context) of
{ok, #reports_Report{status = created, files = Files, party_id = PartyID, shop_id = ShopID}} -> {ok, #reports_Report{status = created, files = Files, party_id = PartyID, shop_id = ShopID}} ->
FileID = maps:get(fileID, Req), FileID = maps:get('fileID', Req),
case lists:keymember(FileID, #reports_FileMeta.file_id, Files) of case lists:keymember(FileID, #reports_FileMeta.file_id, Files) of
true -> true ->
generate_report_presigned_url(FileID, Context); generate_report_presigned_url(FileID, Context);
@ -263,7 +263,7 @@ generate_report_presigned_url(FileID, Context) ->
case Exception of case Exception of
#reporter_base_InvalidRequest{errors = Errors} -> #reporter_base_InvalidRequest{errors = Errors} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors), FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidRequest', FormattedErrors)};
#reports_FileNotFound{} -> #reports_FileNotFound{} ->
{ok, general_error(404, <<"File not found">>)} {ok, general_error(404, <<"File not found">>)}
end end
@ -310,9 +310,9 @@ decode_report_file_signature(#reports_Signature{md5 = MD5, sha256 = SHA256}) ->
#{<<"md5">> => MD5, <<"sha256">> => SHA256}. #{<<"md5">> => MD5, <<"sha256">> => SHA256}.
build_prototypes(OperationID, PartyID, Report, Req) -> build_prototypes(OperationID, PartyID, Report, Req) ->
ReportID = genlib_map:get(reportID, Req), ReportID = genlib_map:get('reportID', Req),
ShopID = genlib_map:get(shopID, Req), ShopID = genlib_map:get('shopID', Req),
FileID = genlib_map:get(fileID, Req), FileID = genlib_map:get('fileID', Req),
[ [
{operation, #{ {operation, #{
id => OperationID, id => OperationID,

View File

@ -129,9 +129,9 @@ process_search_request_result(QueryType, Result, Context, #{decode_fun := Decode
{ok, {200, #{}, Resp}}; {ok, {200, #{}, Resp}};
{exception, #'InvalidRequest'{errors = Errors}} -> {exception, #'InvalidRequest'{errors = Errors}} ->
FormattedErrors = capi_handler_utils:format_request_errors(Errors), FormattedErrors = capi_handler_utils:format_request_errors(Errors),
{ok, logic_error(invalidRequest, FormattedErrors)}; {ok, logic_error('invalidRequest', FormattedErrors)};
{exception, #merchstat_BadToken{}} -> {exception, #merchstat_BadToken{}} ->
{ok, logic_error(invalidRequest, <<"Invalid token">>)} {ok, logic_error('invalidRequest', <<"Invalid token">>)}
end. end.
%% %%
@ -466,7 +466,7 @@ decode_stat_payout_status({Status, _}) ->
decode_payout_tool_details(ToolInfo) -> decode_payout_tool_details(ToolInfo) ->
capi_handler_decoder_party:decode_payout_tool_details(ToolInfo). capi_handler_decoder_party:decode_payout_tool_details(ToolInfo).
decode_stat_refund(Refund, Context) -> decode_stat_refund(Refund, _Context) ->
capi_handler_utils:merge_and_compact( capi_handler_utils:merge_and_compact(
#{ #{
<<"invoiceID">> => Refund#merchstat_StatRefund.invoice_id, <<"invoiceID">> => Refund#merchstat_StatRefund.invoice_id,
@ -482,14 +482,14 @@ decode_stat_refund(Refund, Context) ->
), ),
<<"allocation">> => capi_allocation:decode(Refund#merchstat_StatRefund.allocation) <<"allocation">> => capi_allocation:decode(Refund#merchstat_StatRefund.allocation)
}, },
decode_stat_refund_status(Refund#merchstat_StatRefund.status, Context) decode_stat_refund_status(Refund#merchstat_StatRefund.status)
). ).
decode_stat_refund_status({Status, StatusInfo}, Context) -> decode_stat_refund_status({Status, StatusInfo}) ->
Error = Error =
case StatusInfo of case StatusInfo of
#merchstat_InvoicePaymentRefundFailed{failure = OperationFailure} -> #merchstat_InvoicePaymentRefundFailed{failure = OperationFailure} ->
capi_handler_decoder_utils:decode_operation_failure(OperationFailure, Context); capi_handler_decoder_utils:decode_operation_failure(OperationFailure);
_ -> _ ->
undefined undefined
end, end,

View File

@ -15,7 +15,7 @@
) -> {ok, capi_handler:request_state()} | {error, noimpl}. ) -> {ok, capi_handler:request_state()} | {error, noimpl}.
prepare(OperationID = 'ActivateShop', Req, Context) -> prepare(OperationID = 'ActivateShop', Req, Context) ->
PartyID = capi_handler_utils:get_party_id(Context), PartyID = capi_handler_utils:get_party_id(Context),
ShopID = maps:get(shopID, Req), ShopID = maps:get('shopID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}], Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}],
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
@ -24,19 +24,16 @@ prepare(OperationID = 'ActivateShop', Req, Context) ->
case capi_party:activate_shop(PartyID, ShopID, Context) of case capi_party:activate_shop(PartyID, ShopID, Context) of
ok -> ok ->
{ok, {204, #{}, undefined}}; {ok, {204, #{}, undefined}};
{error, Exception} -> {error, #payproc_ShopNotFound{}} ->
case Exception of {ok, general_error(404, <<"Shop not found">>)};
#payproc_ShopNotFound{} -> {error, #payproc_InvalidShopStatus{status = {suspension, {active, _}}}} ->
{ok, general_error(404, <<"Shop not found">>)}; {ok, {204, #{}, undefined}}
#payproc_InvalidShopStatus{status = {suspension, {active, _}}} ->
{ok, {204, #{}, undefined}}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'SuspendShop', Req, Context) -> prepare(OperationID = 'SuspendShop', Req, Context) ->
PartyID = capi_handler_utils:get_party_id(Context), PartyID = capi_handler_utils:get_party_id(Context),
ShopID = maps:get(shopID, Req), ShopID = maps:get('shopID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}], Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}],
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
@ -45,13 +42,10 @@ prepare(OperationID = 'SuspendShop', Req, Context) ->
case capi_party:suspend_shop(PartyID, ShopID, Context) of case capi_party:suspend_shop(PartyID, ShopID, Context) of
ok -> ok ->
{ok, {204, #{}, undefined}}; {ok, {204, #{}, undefined}};
{error, Exception} -> {error, #payproc_ShopNotFound{}} ->
case Exception of {ok, general_error(404, <<"Shop not found">>)};
#payproc_ShopNotFound{} -> {error, #payproc_InvalidShopStatus{status = {suspension, {suspended, _}}}} ->
{ok, general_error(404, <<"Shop not found">>)}; {ok, {204, #{}, undefined}}
#payproc_InvalidShopStatus{status = {suspension, {suspended, _}}} ->
{ok, {204, #{}, undefined}}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -68,7 +62,7 @@ prepare(OperationID = 'GetShops', _Req, Context) ->
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetShopByID', Req, Context) -> prepare(OperationID = 'GetShopByID', Req, Context) ->
PartyID = capi_handler_utils:get_party_id(Context), PartyID = capi_handler_utils:get_party_id(Context),
ShopID = maps:get(shopID, Req), ShopID = maps:get('shopID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}], Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}],
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
@ -83,7 +77,7 @@ prepare(OperationID = 'GetShopByID', Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetShopsForParty', Req, Context) -> prepare(OperationID = 'GetShopsForParty', Req, Context) ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID, party => PartyID}}], Prototypes = [{operation, #{id => OperationID, party => PartyID}}],
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
@ -100,8 +94,8 @@ prepare(OperationID = 'GetShopsForParty', Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetShopByIDForParty', Req, Context) -> prepare(OperationID = 'GetShopByIDForParty', Req, Context) ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
ShopID = maps:get(shopID, Req), ShopID = maps:get('shopID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}], Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}],
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
@ -120,8 +114,8 @@ prepare(OperationID = 'GetShopByIDForParty', Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'ActivateShopForParty', Req, Context) -> prepare(OperationID = 'ActivateShopForParty', Req, Context) ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
ShopID = maps:get(shopID, Req), ShopID = maps:get('shopID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}], Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}],
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
@ -130,23 +124,20 @@ prepare(OperationID = 'ActivateShopForParty', Req, Context) ->
case capi_party:activate_shop(PartyID, ShopID, Context) of case capi_party:activate_shop(PartyID, ShopID, Context) of
ok -> ok ->
{ok, {204, #{}, undefined}}; {ok, {204, #{}, undefined}};
{error, Exception} -> {error, #payproc_InvalidUser{}} ->
case Exception of {ok, general_error(404, <<"Party not found">>)};
#payproc_InvalidUser{} -> {error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)}; {ok, general_error(404, <<"Party not found">>)};
#payproc_PartyNotFound{} -> {error, #payproc_ShopNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)}; {ok, general_error(404, <<"Shop not found">>)};
#payproc_ShopNotFound{} -> {error, #payproc_InvalidShopStatus{status = {suspension, {active, _}}}} ->
{ok, general_error(404, <<"Shop not found">>)}; {ok, {204, #{}, undefined}}
#payproc_InvalidShopStatus{status = {suspension, {active, _}}} ->
{ok, {204, #{}, undefined}}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'SuspendShopForParty', Req, Context) -> prepare(OperationID = 'SuspendShopForParty', Req, Context) ->
PartyID = maps:get(partyID, Req), PartyID = maps:get('partyID', Req),
ShopID = maps:get(shopID, Req), ShopID = maps:get('shopID', Req),
Authorize = fun() -> Authorize = fun() ->
Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}], Prototypes = [{operation, #{id => OperationID, party => PartyID, shop => ShopID}}],
{ok, capi_auth:authorize_operation(Prototypes, Context)} {ok, capi_auth:authorize_operation(Prototypes, Context)}
@ -155,17 +146,14 @@ prepare(OperationID = 'SuspendShopForParty', Req, Context) ->
case capi_party:suspend_shop(PartyID, ShopID, Context) of case capi_party:suspend_shop(PartyID, ShopID, Context) of
ok -> ok ->
{ok, {204, #{}, undefined}}; {ok, {204, #{}, undefined}};
{error, Exception} -> {error, #payproc_InvalidUser{}} ->
case Exception of {ok, general_error(404, <<"Party not found">>)};
#payproc_InvalidUser{} -> {error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)}; {ok, general_error(404, <<"Party not found">>)};
#payproc_PartyNotFound{} -> {error, #payproc_ShopNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)}; {ok, general_error(404, <<"Shop not found">>)};
#payproc_ShopNotFound{} -> {error, #payproc_InvalidShopStatus{status = {suspension, {suspended, _}}}} ->
{ok, general_error(404, <<"Shop not found">>)}; {ok, {204, #{}, undefined}}
#payproc_InvalidShopStatus{status = {suspension, {suspended, _}}} ->
{ok, {204, #{}, undefined}}
end
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};

View File

@ -28,7 +28,7 @@
-export([get_time/2]). -export([get_time/2]).
-export([get_split_interval/2]). -export([get_split_interval/2]).
-export([get_time_diff/2]). -export([get_time_diff/2]).
-export([collect_events/5]). -export([collect_events/4]).
-export([unwrap_payment_session/1]). -export([unwrap_payment_session/1]).
-export([wrap_payment_session/2]). -export([wrap_payment_session/2]).
@ -54,22 +54,22 @@ general_error(Code, Message) ->
create_error_resp(Code, #{<<"message">> => genlib:to_binary(Message)}). create_error_resp(Code, #{<<"message">> => genlib:to_binary(Message)}).
-spec logic_error(term()) -> response(). -spec logic_error(term()) -> response().
logic_error(invalidPaymentToolToken) -> logic_error('invalidPaymentToolToken') ->
logic_error(invalidPaymentToolToken, <<"Specified payment tool token is invalid">>). logic_error('invalidPaymentToolToken', <<"Specified payment tool token is invalid">>).
-spec logic_error -spec logic_error
(term(), io_lib:chars() | binary()) -> response(); (term(), io_lib:chars() | binary()) -> response();
(term(), {binary(), binary() | undefined}) -> response(). (term(), {binary(), binary() | undefined}) -> response().
logic_error(externalIDConflict, {ID, undefined}) -> logic_error('externalIDConflict', {ID, undefined}) ->
logic_error(externalIDConflict, {ID, <<"undefined">>}); logic_error('externalIDConflict', {ID, <<"undefined">>});
logic_error(externalIDConflict, {ID, ExternalID}) -> logic_error('externalIDConflict', {ID, ExternalID}) ->
Data = #{ Data = #{
<<"externalID">> => ExternalID, <<"externalID">> => ExternalID,
<<"id">> => ID, <<"id">> => ID,
<<"message">> => <<"This 'externalID' has been used by another request">> <<"message">> => <<"This 'externalID' has been used by another request">>
}, },
create_error_resp(409, Data); create_error_resp(409, Data);
logic_error(externalIDConflict, ExternalID) -> logic_error('externalIDConflict', ExternalID) ->
Data = #{ Data = #{
<<"externalID">> => ExternalID, <<"externalID">> => ExternalID,
<<"message">> => <<"This 'externalID' has been used by another request">> <<"message">> => <<"This 'externalID' has been used by another request">>
@ -216,18 +216,17 @@ get_time_diff(From, To) ->
integer(), integer(),
integer(), integer(),
fun((_) -> {exception, _} | {ok, _}), fun((_) -> {exception, _} | {ok, _}),
fun((_, _) -> false | {true, #{binary() => binary() | [any()] | integer()}}), fun((_) -> false | {true, #{binary() => binary() | [any()] | integer()}})
undefined
) -> {ok, _} | {exception, _}. ) -> {ok, _} | {exception, _}.
collect_events(Limit, After, GetterFun, DecodeFun, Context) -> collect_events(Limit, After, GetterFun, DecodeFun) ->
collect_events([], Limit, After, GetterFun, DecodeFun, Context). collect_events([], Limit, After, GetterFun, DecodeFun).
collect_events(Collected, 0, _, _, _, _) -> collect_events(Collected, 0, _, _, _) ->
{ok, Collected}; {ok, Collected};
collect_events(Collected0, Left, After, GetterFun, DecodeFun, Context) when Left > 0 -> collect_events(Collected0, Left, After, GetterFun, DecodeFun) when Left > 0 ->
case get_events(Left, After, GetterFun) of case get_events(Left, After, GetterFun) of
{ok, Events} -> {ok, Events} ->
Filtered = decode_and_filter_events(DecodeFun, Context, Events), Filtered = decode_and_filter_events(DecodeFun, Events),
Collected = Collected0 ++ Filtered, Collected = Collected0 ++ Filtered,
case length(Events) of case length(Events) of
Left -> Left ->
@ -236,8 +235,7 @@ collect_events(Collected0, Left, After, GetterFun, DecodeFun, Context) when Left
Left - length(Filtered), Left - length(Filtered),
get_last_event_id(Events), get_last_event_id(Events),
GetterFun, GetterFun,
DecodeFun, DecodeFun
Context
); );
N when N < Left -> N when N < Left ->
{ok, Collected} {ok, Collected}
@ -246,10 +244,10 @@ collect_events(Collected0, Left, After, GetterFun, DecodeFun, Context) when Left
Error Error
end. end.
decode_and_filter_events(DecodeFun, Context, Events) -> decode_and_filter_events(DecodeFun, Events) ->
lists:foldr( lists:foldr(
fun(Event, Acc) -> fun(Event, Acc) ->
case DecodeFun(Event, Context) of case DecodeFun(Event) of
{true, Ev} -> {true, Ev} ->
[Ev | Acc]; [Ev | Acc];
false -> false ->

View File

@ -28,16 +28,17 @@ prepare('CreateWebhook' = OperationID, Req, Context) ->
ShopID = validate_webhook_params(WebhookParams), ShopID = validate_webhook_params(WebhookParams),
case capi_party:get_shop(PartyID, ShopID, Context) of case capi_party:get_shop(PartyID, ShopID, Context) of
{ok, _} -> {ok, _} ->
case capi_handler_utils:service_call({webhook_manager, 'Create', {WebhookParams}}, Context) of ok;
{ok, Webhook} ->
{ok, {201, #{}, decode_webhook(Webhook)}};
{exception, #webhooker_LimitExceeded{}} ->
{ok, general_error(429, <<"Webhook limit exceeded">>)}
end;
{error, #payproc_InvalidUser{}} -> {error, #payproc_InvalidUser{}} ->
{ok, logic_error(invalidPartyID, <<"Party not found">>)}; capi_handler:respond(logic_error('invalidPartyID', <<"Party not found">>));
{error, #payproc_ShopNotFound{}} -> {error, #payproc_ShopNotFound{}} ->
{ok, logic_error(invalidShopID, <<"Shop not found">>)} capi_handler:respond(logic_error('invalidShopID', <<"Shop not found">>))
end,
case capi_handler_utils:service_call({webhook_manager, 'Create', {WebhookParams}}, Context) of
{ok, Webhook} ->
{ok, {201, #{}, decode_webhook(Webhook)}};
{exception, #webhooker_LimitExceeded{}} ->
{ok, general_error(429, <<"Webhook limit exceeded">>)}
end end
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
@ -56,7 +57,7 @@ prepare('GetWebhooks' = OperationID, _Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('GetWebhookByID' = OperationID, Req, Context) -> prepare('GetWebhookByID' = OperationID, Req, Context) ->
WebhookID = maps:get(webhookID, Req), WebhookID = maps:get('webhookID', Req),
Webhook = Webhook =
case encode_webhook_id(WebhookID) of case encode_webhook_id(WebhookID) of
{ok, ID} -> {ok, ID} ->
@ -83,7 +84,7 @@ prepare('GetWebhookByID' = OperationID, Req, Context) ->
end, end,
{ok, #{authorize => Authorize, process => Process}}; {ok, #{authorize => Authorize, process => Process}};
prepare('DeleteWebhookByID' = OperationID, Req, Context) -> prepare('DeleteWebhookByID' = OperationID, Req, Context) ->
WebhookID = maps:get(webhookID, Req), WebhookID = maps:get('webhookID', Req),
{EncodedWebhookID, Webhook} = {EncodedWebhookID, Webhook} =
case encode_webhook_id(WebhookID) of case encode_webhook_id(WebhookID) of
{ok, ID} -> {ok, ID} ->
@ -177,53 +178,53 @@ encode_webhook_scope(#{<<"topic">> := <<"CustomersTopic">>, <<"shopID">> := Shop
types = ordsets:from_list([encode_customer_event_type(V) || V <- EventTypes]) types = ordsets:from_list([encode_customer_event_type(V) || V <- EventTypes])
}}. }}.
-define(invpaid(), {paid, #webhooker_InvoicePaid{}}). -define(INVPAID(), {paid, #webhooker_InvoicePaid{}}).
-define(invcancelled(), {cancelled, #webhooker_InvoiceCancelled{}}). -define(INVCANCELLED(), {cancelled, #webhooker_InvoiceCancelled{}}).
-define(invfulfilled(), {fulfilled, #webhooker_InvoiceFulfilled{}}). -define(INVFULFILLED(), {fulfilled, #webhooker_InvoiceFulfilled{}}).
-define(pmtprocessed(), {processed, #webhooker_InvoicePaymentProcessed{}}). -define(PMTPROCESSED(), {processed, #webhooker_InvoicePaymentProcessed{}}).
-define(pmtcaptured(), {captured, #webhooker_InvoicePaymentCaptured{}}). -define(PMTCAPTURED(), {captured, #webhooker_InvoicePaymentCaptured{}}).
-define(pmtcancelled(), {cancelled, #webhooker_InvoicePaymentCancelled{}}). -define(PMTCANCELLED(), {cancelled, #webhooker_InvoicePaymentCancelled{}}).
-define(pmtrefunded(), {refunded, #webhooker_InvoicePaymentRefunded{}}). -define(PMTREFUNDED(), {refunded, #webhooker_InvoicePaymentRefunded{}}).
-define(pmtfailed(), {failed, #webhooker_InvoicePaymentFailed{}}). -define(PMTFAILED(), {failed, #webhooker_InvoicePaymentFailed{}}).
-define(pmtrfndcreated(), {invoice_payment_refund_created, #webhooker_InvoicePaymentRefundCreated{}}). -define(PMTRFNDCREATED(), {invoice_payment_refund_created, #webhooker_InvoicePaymentRefundCreated{}}).
-define(pmtrfndstatus(Value), -define(PMTRFNDSTATUS(Value),
{ {
invoice_payment_refund_status_changed, invoice_payment_refund_status_changed,
#webhooker_InvoicePaymentRefundStatusChanged{value = Value} #webhooker_InvoicePaymentRefundStatusChanged{value = Value}
} }
). ).
-define(pmtrfndfailed(), {failed, #webhooker_InvoicePaymentRefundFailed{}}). -define(PMTRFNDFAILED(), {failed, #webhooker_InvoicePaymentRefundFailed{}}).
-define(pmtrfndsucceeded(), {succeeded, #webhooker_InvoicePaymentRefundSucceeded{}}). -define(PMTRFNDSUCCEEDED(), {succeeded, #webhooker_InvoicePaymentRefundSucceeded{}}).
encode_invoice_event_type(<<"InvoiceCreated">>) -> encode_invoice_event_type(<<"InvoiceCreated">>) ->
{created, #webhooker_InvoiceCreated{}}; {created, #webhooker_InvoiceCreated{}};
encode_invoice_event_type(<<"InvoicePaid">>) -> encode_invoice_event_type(<<"InvoicePaid">>) ->
{status_changed, #webhooker_InvoiceStatusChanged{value = ?invpaid()}}; {status_changed, #webhooker_InvoiceStatusChanged{value = ?INVPAID()}};
encode_invoice_event_type(<<"InvoiceCancelled">>) -> encode_invoice_event_type(<<"InvoiceCancelled">>) ->
{status_changed, #webhooker_InvoiceStatusChanged{value = ?invcancelled()}}; {status_changed, #webhooker_InvoiceStatusChanged{value = ?INVCANCELLED()}};
encode_invoice_event_type(<<"InvoiceFulfilled">>) -> encode_invoice_event_type(<<"InvoiceFulfilled">>) ->
{status_changed, #webhooker_InvoiceStatusChanged{value = ?invfulfilled()}}; {status_changed, #webhooker_InvoiceStatusChanged{value = ?INVFULFILLED()}};
encode_invoice_event_type(<<"PaymentStarted">>) -> encode_invoice_event_type(<<"PaymentStarted">>) ->
{payment, {created, #webhooker_InvoicePaymentCreated{}}}; {payment, {created, #webhooker_InvoicePaymentCreated{}}};
encode_invoice_event_type(<<"PaymentProcessed">>) -> encode_invoice_event_type(<<"PaymentProcessed">>) ->
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?pmtprocessed()}}}; {payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?PMTPROCESSED()}}};
encode_invoice_event_type(<<"PaymentCaptured">>) -> encode_invoice_event_type(<<"PaymentCaptured">>) ->
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?pmtcaptured()}}}; {payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?PMTCAPTURED()}}};
encode_invoice_event_type(<<"PaymentCancelled">>) -> encode_invoice_event_type(<<"PaymentCancelled">>) ->
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?pmtcancelled()}}}; {payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?PMTCANCELLED()}}};
encode_invoice_event_type(<<"PaymentRefunded">>) -> encode_invoice_event_type(<<"PaymentRefunded">>) ->
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?pmtrefunded()}}}; {payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?PMTREFUNDED()}}};
encode_invoice_event_type(<<"PaymentFailed">>) -> encode_invoice_event_type(<<"PaymentFailed">>) ->
{payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?pmtfailed()}}}; {payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = ?PMTFAILED()}}};
encode_invoice_event_type(<<"PaymentRefundCreated">>) -> encode_invoice_event_type(<<"PaymentRefundCreated">>) ->
{payment, {invoice_payment_refund_change, ?pmtrfndcreated()}}; {payment, {invoice_payment_refund_change, ?PMTRFNDCREATED()}};
encode_invoice_event_type(<<"PaymentRefundFailed">>) -> encode_invoice_event_type(<<"PaymentRefundFailed">>) ->
{payment, {invoice_payment_refund_change, ?pmtrfndstatus(?pmtrfndfailed())}}; {payment, {invoice_payment_refund_change, ?PMTRFNDSTATUS(?PMTRFNDFAILED())}};
encode_invoice_event_type(<<"PaymentRefundSucceeded">>) -> encode_invoice_event_type(<<"PaymentRefundSucceeded">>) ->
{payment, {invoice_payment_refund_change, ?pmtrfndstatus(?pmtrfndsucceeded())}}. {payment, {invoice_payment_refund_change, ?PMTRFNDSTATUS(?PMTRFNDSUCCEEDED())}}.
encode_customer_event_type(<<"CustomerCreated">>) -> encode_customer_event_type(<<"CustomerCreated">>) ->
{created, #webhooker_CustomerCreated{}}; {created, #webhooker_CustomerCreated{}};
@ -269,9 +270,9 @@ decode_invoice_event_type({status_changed, #webhooker_InvoiceStatusChanged{value
[ [
decode_invoice_status_event_type(V) decode_invoice_status_event_type(V)
|| V <- [ || V <- [
?invpaid(), ?INVPAID(),
?invcancelled(), ?INVCANCELLED(),
?invfulfilled() ?INVFULFILLED()
] ]
]; ];
decode_invoice_event_type({status_changed, #webhooker_InvoiceStatusChanged{value = Value}}) -> decode_invoice_event_type({status_changed, #webhooker_InvoiceStatusChanged{value = Value}}) ->
@ -283,32 +284,32 @@ decode_invoice_event_type({payment, {status_changed, #webhooker_InvoicePaymentSt
[ [
decode_payment_status_event_type(V) decode_payment_status_event_type(V)
|| V <- [ || V <- [
?pmtprocessed(), ?PMTPROCESSED(),
?pmtcaptured(), ?PMTCAPTURED(),
?pmtcancelled(), ?PMTCANCELLED(),
?pmtrefunded(), ?PMTREFUNDED(),
?pmtfailed() ?PMTFAILED()
] ]
]; ];
decode_invoice_event_type({payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = Value}}}) -> decode_invoice_event_type({payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = Value}}}) ->
[decode_payment_status_event_type(Value)]; [decode_payment_status_event_type(Value)];
decode_invoice_event_type({payment, {invoice_payment_refund_change, ?pmtrfndcreated()}}) -> decode_invoice_event_type({payment, {invoice_payment_refund_change, ?PMTRFNDCREATED()}}) ->
[<<"PaymentRefundCreated">>]; [<<"PaymentRefundCreated">>];
decode_invoice_event_type({payment, {invoice_payment_refund_change, ?pmtrfndstatus(Value)}}) -> decode_invoice_event_type({payment, {invoice_payment_refund_change, ?PMTRFNDSTATUS(Value)}}) ->
[decode_payment_refund_status_event_type(Value)]. [decode_payment_refund_status_event_type(Value)].
decode_invoice_status_event_type(?invpaid()) -> <<"InvoicePaid">>; decode_invoice_status_event_type(?INVPAID()) -> <<"InvoicePaid">>;
decode_invoice_status_event_type(?invcancelled()) -> <<"InvoiceCancelled">>; decode_invoice_status_event_type(?INVCANCELLED()) -> <<"InvoiceCancelled">>;
decode_invoice_status_event_type(?invfulfilled()) -> <<"InvoiceFulfilled">>. decode_invoice_status_event_type(?INVFULFILLED()) -> <<"InvoiceFulfilled">>.
decode_payment_status_event_type(?pmtprocessed()) -> <<"PaymentProcessed">>; decode_payment_status_event_type(?PMTPROCESSED()) -> <<"PaymentProcessed">>;
decode_payment_status_event_type(?pmtcaptured()) -> <<"PaymentCaptured">>; decode_payment_status_event_type(?PMTCAPTURED()) -> <<"PaymentCaptured">>;
decode_payment_status_event_type(?pmtcancelled()) -> <<"PaymentCancelled">>; decode_payment_status_event_type(?PMTCANCELLED()) -> <<"PaymentCancelled">>;
decode_payment_status_event_type(?pmtrefunded()) -> <<"PaymentRefunded">>; decode_payment_status_event_type(?PMTREFUNDED()) -> <<"PaymentRefunded">>;
decode_payment_status_event_type(?pmtfailed()) -> <<"PaymentFailed">>. decode_payment_status_event_type(?PMTFAILED()) -> <<"PaymentFailed">>.
decode_payment_refund_status_event_type(?pmtrfndfailed()) -> <<"PaymentRefundFailed">>; decode_payment_refund_status_event_type(?PMTRFNDFAILED()) -> <<"PaymentRefundFailed">>;
decode_payment_refund_status_event_type(?pmtrfndsucceeded()) -> <<"PaymentRefundSucceeded">>. decode_payment_refund_status_event_type(?PMTRFNDSUCCEEDED()) -> <<"PaymentRefundSucceeded">>.
decode_customer_event_type({created, #webhooker_CustomerCreated{}}) -> decode_customer_event_type({created, #webhooker_CustomerCreated{}}) ->
<<"CustomerCreated">>; <<"CustomerCreated">>;

View File

@ -6,6 +6,8 @@
-export([marshal/1]). -export([marshal/1]).
-export([unmarshal/1]). -export([unmarshal/1]).
-export_type([value/0]).
%% %%
-type value() :: term(). -type value() :: term().

View File

@ -77,15 +77,18 @@ mk_operation_id_getter(#{env := Env}) ->
(Req = #{host := _Host, path := _Path}) -> (Req = #{host := _Host, path := _Path}) ->
case cowboy_router:execute(Req, Env) of case cowboy_router:execute(Req, Env) of
{ok, _, #{handler_opts := {_Operations, _LogicHandler, _SwaggerHandlerOpts} = HandlerOpts}} -> {ok, _, #{handler_opts := {_Operations, _LogicHandler, _SwaggerHandlerOpts} = HandlerOpts}} ->
case swag_server_utils:get_operation_id(Req, HandlerOpts) of try_get_operation_id(Req, HandlerOpts);
undefined ->
#{};
OperationID ->
#{operation_id => OperationID}
end;
_ -> _ ->
#{} #{}
end; end;
(_Req) -> (_Req) ->
#{} #{}
end. end.
try_get_operation_id(Req, HandlerOpts) ->
case swag_server_utils:get_operation_id(Req, HandlerOpts) of
undefined ->
#{};
OperationID ->
#{operation_id => OperationID}
end.

View File

@ -324,7 +324,7 @@ merge_deduplication_card_test() ->
], ],
SamsungPayMethod = #{ SamsungPayMethod = #{
<<"method">> => <<"BankCard">>, <<"method">> => <<"BankCard">>,
<<"PaymentSystems">> => Systems1, <<"paymentSystems">> => Systems1,
<<"tokenProviders">> => [<<"samsungpay">>] <<"tokenProviders">> => [<<"samsungpay">>]
}, },
Methods = [ Methods = [

View File

@ -31,7 +31,7 @@
get_customer_forbidden_notfound/1 get_customer_forbidden_notfound/1
]). ]).
-define(emptyresp(Code), {error, {Code, #{}}}). -define(EMPTYRESP(Code), {error, {Code, #{}}}).
-type test_case_name() :: atom(). -type test_case_name() :: atom().
-type config() :: [{atom(), any()}]. -type config() :: [{atom(), any()}].
@ -113,13 +113,13 @@ end_per_group(_Group, C) ->
authorization_error_no_header_test(Config) -> authorization_error_no_header_test(Config) ->
Token = <<>>, Token = <<>>,
_ = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), Config), _ = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), Config),
?emptyresp(401) = capi_client_categories:get_categories(capi_ct_helper:get_context(Token)). ?EMPTYRESP(401) = capi_client_categories:get_categories(capi_ct_helper:get_context(Token)).
-spec authorization_error_no_permission_test(config()) -> _. -spec authorization_error_no_permission_test(config()) -> _.
authorization_error_no_permission_test(Config) -> authorization_error_no_permission_test(Config) ->
Token = ?API_TOKEN, Token = ?API_TOKEN,
_ = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_forbidden(), Config), _ = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_forbidden(), Config),
?emptyresp(401) = capi_client_parties:get_my_party(capi_ct_helper:get_context(Token)). ?EMPTYRESP(401) = capi_client_parties:get_my_party(capi_ct_helper:get_context(Token)).
%%% %%%

View File

@ -98,7 +98,6 @@
get_webhooks/1, get_webhooks/1,
get_webhook_by_id/1, get_webhook_by_id/1,
delete_webhook_by_id/1, delete_webhook_by_id/1,
get_locations_names_ok_test/1,
search_invoices_ok_test/1, search_invoices_ok_test/1,
search_payments_ok_test/1, search_payments_ok_test/1,
search_refunds_ok_test/1, search_refunds_ok_test/1,
@ -126,6 +125,7 @@
get_payment_institution_payment_terms/1, get_payment_institution_payment_terms/1,
get_payment_institution_payout_terms/1, get_payment_institution_payout_terms/1,
get_payment_institution_payout_schedules/1, get_payment_institution_payout_schedules/1,
get_service_provider_by_id/1,
check_no_payment_by_external_id_test/1, check_no_payment_by_external_id_test/1,
check_no_internal_id_for_external_id_test/1, check_no_internal_id_for_external_id_test/1,
retrieve_payment_by_external_id_test/1, retrieve_payment_by_external_id_test/1,
@ -198,8 +198,6 @@ groups() ->
activate_shop_ok_test, activate_shop_ok_test,
suspend_shop_ok_test, suspend_shop_ok_test,
get_locations_names_ok_test,
get_account_by_id_ok_test, get_account_by_id_ok_test,
get_categories_ok_test, get_categories_ok_test,
@ -247,6 +245,7 @@ groups() ->
get_payment_institution_payment_terms, get_payment_institution_payment_terms,
get_payment_institution_payout_terms, get_payment_institution_payout_terms,
get_payment_institution_payout_schedules, get_payment_institution_payout_schedules,
get_service_provider_by_id,
get_category_by_ref_ok_test, get_category_by_ref_ok_test,
get_schedule_by_ref_ok_test, get_schedule_by_ref_ok_test,
@ -1905,19 +1904,6 @@ delete_webhook_by_id(Config) ->
), ),
ok = capi_client_webhooks:delete_webhook_by_id(?config(context, Config), ?INTEGER_BINARY). ok = capi_client_webhooks:delete_webhook_by_id(?config(context, Config), ?INTEGER_BINARY).
-spec get_locations_names_ok_test(config()) -> _.
get_locations_names_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[{geo_ip_service, fun('GetLocationName', _) -> {ok, #{123 => ?STRING}} end}],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_op_ctx(<<"GetLocationsNames">>, Config),
Query = #{
<<"geoIDs">> => <<"5,3,6,5,4">>,
<<"language">> => <<"ru">>
},
{ok, _} = capi_client_geo:get_location_names(?config(context, Config), Query).
-spec search_invoices_ok_test(config()) -> _. -spec search_invoices_ok_test(config()) -> _.
search_invoices_ok_test(Config) -> search_invoices_ok_test(Config) ->
_ = capi_ct_helper:mock_services( _ = capi_ct_helper:mock_services(
@ -1945,23 +1931,23 @@ search_invoices_ok_test_(BankCardTokenProvider, Config) ->
{limit, 2}, {limit, 2},
{from_time, {{2015, 08, 11}, {19, 42, 35}}}, {from_time, {{2015, 08, 11}, {19, 42, 35}}},
{to_time, {{2020, 08, 11}, {19, 42, 35}}}, {to_time, {{2020, 08, 11}, {19, 42, 35}}},
{invoiceStatus, <<"fulfilled">>}, {'invoiceStatus', <<"fulfilled">>},
{payerEmail, <<"test@test.ru">>}, {'payerEmail', <<"test@test.ru">>},
{payerIP, <<"192.168.0.1">>}, {'payerIP', <<"192.168.0.1">>},
{paymentStatus, <<"processed">>}, {'paymentStatus', <<"processed">>},
{paymentFlow, <<"instant">>}, {'paymentFlow', <<"instant">>},
{paymentMethod, <<"bankCard">>}, {'paymentMethod', <<"bankCard">>},
{invoiceID, <<"testInvoiceID">>}, {'invoiceID', <<"testInvoiceID">>},
{paymentID, <<"testPaymentID">>}, {'paymentID', <<"testPaymentID">>},
{customerID, <<"testCustomerID">>}, {'customerID', <<"testCustomerID">>},
{payerFingerprint, <<"blablablalbalbal">>}, {'payerFingerprint', <<"blablablalbalbal">>},
{first6, <<"424242">>}, {'first6', <<"424242">>},
{last4, <<"2222">>}, {'last4', <<"2222">>},
{rrn, <<"090909090909">>}, {'rrn', <<"090909090909">>},
{bankCardTokenProvider, BankCardTokenProvider}, {'bankCardTokenProvider', BankCardTokenProvider},
{bankCardPaymentSystem, <<"visa">>}, {'bankCardPaymentSystem', <<"visa">>},
{paymentAmount, 10000}, {'paymentAmount', 10000},
{continuationToken, <<"come_back_next_time">>} {'continuationToken', <<"come_back_next_time">>}
], ],
{ok, _, _} = capi_client_searches:search_invoices(?config(context, Config), ?STRING, Query), {ok, _, _} = capi_client_searches:search_invoices(?config(context, Config), ?STRING, Query),
ok. ok.
@ -1991,22 +1977,22 @@ search_payments_ok_(BankCardTokenProvider, Config) ->
{limit, 2}, {limit, 2},
{from_time, {{2015, 08, 11}, {19, 42, 35}}}, {from_time, {{2015, 08, 11}, {19, 42, 35}}},
{to_time, {{2020, 08, 11}, {19, 42, 35}}}, {to_time, {{2020, 08, 11}, {19, 42, 35}}},
{payerEmail, <<"test@test.ru">>}, {'payerEmail', <<"test@test.ru">>},
{payerIP, <<"192.168.0.1">>}, {'payerIP', <<"192.168.0.1">>},
{paymentStatus, <<"processed">>}, {'paymentStatus', <<"processed">>},
{paymentFlow, <<"instant">>}, {'paymentFlow', <<"instant">>},
{paymentMethod, <<"bankCard">>}, {'paymentMethod', <<"bankCard">>},
{invoiceID, <<"testInvoiceID">>}, {'invoiceID', <<"testInvoiceID">>},
{paymentID, <<"testPaymentID">>}, {'paymentID', <<"testPaymentID">>},
{payerFingerprint, <<"blablablalbalbal">>}, {'payerFingerprint', <<"blablablalbalbal">>},
{first6, <<"424242">>}, {'first6', <<"424242">>},
{last4, <<"2222">>}, {'last4', <<"2222">>},
{rrn, <<"090909090909">>}, {'rrn', <<"090909090909">>},
{approvalCode, <<"808080">>}, {'approvalCode', <<"808080">>},
{bankCardTokenProvider, BankCardTokenProvider}, {'bankCardTokenProvider', BankCardTokenProvider},
{bankCardPaymentSystem, <<"visa">>}, {'bankCardPaymentSystem', <<"visa">>},
{paymentAmount, 10000}, {'paymentAmount', 10000},
{continuationToken, <<"come_back_next_time">>} {'continuationToken', <<"come_back_next_time">>}
], ],
{ok, _, _} = capi_client_searches:search_payments(?config(context, Config), ?STRING, Query), {ok, _, _} = capi_client_searches:search_payments(?config(context, Config), ?STRING, Query),
ok. ok.
@ -2036,13 +2022,13 @@ search_refunds_ok_test(Config) ->
{offset, 2}, {offset, 2},
{from_time, {{2015, 08, 11}, {19, 42, 35}}}, {from_time, {{2015, 08, 11}, {19, 42, 35}}},
{to_time, {{2020, 08, 11}, {19, 42, 35}}}, {to_time, {{2020, 08, 11}, {19, 42, 35}}},
{shopID, ShopID}, {'shopID', ShopID},
{invoiceID, <<"testInvoiceID">>}, {'invoiceID', <<"testInvoiceID">>},
{paymentID, <<"testPaymentID">>}, {'paymentID', <<"testPaymentID">>},
{refundID, <<"testRefundID">>}, {'refundID', <<"testRefundID">>},
% {rrn, <<"090909090909">>}, % {rrn, <<"090909090909">>},
% {approvalCode, <<"808080">>}, % {approvalCode, <<"808080">>},
{refundStatus, <<"succeeded">>} {'refundStatus', <<"succeeded">>}
], ],
{ok, _, _} = capi_client_searches:search_refunds(?config(context, Config), ShopID, Query). {ok, _, _} = capi_client_searches:search_refunds(?config(context, Config), ShopID, Query).
@ -2066,8 +2052,8 @@ search_payouts_ok_test(Config) ->
{offset, 2}, {offset, 2},
{from_time, {{2015, 08, 11}, {19, 42, 35}}}, {from_time, {{2015, 08, 11}, {19, 42, 35}}},
{to_time, {{2020, 08, 11}, {19, 42, 35}}}, {to_time, {{2020, 08, 11}, {19, 42, 35}}},
{payoutID, <<"testPayoutID">>}, {'payoutID', <<"testPayoutID">>},
{payoutToolType, <<"Wallet">>} {'payoutToolType', <<"Wallet">>}
], ],
{ok, _, _} = capi_client_searches:search_payouts(?config(context, Config), ShopID, Query). {ok, _, _} = capi_client_searches:search_payouts(?config(context, Config), ShopID, Query).
@ -2164,7 +2150,7 @@ get_payment_method_stats_ok_test(Config) ->
{to_time, {{2020, 08, 11}, {19, 42, 35}}}, {to_time, {{2020, 08, 11}, {19, 42, 35}}},
{split_unit, minute}, {split_unit, minute},
{split_size, 1}, {split_size, 1},
{paymentMethod, <<"bankCard">>} {'paymentMethod', <<"bankCard">>}
], ],
{ok, _} = capi_client_analytics:get_payment_method_stats(?config(context, Config), ?STRING, Query). {ok, _} = capi_client_analytics:get_payment_method_stats(?config(context, Config), ?STRING, Query).
@ -2497,6 +2483,26 @@ get_payment_institution_payout_schedules(Config) ->
<<"BankAccount">> <<"BankAccount">>
). ).
-spec get_service_provider_by_id(config()) -> _.
get_service_provider_by_id(Config) ->
_ = capi_ct_helper_bouncer:mock_assert_op_ctx(<<"GetServiceProviderByID">>, Config),
?assertEqual(
{ok, #{
<<"id">> => <<"qiwi">>,
<<"brandName">> => <<"QIWI">>,
<<"category">> => <<"wallets">>,
<<"metadata">> => #{
<<"test.ns">> => #{
<<"answer">> => 42,
<<"localization">> => #{
<<"ru_RU">> => [<<"КИВИ Кошелёк">>]
}
}
}
}},
capi_client_payment_institutions:get_service_provider_by_id(?config(context, Config), <<"qiwi">>)
).
-spec get_country_by_id_test(config()) -> _. -spec get_country_by_id_test(config()) -> _.
get_country_by_id_test(Config) -> get_country_by_id_test(Config) ->
_ = capi_ct_helper_bouncer:mock_assert_op_ctx(<<"GetCountryByID">>, Config), _ = capi_ct_helper_bouncer:mock_assert_op_ctx(<<"GetCountryByID">>, Config),

View File

@ -28,8 +28,8 @@
-define(CAPI_HOST_NAME, "localhost"). -define(CAPI_HOST_NAME, "localhost").
-define(CAPI_URL, ?CAPI_HOST_NAME ++ ":" ++ integer_to_list(?CAPI_PORT)). -define(CAPI_URL, ?CAPI_HOST_NAME ++ ":" ++ integer_to_list(?CAPI_PORT)).
-define(TK_META_NS_KEYCLOAK, <<"test.rbkmoney.keycloak">>). -define(TK_META_NS_KEYCLOAK, <<"dev.vality.keycloak">>).
-define(TK_META_NS_APIKEYMGMT, <<"test.rbkmoney.apikeymgmt">>). -define(TK_META_NS_APIKEYMGMT, <<"dev.vality.apikeymgmt">>).
%% %%
-type config() :: [{atom(), any()}]. -type config() :: [{atom(), any()}].
@ -190,26 +190,28 @@ mock_services(Services, SupOrConfig) ->
replace_env(Env) -> replace_env(Env) ->
maps:fold( maps:fold(
fun(App, AppEnv, Acc) -> fun(App, AppEnv, Acc) ->
AppReplaces = AppReplaces = replace_env(App, AppEnv),
maps:fold(
fun(Key, Value, AppAcc) ->
AccValue =
case application:get_env(App, Key) of
undefined -> undefined;
{ok, Original} -> {value, Original}
end,
application:set_env(App, Key, Value),
AppAcc#{Key => AccValue}
end,
#{},
AppEnv
),
Acc#{App => AppReplaces} Acc#{App => AppReplaces}
end, end,
#{}, #{},
Env Env
). ).
replace_env(App, AppEnv) ->
maps:fold(
fun(Key, Value, Acc) ->
AccValue =
case application:get_env(App, Key) of
undefined -> undefined;
{ok, Original} -> {value, Original}
end,
application:set_env(App, Key, Value),
Acc#{Key => AccValue}
end,
#{},
AppEnv
).
-spec restore_env(replaces()) -> ok. -spec restore_env(replaces()) -> ok.
restore_env(Replaces) -> restore_env(Replaces) ->
maps:foreach( maps:foreach(

View File

@ -89,7 +89,7 @@ mock_invoice_access_token(PartyID, InvoiceID, SupOrConfig) ->
token => #{id => ?STRING}, token => #{id => ?STRING},
scope => [#{party => #{id => PartyID}, invoice => #{id => InvoiceID}}] scope => [#{party => #{id => PartyID}, invoice => #{id => InvoiceID}}]
}, },
{<<"com.rbkmoney.capi">>, create_bouncer_context(AuthParams), [ {<<"dev.vality.capi">>, create_bouncer_context(AuthParams), [
api_key_metadata(), consumer_metadata(<<"client">>) api_key_metadata(), consumer_metadata(<<"client">>)
]} ]}
end), end),
@ -104,7 +104,7 @@ mock_invoice_template_access_token(PartyID, InvoiceTemplateID, SupOrConfig) ->
token => #{id => ?STRING}, token => #{id => ?STRING},
scope => [#{party => #{id => PartyID}, invoice_template => #{id => InvoiceTemplateID}}] scope => [#{party => #{id => PartyID}, invoice_template => #{id => InvoiceTemplateID}}]
}, },
{<<"com.rbkmoney.capi">>, create_bouncer_context(AuthParams), api_key_metadata()} {<<"dev.vality.capi">>, create_bouncer_context(AuthParams), api_key_metadata()}
end), end),
mock_token(Handler, SupOrConfig). mock_token(Handler, SupOrConfig).
@ -117,7 +117,7 @@ mock_customer_access_token(PartyID, CustomerID, SupOrConfig) ->
token => #{id => ?STRING}, token => #{id => ?STRING},
scope => [#{party => #{id => PartyID}, customer => #{id => CustomerID}}] scope => [#{party => #{id => PartyID}, customer => #{id => CustomerID}}]
}, },
{<<"com.rbkmoney.capi">>, create_bouncer_context(AuthParams), api_key_metadata()} {<<"dev.vality.capi">>, create_bouncer_context(AuthParams), api_key_metadata()}
end), end),
mock_token(Handler, SupOrConfig). mock_token(Handler, SupOrConfig).

View File

@ -22,7 +22,7 @@
deadline_relative_ok_test/1 deadline_relative_ok_test/1
]). ]).
-define(badresp(Code), {error, {invalid_response_code, Code}}). -define(BADRESP(Code), {error, {invalid_response_code, Code}}).
-type test_case_name() :: atom(). -type test_case_name() :: atom().
-type config() :: [{atom(), any()}]. -type config() :: [{atom(), any()}].
@ -106,7 +106,7 @@ deadline_absolute_ok_test(Config) ->
Config Config
), ),
Deadline = woody_deadline:from_timeout(3000), Deadline = woody_deadline:from_timeout(3000),
?badresp(504) = capi_client_invoices:get_invoice_by_id(Context#{deadline => Deadline}, ?STRING), ?BADRESP(504) = capi_client_invoices:get_invoice_by_id(Context#{deadline => Deadline}, ?STRING),
Deadline2 = woody_deadline:from_timeout(3000), Deadline2 = woody_deadline:from_timeout(3000),
{ok, _} = capi_client_categories:get_categories(Context#{deadline => Deadline2}). {ok, _} = capi_client_categories:get_categories(Context#{deadline => Deadline2}).
@ -123,5 +123,5 @@ deadline_relative_ok_test(Config) ->
], ],
Config Config
), ),
?badresp(504) = capi_client_invoices:get_invoice_by_id(Context, ?STRING), ?BADRESP(504) = capi_client_invoices:get_invoice_by_id(Context, ?STRING),
{ok, _} = capi_client_categories:get_categories(Context). {ok, _} = capi_client_categories:get_categories(Context).

View File

@ -1132,7 +1132,21 @@
{payment_service, #domain_PaymentServiceRef{id = <<"qiwi">>}} => {payment_service, #domain_PaymentServiceRef{id = <<"qiwi">>}} =>
{payment_service, #domain_PaymentServiceObject{ {payment_service, #domain_PaymentServiceObject{
ref = #domain_PaymentServiceRef{id = <<"qiwi">>}, ref = #domain_PaymentServiceRef{id = <<"qiwi">>},
data = #domain_PaymentService{name = <<"Qiwi">>} data = #domain_PaymentService{
name = <<"Qiwi">>,
brand_name = <<"QIWI">>,
category = <<"wallets">>,
metadata = #{
<<"test.ns">> =>
{obj, #{
<<"answer">> => {i, 42},
<<"localization">> =>
{obj, #{
<<"ru_RU">> => {arr, [{str, <<"КИВИ Кошелёк">>}]}
}}
}}
}
}
}}, }},
{payment_system_legacy, #domain_LegacyBankCardPaymentSystemRef{id = visa}} => {payment_system_legacy, #domain_LegacyBankCardPaymentSystemRef{id = visa}} =>

View File

@ -3,10 +3,8 @@
-include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct.hrl").
-include_lib("stdlib/include/assert.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_payment_processing_thrift.hrl").
-include_lib("capi_dummy_data.hrl"). -include_lib("capi_dummy_data.hrl").
-include_lib("jose/include/jose_jwk.hrl").
-export([all/0]). -export([all/0]).
-export([groups/0]). -export([groups/0]).
@ -25,12 +23,6 @@
get_invoice_payment_methods_by_tpl_id_ok_test/1 get_invoice_payment_methods_by_tpl_id_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 test_case_name() :: atom().
-type config() :: [{atom(), any()}]. -type config() :: [{atom(), any()}].
-type group_name() :: atom(). -type group_name() :: atom().

View File

@ -141,19 +141,12 @@ schema_param_validation(Config) ->
query_param_validation(Config) -> query_param_validation(Config) ->
_ = capi_ct_helper:mock_services( _ = capi_ct_helper:mock_services(
[ [
{merchant_stat, fun('GetInvoices', _) -> {ok, ?STAT_RESPONSE_INVOICES} end}, {merchant_stat, fun('GetInvoices', _) -> {ok, ?STAT_RESPONSE_INVOICES} end}
{geo_ip_service, fun('GetLocationName', _) -> {ok, #{123 => ?STRING}} end}
], ],
Config Config
), ),
Query0 = [ Query0 = [
{payerEmail, <<"te%^st@test.ru">>} {'payerEmail', <<"te%^st@test.ru">>}
], ],
{error, {request_validation_failed, _}} = {error, {request_validation_failed, _}} =
capi_client_searches:search_invoices(?config(context, Config), ?STRING, Query0), capi_client_searches:search_invoices(?config(context, Config), ?STRING, Query0).
Query1 = #{
<<"geoIDs">> => <<"no,also no">>,
<<"language">> => <<"ru">>
},
{error, {request_validation_failed, _}} =
capi_client_geo:get_location_names(?config(context, Config), Query1).

View File

@ -1,7 +1,7 @@
-define(TK_AUTHORITY_KEYCLOAK, <<"test.rbkmoney.keycloak">>). -define(TK_AUTHORITY_KEYCLOAK, <<"dev.vality.keycloak">>).
-define(TK_AUTHORITY_APIKEYMGMT, <<"test.rbkmoney.apikeymgmt">>). -define(TK_AUTHORITY_APIKEYMGMT, <<"dev.vality.apikeymgmt">>).
-define(TK_META_PARTY_ID, <<"test.rbkmoney.party.id">>). -define(TK_META_PARTY_ID, <<"dev.vality.party.id">>).
-define(TK_META_TOKEN_CONSUMER, <<"test.rbkmoney.capi.consumer">>). -define(TK_META_TOKEN_CONSUMER, <<"dev.vality.capi.consumer">>).
-define(TK_META_USER_ID, <<"test.rbkmoney.user.id">>). -define(TK_META_USER_ID, <<"dev.vality.user.id">>).
-define(TK_META_USER_EMAIL, <<"test.rbkmoney.user.email">>). -define(TK_META_USER_EMAIL, <<"dev.vality.user.email">>).

View File

@ -22,7 +22,7 @@
woody_unknown_test/1 woody_unknown_test/1
]). ]).
-define(badresp(Code), {error, {invalid_response_code, Code}}). -define(BADRESP(Code), {error, {invalid_response_code, Code}}).
-type test_case_name() :: atom(). -type test_case_name() :: atom().
-type config() :: [{atom(), any()}]. -type config() :: [{atom(), any()}].
@ -93,7 +93,7 @@ end_per_testcase(_Name, C) ->
-spec woody_unexpected_test(config()) -> _. -spec woody_unexpected_test(config()) -> _.
woody_unexpected_test(Config) -> woody_unexpected_test(Config) ->
_ = capi_ct_helper:mock_services([{invoicing, fun('Get', _) -> {ok, "spanish inquisition"} end}], Config), _ = capi_ct_helper:mock_services([{invoicing, fun('Get', _) -> {ok, "spanish inquisition"} end}], Config),
?badresp(500) = capi_client_invoices:get_invoice_by_id(?config(context, Config), ?STRING). ?BADRESP(500) = capi_client_invoices:get_invoice_by_id(?config(context, Config), ?STRING).
-spec woody_unavailable_test(config()) -> _. -spec woody_unavailable_test(config()) -> _.
woody_unavailable_test(Config) -> woody_unavailable_test(Config) ->
@ -102,7 +102,7 @@ woody_unavailable_test(Config) ->
invoicing => #{url => <<"http://spanish.inquision/v1/partymgmt">>} invoicing => #{url => <<"http://spanish.inquision/v1/partymgmt">>}
}} }}
]), ]),
?badresp(503) = capi_client_invoices:get_invoice_by_id(?config(context, Config), ?STRING). ?BADRESP(503) = capi_client_invoices:get_invoice_by_id(?config(context, Config), ?STRING).
-spec woody_retry_test(config()) -> _. -spec woody_retry_test(config()) -> _.
woody_retry_test(Config) -> woody_retry_test(Config) ->
@ -120,10 +120,10 @@ woody_retry_test(Config) ->
invoicing => 5000 invoicing => 5000
}} }}
]), ]),
{Time, ?badresp(503)} = timer:tc(capi_client_invoices, get_invoice_by_id, [?config(context, Config), ?STRING]), {Time, ?BADRESP(503)} = timer:tc(capi_client_invoices, get_invoice_by_id, [?config(context, Config), ?STRING]),
true = (Time > 3000000) and (Time < 10000000). true = (Time > 3000000) and (Time < 10000000).
-spec woody_unknown_test(config()) -> _. -spec woody_unknown_test(config()) -> _.
woody_unknown_test(Config) -> woody_unknown_test(Config) ->
_ = capi_ct_helper:mock_services([{invoicing, fun('Get', _) -> timer:sleep(60000) end}], Config), _ = capi_ct_helper:mock_services([{invoicing, fun('Get', _) -> timer:sleep(60000) end}], Config),
?badresp(504) = capi_client_invoices:get_invoice_by_id(?config(context, Config), ?STRING). ?BADRESP(504) = capi_client_invoices:get_invoice_by_id(?config(context, Config), ?STRING).

View File

@ -1,15 +0,0 @@
-module(capi_client_geo).
-export([get_location_names/2]).
-type context() :: capi_client_lib:context().
-type query_string() :: map().
-spec get_location_names(context(), query_string()) -> {ok, term()} | {error, term()}.
get_location_names(Context, Query) ->
Params = #{
qs_val => Query
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_geo_api:get_locations_names(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).

View File

@ -8,6 +8,7 @@
-export([get_payment_institution_payout_methods/3]). -export([get_payment_institution_payout_methods/3]).
-export([get_payment_institution_payout_schedules/2]). -export([get_payment_institution_payout_schedules/2]).
-export([get_payment_institution_payout_schedules/4]). -export([get_payment_institution_payout_schedules/4]).
-export([get_service_provider_by_id/2]).
-type context() :: capi_client_lib:context(). -type context() :: capi_client_lib:context().
@ -80,10 +81,21 @@ get_payment_institution_payout_schedules(Context, PaymentInstitutionID, Currency
<<"paymentInstitutionID">> => genlib:to_list(PaymentInstitutionID) <<"paymentInstitutionID">> => genlib:to_list(PaymentInstitutionID)
}, },
qs_val => genlib_map:compact(#{ qs_val => genlib_map:compact(#{
currency => Currency, 'currency' => Currency,
payoutMethod => Method 'payoutMethod' => Method
}) })
}, },
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params), {Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_payment_institutions_api:get_payment_institution_payout_schedules(Url, PreparedParams, Opts), Response = swag_client_payment_institutions_api:get_payment_institution_payout_schedules(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response). capi_client_lib:handle_response(Response).
-spec get_service_provider_by_id(context(), binary()) -> {ok, term()} | {error, term()}.
get_service_provider_by_id(Context, ServiceProviderID) ->
Params = #{
binding => #{
<<"serviceProviderID">> => ServiceProviderID
}
},
{Url, PreparedParams, Opts} = capi_client_lib:make_request(Context, Params),
Response = swag_client_payment_institutions_api:get_service_provider_by_id(Url, PreparedParams, Opts),
capi_client_lib:handle_response(Response).

View File

@ -85,8 +85,6 @@ get_service_modname(payouts) ->
{payouts_payout_manager_thrift, 'PayoutManagement'}; {payouts_payout_manager_thrift, 'PayoutManagement'};
get_service_modname(accounter) -> get_service_modname(accounter) ->
{dmsl_accounter_thrift, 'Accounter'}; {dmsl_accounter_thrift, 'Accounter'};
get_service_modname(geo_ip_service) ->
{dmsl_geo_ip_thrift, 'GeoIpService'};
get_service_modname(webhook_manager) -> get_service_modname(webhook_manager) ->
{dmsl_webhooker_thrift, 'WebhookManager'}; {dmsl_webhooker_thrift, 'WebhookManager'};
get_service_modname(customer_management) -> get_service_modname(customer_management) ->

@ -1 +0,0 @@
Subproject commit be44d69fc87b22a0bb82d98d6eae7658d1647f98

View File

@ -76,10 +76,10 @@
}}, }},
{auth_config, #{ {auth_config, #{
metadata_mappings => #{ metadata_mappings => #{
party_id => <<"test.rbkmoney.party.id">>, party_id => <<"dev.vality.party.id">>,
token_consumer => <<"test.rbkmoney.capi.consumer">>, token_consumer => <<"dev.vality.capi.consumer">>,
user_id => <<"test.rbkmoney.user.id">>, user_id => <<"dev.vality.user.id">>,
user_email => <<"test.rbkmoney.user.email">> user_email => <<"dev.vality.user.email">>
} }
}} }}
]}, ]},
@ -94,8 +94,7 @@
webhook_manager => <<"http://hooker:8022/hook">>, webhook_manager => <<"http://hooker:8022/hook">>,
merchant_stat => <<"http://magista:8022/stat">>, merchant_stat => <<"http://magista:8022/stat">>,
reporting => <<"http://reporter:8022/reports">>, reporting => <<"http://reporter:8022/reports">>,
payouts => <<"http://payouter:8022/reports">>, payouts => <<"http://payouter:8022/reports">>
geo_ip_service => <<"http://columbus:8022/repo">>
}}, }},
{service_deadlines, #{ {service_deadlines, #{
party_management => 5000, % milliseconds party_management => 5000, % milliseconds
@ -107,7 +106,7 @@
% '_' work as "any" % '_' work as "any"
% default value is 'finish' % default value is 'finish'
% for more info look genlib_retry :: strategy() % for more info look genlib_retry :: strategy()
% https://github.com/rbkmoney/genlib/blob/master/src/genlib_retry.erl#L19 % https://github.com/valitydev/genlib/blob/master/src/genlib_retry.erl#L19
'Get' => {linear, 3, 1000}, 'Get' => {linear, 3, 1000},
'_' => finish '_' => finish
} }
@ -121,8 +120,8 @@
memory => 52428800 % 50Mb memory => 52428800 % 50Mb
}}, }},
{service_urls, #{ {service_urls, #{
'Repository' => <<"dominant:8022/v1/domain/repository">>, 'Repository' => <<"http://dominant:8022/v1/domain/repository">>,
'RepositoryClient' => <<"dominant:8022/v1/domain/repository_client">> 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">>
}} }}
]}, ]},

View File

@ -1,33 +1,64 @@
[ [
{elvis, [ {elvis, [
{verbose, true},
{config, [ {config, [
#{ #{
dirs => ["apps/*/**"], dirs => ["apps/**/src", "apps/**/include"],
filter => "*.erl", filter => "*.erl",
ignore => ["apps/swag_*"], ruleset => erl_files,
rules => [ rules => [
{elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, %% Common settings
{elvis_text_style, no_tabs}, {elvis_text_style, line_length, #{limit => 120}},
{elvis_text_style, no_trailing_whitespace}, {elvis_style, nesting_level, #{level => 3}},
{elvis_style, macro_module_names}, {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}},
{elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, {elvis_style, no_if_expression, disable},
{elvis_style, nesting_level, #{level => 4}}, %% Project settings
{elvis_style, god_modules, #{ {elvis_style, numeric_format, #{
limit => 30,
ignore => [ ignore => [
capi_base_api_token_tests_SUITE, capi_idempotency_tests_SUITE % Elvis fails with `bararg` here
capi_handler_utils
] ]
}}, }},
{elvis_style, no_if_expression}, % Verbose authorization code triggers this otherwise
{elvis_style, invalid_dynamic_call, #{ignore => [capi_domain]}},
{elvis_style, used_ignored_variable},
{elvis_style, no_behavior_info},
{elvis_style, module_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*(_SUITE)?$"}},
{elvis_style, function_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*$"}},
{elvis_style, state_record_and_type, #{ignore => []}},
{elvis_style, no_spec_with_records},
{elvis_style, dont_repeat_yourself, #{min_complexity => 30}}, {elvis_style, dont_repeat_yourself, #{min_complexity => 30}},
{elvis_style, no_debug_call, #{}} {elvis_style, god_modules, #{
ignore => [
% TODO
% Need to rethink its responsibilities
capi_handler_utils
]
}},
{elvis_style, invalid_dynamic_call, #{
ignore => [
% Uses thrift types reflection through generated code
capi_domain
]
}},
{elvis_style, macro_names, #{
ignore => [
% Abuses lowercase macros too much
capi_feature_schemas,
capi_feature_schemas_legacy
]
}}
]
},
#{
dirs => ["apps/**/test"],
filter => "*.erl",
ruleset => erl_files,
rules => [
{elvis_text_style, line_length, #{limit => 120}},
{elvis_style, nesting_level, #{level => 3}},
{elvis_style, no_if_expression, disable},
% We want to use `ct:pal/2` and friends in test code.
{elvis_style, no_debug_call, disable},
% Assert macros can trigger use of ignored binding, yet we want them for better
% readability.
{elvis_style, used_ignored_variable, disable},
% Tests are usually more comprehensible when a bit more verbose.
{elvis_style, dont_repeat_yourself, #{min_complexity => 50}},
{elvis_style, god_modules, disable}
] ]
}, },
#{ #{
@ -41,21 +72,22 @@
ruleset => elvis_config ruleset => elvis_config
}, },
#{ #{
dirs => [".", "apps/*/*"], dirs => [".", "apps/*"],
filter => "rebar.config", filter => "rebar.config",
ignore => ["apps/swag_*"], ruleset => rebar_config,
rules => [ rules => [
{elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, {elvis_text_style, line_length, #{limit => 120}},
{elvis_text_style, no_tabs}, {elvis_text_style, no_tabs},
{elvis_text_style, no_trailing_whitespace} {elvis_text_style, no_trailing_whitespace},
%% Temporarily disabled till regex pattern is available
{elvis_project, no_deps_master_rebar, disable}
] ]
}, },
#{ #{
dirs => ["apps/**"], dirs => ["apps/*/src"],
filter => "*.app.src", filter => "*.app.src",
ignore => ["apps/swag_*"],
rules => [ rules => [
{elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, {elvis_text_style, line_length, #{limit => 120}},
{elvis_text_style, no_tabs}, {elvis_text_style, no_tabs},
{elvis_text_style, no_trailing_whitespace} {elvis_text_style, no_trailing_whitespace}
] ]

View File

@ -27,32 +27,33 @@
%% Common project dependencies. %% Common project dependencies.
{deps, [ {deps, [
{cowboy, "2.9.0"}, {cowboy, "2.9.0"},
{jose, "1.11.2"}, %% NOTE
{genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, %% Pinning to version "1.11.2" from hex here causes constant upgrading and recompilation of the entire project
{cowboy_draining_server, {git, "https://github.com/rbkmoney/cowboy_draining_server.git", {branch, "master"}}}, {jose, {git, "https://github.com/potatosalad/erlang-jose.git", {tag, "1.11.2"}}},
{woody, {git, "https://github.com/rbkmoney/woody_erlang.git", {branch, "master"}}}, {genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}},
{woody_user_identity, {git, "https://github.com/rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}}, {cowboy_draining_server, {git, "https://github.com/valitydev/cowboy_draining_server.git", {branch, "master"}}},
{woody_api_hay, {git, "https://github.com/rbkmoney/woody_api_hay.git", {branch, "master"}}}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}},
{damsel, {git, "https://github.com/rbkmoney/damsel.git", {branch, "master"}}}, {woody_user_identity, {git, "https://github.com/valitydev/woody_erlang_user_identity.git", {branch, "master"}}},
{bender_proto, {git, "https://github.com/rbkmoney/bender-proto.git", {branch, "master"}}}, {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}},
{bender_client, {git, "https://github.com/rbkmoney/bender_client_erlang.git", {branch, "master"}}}, {bender_proto, {git, "https://github.com/valitydev/bender-proto.git", {branch, "master"}}},
{reporter_proto, {git, "https://github.com/rbkmoney/reporter-proto.git", {branch, "master"}}}, {bender_client, {git, "https://github.com/valitydev/bender_client_erlang.git", {branch, "master"}}},
{dmt_client, {git, "https://github.com/rbkmoney/dmt_client.git", {branch, "master"}}}, {reporter_proto, {git, "https://github.com/valitydev/reporter-proto.git", {branch, "master"}}},
{cowboy_cors, {git, "https://github.com/rbkmoney/cowboy_cors.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}},
{cowboy_access_log, {git, "https://github.com/rbkmoney/cowboy_access_log.git", {branch, "master"}}}, {cowboy_cors, {git, "https://github.com/valitydev/cowboy_cors.git", {branch, "master"}}},
{payproc_errors, {git, "https://github.com/rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, {cowboy_access_log, {git, "https://github.com/valitydev/cowboy_access_log.git", {branch, "master"}}},
{scoper, {git, "https://github.com/rbkmoney/scoper.git", {branch, master}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}},
{erl_health, {git, "https://github.com/rbkmoney/erlang-health.git", {branch, master}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {branch, master}}},
{lechiffre, {git, "https://github.com/rbkmoney/lechiffre.git", {branch, master}}}, {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, master}}},
{prometheus, "4.8.1"}, {lechiffre, {git, "https://github.com/valitydev/lechiffre.git", {branch, master}}},
{prometheus_cowboy, "0.1.8"}, {bouncer_proto, {git, "https://github.com/valitydev/bouncer-proto.git", {branch, master}}},
{bouncer_proto, {git, "https://github.com/rbkmoney/bouncer-proto.git", {branch, master}}}, {bouncer_client, {git, "https://github.com/valitydev/bouncer_client_erlang.git", {branch, master}}},
{bouncer_client, {git, "https://github.com/rbkmoney/bouncer_client_erlang.git", {branch, master}}}, {token_keeper_client, {git, "https://github.com/valitydev/token-keeper-client.git", {branch, master}}},
{token_keeper_client, {git, "https://github.com/rbkmoney/token-keeper-client.git", {branch, master}}}, {party_client, {git, "https://github.com/valitydev/party_client_erlang.git", {branch, master}}},
{party_client, {git, "https://github.com/rbkmoney/party_client_erlang.git", {branch, master}}}, {payout_manager_proto, {git, "https://github.com/valitydev/payout-manager-proto.git", {branch, master}}},
{payout_manager_proto, {git, "https://github.com/rbkmoney/payout-manager-proto.git", {branch, master}}}, {feat, {git, "https://github.com/valitydev/feat.git", {branch, master}}},
{how_are_you, {git, "https://github.com/rbkmoney/how_are_you.git", {branch, master}}}, %% Libraries generated with swagger-codegen-erlang from valitydev/swag-payments
{feat, {git, "https://github.com/rbkmoney/feat.git", {branch, master}}} {swag_server, {git, "https://github.com/valitydev/swag-payments", {branch, "release/erlang/server/v2"}}},
{swag_client, {git, "https://github.com/valitydev/swag-payments", {branch, "release/erlang/client/v2"}}}
]}. ]}.
%% XRef checks %% XRef checks
@ -84,12 +85,20 @@
{profiles, [ {profiles, [
{prod, [ {prod, [
{deps, [ {deps, [
%% NOTE
%% Because of a dependency conflict, prometheus libs are only included in production build for now
%% https://github.com/project-fifo/rebar3_lint/issues/42
%% https://github.com/valitydev/hellgate/pull/2/commits/884724c1799703cee4d1033850fe32c17f986d9e
{prometheus, "4.8.1"},
{prometheus_cowboy, "0.1.8"},
{recon, "2.3.6"}, {recon, "2.3.6"},
{logger_logstash_formatter, {logger_logstash_formatter,
{git, "https://github.com/rbkmoney/logger_logstash_formatter.git", {ref, "87e52c7"}}} {git, "https://github.com/valitydev/logger_logstash_formatter.git", {ref, "87e52c7"}}},
{iosetopts, {git, "https://github.com/valitydev/iosetopts.git", {ref, "edb445c"}}}
]}, ]},
{relx, [ {relx, [
{release, {capi, "0.1.0"}, [ {release, {capi, "0.1.0"}, [
iosetopts,
% tools for introspection % tools for introspection
{recon, load}, {recon, load},
% debugger % debugger
@ -97,18 +106,14 @@
% profiler % profiler
{tools, load}, {tools, load},
logger_logstash_formatter, logger_logstash_formatter,
capi, prometheus,
prometheus_cowboy,
sasl, sasl,
woody_api_hay, capi
how_are_you
]}, ]},
{mode, minimal}, {mode, minimal},
{sys_config, "./config/sys.config"}, {sys_config, "./config/sys.config"},
{vm_args, "./config/vm.args"}, {vm_args, "./config/vm.args"},
{overlay, [
{mkdir, "var/keys/capi"},
{copy, "var/keys/capi/private.pem", "var/keys/capi/private.pem"}
]},
{extended_start_script, true} {extended_start_script, true}
]} ]}
]}, ]},
@ -118,7 +123,9 @@
]}. ]}.
{plugins, [ {plugins, [
{erlfmt, "1.0.0"} {covertool, "2.0.4"},
{erlfmt, "1.0.0"},
{rebar3_lint, "1.0.1"}
]}. ]}.
{erlfmt, [ {erlfmt, [
@ -126,6 +133,9 @@
{files, ["apps/capi*/{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]} {files, ["apps/capi*/{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]}
]}. ]}.
{pre_hooks, [ {covertool, [
{thrift, "git submodule update --init"} {coverdata_files, [
"eunit.coverdata",
"ct.coverdata"
]}
]}. ]}.

View File

@ -1,69 +1,63 @@
{"1.2.0", {"1.2.0",
[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, [{<<"bender_client">>,
{<<"bear">>,{pkg,<<"bear">>,<<"0.9.0">>},2}, {git,"https://github.com/valitydev/bender_client_erlang.git",
{<<"bender_client">>,
{git,"https://github.com/rbkmoney/bender_client_erlang.git",
{ref,"29501d6f6425bc310ef6b37b62790126bdff356b"}}, {ref,"29501d6f6425bc310ef6b37b62790126bdff356b"}},
0}, 0},
{<<"bender_proto">>, {<<"bender_proto">>,
{git,"https://github.com/rbkmoney/bender-proto.git", {git,"https://github.com/valitydev/bender-proto.git",
{ref,"dfe271b09a2b8e457f50e4732b905a0b846bf529"}}, {ref,"e08deadaab22019ff50a5d96ca6befff0034dab3"}},
0}, 0},
{<<"bouncer_client">>, {<<"bouncer_client">>,
{git,"https://github.com/rbkmoney/bouncer_client_erlang.git", {git,"https://github.com/valitydev/bouncer_client_erlang.git",
{ref,"535449a459b70643836c440a863b42656f2a1409"}}, {ref,"535449a459b70643836c440a863b42656f2a1409"}},
0}, 0},
{<<"bouncer_proto">>, {<<"bouncer_proto">>,
{git,"https://github.com/rbkmoney/bouncer-proto.git", {git,"https://github.com/valitydev/bouncer-proto.git",
{ref,"19bd3d674fd4182927063e17e274559a08d422c5"}}, {ref,"96bd74dbf1db33ce1cbc6f6d3ce5a9b598ee29f5"}},
0}, 0},
{<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},1}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},1},
{<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},1}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},2},
{<<"cg_mon">>, {<<"cg_mon">>,
{git,"https://github.com/rbkmoney/cg_mon.git", {git,"https://github.com/valitydev/cg_mon.git",
{ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}},
1}, 1},
{<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},0}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},0},
{<<"cowboy_access_log">>, {<<"cowboy_access_log">>,
{git,"https://github.com/rbkmoney/cowboy_access_log.git", {git,"https://github.com/valitydev/cowboy_access_log.git",
{ref,"c058ad42cd11c6503feb398fb8587c2f72155a60"}}, {ref,"04da359e022cf05c5c93812504d5791d6bc97453"}},
0}, 0},
{<<"cowboy_cors">>, {<<"cowboy_cors">>,
{git,"https://github.com/rbkmoney/cowboy_cors.git", {git,"https://github.com/valitydev/cowboy_cors.git",
{ref,"5a3b084fb8c5a4ff58e3c915a822d709d6023c3b"}}, {ref,"5a3b084fb8c5a4ff58e3c915a822d709d6023c3b"}},
0}, 0},
{<<"cowboy_draining_server">>, {<<"cowboy_draining_server">>,
{git,"https://github.com/rbkmoney/cowboy_draining_server.git", {git,"https://github.com/valitydev/cowboy_draining_server.git",
{ref,"186cf4d0722d4ad79afe73d371df6b1371e51905"}}, {ref,"186cf4d0722d4ad79afe73d371df6b1371e51905"}},
0}, 0},
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},1},
{<<"damsel">>, {<<"damsel">>,
{git,"https://github.com/rbkmoney/damsel.git", {git,"https://github.com/valitydev/damsel.git",
{ref,"af7c970159e8575de98c1b2d85cfdd8e00b7545d"}}, {ref,"b25d3365e1f2b075ffea30b3a2e1c41eb3f6145b"}},
0}, 0},
{<<"dmt_client">>, {<<"dmt_client">>,
{git,"https://github.com/rbkmoney/dmt_client.git", {git,"https://github.com/valitydev/dmt_client.git",
{ref,"3f66402843ffeb488010f707a193858cb09325e0"}}, {ref,"e9b1961b96ce138a34f6cf9cebef6ddf66af1942"}},
0}, 0},
{<<"dmt_core">>, {<<"dmt_core">>,
{git,"https://github.com/rbkmoney/dmt_core.git", {git,"https://github.com/valitydev/dmt_core.git",
{ref,"5a0ff399dee3fd606bb864dd0e27ddde539345e2"}}, {ref,"910e20edbe03ae4645aa3923baea8054003753b5"}},
1}, 1},
{<<"email_validator">>,{pkg,<<"email_validator">>,<<"1.1.0">>},0}, {<<"email_validator">>,{pkg,<<"email_validator">>,<<"1.1.0">>},1},
{<<"erl_health">>, {<<"erl_health">>,
{git,"https://github.com/rbkmoney/erlang-health.git", {git,"https://github.com/valitydev/erlang-health.git",
{ref,"5958e2f35cd4d09f40685762b82b82f89b4d9333"}}, {ref,"5958e2f35cd4d09f40685762b82b82f89b4d9333"}},
0}, 0},
{<<"feat">>, {<<"feat">>,
{git,"https://github.com/rbkmoney/feat.git", {git,"https://github.com/valitydev/feat.git",
{ref,"bf7dff68c822e58769da962e7f99c3e428a88551"}}, {ref,"bf7dff68c822e58769da962e7f99c3e428a88551"}},
0}, 0},
{<<"folsom">>,
{git,"https://github.com/folsom-project/folsom.git",
{ref,"62fd0714e6f0b4e7833880afe371a9c882ea0fc2"}},
1},
{<<"genlib">>, {<<"genlib">>,
{git,"https://github.com/rbkmoney/genlib.git", {git,"https://github.com/valitydev/genlib.git",
{ref,"82c5ff3866e3019eb347c7f1d8f1f847bed28c10"}}, {ref,"82c5ff3866e3019eb347c7f1d8f1f847bed28c10"}},
0}, 0},
{<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},1},
@ -71,92 +65,89 @@
{git,"https://github.com/ninenines/gun.git", {git,"https://github.com/ninenines/gun.git",
{ref,"e7dd9f227e46979d8073e71c683395a809b78cb4"}}, {ref,"e7dd9f227e46979d8073e71c683395a809b78cb4"}},
1}, 1},
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.4">>},0}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.4">>},1},
{<<"how_are_you">>, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2},
{git,"https://github.com/rbkmoney/how_are_you.git",
{ref,"2fd8013420328464c2c84302af2781b86577b39f"}},
0},
{<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},1},
{<<"jesse">>, {<<"jesse">>,
{git,"https://github.com/rbkmoney/jesse.git", {git,"https://github.com/valitydev/jesse.git",
{ref,"9b980b7f9ce09b6a136fe5a23d404d1b903f3061"}}, {ref,"9b980b7f9ce09b6a136fe5a23d404d1b903f3061"}},
1},
{<<"jose">>,
{git,"https://github.com/potatosalad/erlang-jose.git",
{ref,"991649695aaccd92c8effb1c1e88e6159fe8e9a6"}},
0}, 0},
{<<"jose">>,{pkg,<<"jose">>,<<"1.11.2">>},0}, {<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1},
{<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},0},
{<<"lechiffre">>, {<<"lechiffre">>,
{git,"https://github.com/rbkmoney/lechiffre.git", {git,"https://github.com/valitydev/lechiffre.git",
{ref,"ab894bc7c0e830f4372d302036f044d20c76ca73"}}, {ref,"ab894bc7c0e830f4372d302036f044d20c76ca73"}},
0}, 0},
{<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},1}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2},
{<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},1}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2},
{<<"msgpack_proto">>, {<<"msgpack_proto">>,
{git,"https://github.com/rbkmoney/msgpack-proto.git", {git,"https://github.com/valitydev/msgpack-proto.git",
{ref,"ec15d5e854ea60c58467373077d90c2faf6273d8"}}, {ref,"ec15d5e854ea60c58467373077d90c2faf6273d8"}},
1}, 1},
{<<"org_management_proto">>, {<<"org_management_proto">>,
{git,"git@github.com:rbkmoney/org-management-proto.git", {git,"https://github.com/valitydev/org-management-proto.git",
{ref,"06c5c8430e445cb7874e54358e457cbb5697fc32"}}, {ref,"06c5c8430e445cb7874e54358e457cbb5697fc32"}},
1}, 1},
{<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.4.0">>},0}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.4.1">>},1},
{<<"party_client">>, {<<"party_client">>,
{git,"https://github.com/rbkmoney/party_client_erlang.git", {git,"https://github.com/valitydev/party_client_erlang.git",
{ref,"8afd535d96a9994d63c678c87688f3b4ff016781"}}, {ref,"8fc5595c4c61c0fe3d2dc29a61f48ba94e9bdef7"}},
0}, 0},
{<<"payout_manager_proto">>, {<<"payout_manager_proto">>,
{git,"https://github.com/rbkmoney/payout-manager-proto.git", {git,"https://github.com/valitydev/payout-manager-proto.git",
{ref,"b6cd2286a438685fceb1f020e24dc42750b74a3e"}}, {ref,"b6cd2286a438685fceb1f020e24dc42750b74a3e"}},
0}, 0},
{<<"payproc_errors">>, {<<"payproc_errors">>,
{git,"https://github.com/rbkmoney/payproc-errors-erlang.git", {git,"https://github.com/valitydev/payproc-errors-erlang.git",
{ref,"ebbfa3775c77d665f519d39ca9afa08c28d7733f"}}, {ref,"ebbfa3775c77d665f519d39ca9afa08c28d7733f"}},
0}, 0},
{<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},0},
{<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.8">>},0},
{<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.11">>},1},
{<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1},
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},1}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},1},
{<<"reporter_proto">>, {<<"reporter_proto">>,
{git,"https://github.com/rbkmoney/reporter-proto.git", {git,"https://github.com/valitydev/reporter-proto.git",
{ref,"aafbfac4463711d43f8e8ed4da103967b95e1fb6"}}, {ref,"aafbfac4463711d43f8e8ed4da103967b95e1fb6"}},
0}, 0},
{<<"scoper">>, {<<"scoper">>,
{git,"https://github.com/rbkmoney/scoper.git", {git,"https://github.com/valitydev/scoper.git",
{ref,"a2c2b7a4b1770205b7b1dbe2e0df6c88044e6244"}}, {ref,"7f3183df279bc8181efe58dafd9cae164f495e6f"}},
0}, 0},
{<<"snowflake">>, {<<"snowflake">>,
{git,"https://github.com/rbkmoney/snowflake.git", {git,"https://github.com/valitydev/snowflake.git",
{ref,"de159486ef40cec67074afe71882bdc7f7deab72"}}, {ref,"de159486ef40cec67074afe71882bdc7f7deab72"}},
1}, 1},
{<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},1}, {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2},
{<<"swag_client">>,
{git,"https://github.com/valitydev/swag-payments",
{ref,"d42fe53131e605b86a6fafd731c8d17275a2d1c3"}},
0},
{<<"swag_server">>,
{git,"https://github.com/valitydev/swag-payments",
{ref,"d66adf6f04071cf587ae1d11c6d3502fbe5fe0af"}},
0},
{<<"thrift">>, {<<"thrift">>,
{git,"https://github.com/rbkmoney/thrift_erlang.git", {git,"https://github.com/valitydev/thrift_erlang.git",
{ref,"846a0819d9b6d09d0c31f160e33a78dbad2067b4"}}, {ref,"846a0819d9b6d09d0c31f160e33a78dbad2067b4"}},
1}, 1},
{<<"token_keeper_client">>, {<<"token_keeper_client">>,
{git,"https://github.com/rbkmoney/token-keeper-client.git", {git,"https://github.com/valitydev/token-keeper-client.git",
{ref,"27158ea5d3e3c74f0090f8d2ac3f2ca52ab39584"}}, {ref,"27158ea5d3e3c74f0090f8d2ac3f2ca52ab39584"}},
0}, 0},
{<<"token_keeper_proto">>, {<<"token_keeper_proto">>,
{git,"https://github.com/rbkmoney/token-keeper-proto.git", {git,"https://github.com/valitydev/token-keeper-proto.git",
{ref,"15781716691a72de8c8f065c11c5b08173fc8434"}}, {ref,"c7f48d24a561c95b8135d3b07fd2ff55a62eb308"}},
1}, 1},
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2},
{<<"woody">>, {<<"woody">>,
{git,"https://github.com/rbkmoney/woody_erlang.git", {git,"https://github.com/valitydev/woody_erlang.git",
{ref,"330bdcf71e99c2ea7aed424cd718939cb360ec1c"}}, {ref,"0c2e16dfc8a51f6f63fcd74df982178a9aeab322"}},
0},
{<<"woody_api_hay">>,
{git,"https://github.com/rbkmoney/woody_api_hay.git",
{ref,"3cb6404bfbe80478a71c88b33c0bd352e94cd3c3"}},
0}, 0},
{<<"woody_user_identity">>, {<<"woody_user_identity">>,
{git,"https://github.com/rbkmoney/woody_erlang_user_identity.git", {git,"https://github.com/valitydev/woody_erlang_user_identity.git",
{ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}}, {ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}},
0}]}. 0}]}.
[ [
{pkg_hash,[ {pkg_hash,[
{<<"accept">>, <<"B33B127ABCA7CC948BBE6CAA4C263369ABF1347CFA9D8E699C6D214660F10CD1">>},
{<<"bear">>, <<"A31CCF5361791DD5E708F4789D67E2FEF496C4F05935FC59ADC11622F834D128">>},
{<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>},
{<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>}, {<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>},
{<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>},
@ -165,21 +156,14 @@
{<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>}, {<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>},
{<<"hackney">>, <<"99DA4674592504D3FB0CFEF0DB84C3BA02B4508BAE2DFF8C0108BAA0D6E0977C">>}, {<<"hackney">>, <<"99DA4674592504D3FB0CFEF0DB84C3BA02B4508BAE2DFF8C0108BAA0D6E0977C">>},
{<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>},
{<<"jose">>, <<"F4C018CCF4FDCE22C71E44D471F15F723CB3EFAB5D909AB2BA202B5BF35557B3">>},
{<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>}, {<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>},
{<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>},
{<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>},
{<<"parse_trans">>, <<"BB87AC362A03CA674EBB7D9D498F45C03256ADED7214C9101F7035EF44B798C7">>}, {<<"parse_trans">>, <<"6E6AA8167CB44CC8F39441D05193BE6E6F4E7C2946CB2759F015F8C56B76E5FF">>},
{<<"prometheus">>, <<"FA76B152555273739C14B06F09F485CF6D5D301FE4E9D31B7FF803D26025D7A0">>},
{<<"prometheus_cowboy">>, <<"CFCE0BC7B668C5096639084FCD873826E6220EA714BF60A716F5BD080EF2A99C">>},
{<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>},
{<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>},
{<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>},
{<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>},
{<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]},
{pkg_hash_ext,[ {pkg_hash_ext,[
{<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>},
{<<"bear">>, <<"47F71F098F2E3CD05E124A896C5EC2F155967A2B6FF6731E0D627312CCAB7E28">>},
{<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>},
{<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>}, {<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>},
{<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>},
@ -188,15 +172,10 @@
{<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>}, {<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>},
{<<"hackney">>, <<"DE16FF4996556C8548D512F4DBE22DD58A587BF3332E7FD362430A7EF3986B16">>}, {<<"hackney">>, <<"DE16FF4996556C8548D512F4DBE22DD58A587BF3332E7FD362430A7EF3986B16">>},
{<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>},
{<<"jose">>, <<"98143FBC48D55F3A18DABA82D34FE48959D44538E9697C08F34200FA5F0947D2">>},
{<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>}, {<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>},
{<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>},
{<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>},
{<<"parse_trans">>, <<"F99E368830BEA44552224E37E04943A54874F08B8590485DE8D13832B63A2DC3">>}, {<<"parse_trans">>, <<"620A406CE75DADA827B82E453C19CF06776BE266F5A67CFF34E1EF2CBB60E49A">>},
{<<"prometheus">>, <<"6EDFBE928D271C7F657A6F2C46258738086584BD6CAE4A000B8B9A6009BA23A5">>},
{<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>},
{<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>},
{<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>},
{<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>},
{<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>}, {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>},
{<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]}

@ -1 +0,0 @@
Subproject commit 42257c406df732cc5b6cd7a864fca94ec9df59bf

View File

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA4MUtYkvoIAHNgvYtHSydanyY1qD8nJ+D/A1FFp5LF4SmM9nn
vSfTFC2T3D53sCR/DtUzCFIQwZIXXHob22ndFydZqhahrYLLJkpH5IXMy593Sho/
oXzxgwkbXaOMevcLFZcj5AneG+q2vFjaDGeQAJaAAPGinMo6UN94DYguNH2s6zqo
yRc8ng6KWD5UgEFTIEWni1RIZvp2NAnSkh/SeI1zs9uY6AR7bf6oFSChTd9m+li5
d20L5tc0aX7LG842SJEM2dJKckI4ZDZHvU6nDitH3TGrxkMa0CqLe7nUOfvSff2c
H9m0CzSbPy/SnyTQLklWoFsi9z2cqqtY6SvR7QIDAQABAoIBADAoz1KSZQgGmtwG
lx/7ITdhvvWtxLJiU0s8JKN2Ayzk1R+i/s4+rDFUmqvEDq0FBNxOvgJ4YvK2tJ6x
4yoeAqslWUbiVn3w2ko3/DNwn7K5VjvgZ+XX+X9UAjMMCduG9y8HFT+VBawBnGm6
t+2UevxFQuPw4iCqC9isKPLtTMkeBXfaCA+tzBqVytlBeW5nJG1Bh9GSV6OeeNoc
x6lh1X+7kxk/qLQZsogNwZXxPLuIK0qJCfsGzMYodSi43nv2mFtl5vBt0M+iU42i
KrL32SlQmkBI4st/HIie9YpSjj55llOU6L0KBPhH58wc8LDEc2Kwcxeow4/McO0E
fSwf9pkCgYEA+4v+371szXbUTfOBOBO7+bGbTo0gzJ8JnMaSdVDLhBaqyp5dbztS
TPiaCqfEYk4AYnl2dR7nLYRca/WRDle7hvDqB7K2RWWS58RDifiQ4gfJM9lW4Ocu
SIhnxVmr4iVdo4eOs6pxe8yRtF1U+uK8WuoV06+lgL/esEJB2JPyeQsCgYEA5L/U
osQFOogSk1Ycjl66UEXm0Y2HzFONTKMSellUnkdSSscx6+mLOn7eL5voSNSJrnCw
Tfh3uZ0NOh63Yw3aPGCwtn+EIflW1hzx+DJMvCS5TaU3BZF954rljklJL6VpaIPP
fXrc0z1FcsAT2s3aQNmEK2SWp7Y44V6mpQn7a+cCgYEA0Tf+dD+MOFRmfrNSvb6E
MUkMwMfXCPoaN6BdfmAF9cYYpdAULIjtigGXtdcWGyF/ZmhaI03hv9UAPfcQgBpu
ae0E6gQ1YAD8r/Jorl/kuWr6aTqS7Rq7Py7dCKLtuHmVqYb9JOhV3T8nzRl3rfhZ
61AZeWj1QeHUKUvikm1zVkMCgYEAyan42xn3BhgKUEw9VqJanQRTLnEYxGDwlBy7
4JM6j2OPQA+GilXVgddxKAXJ7dM6IkiElei0HDZB//gucqw2tr4DbJDUu2LnVFIm
XEpz7fZuSu6ZqFYQ6n1ATYV8eP3aBOMXnKchYTWGMVj26BJNFJju9ZZzXx293aol
PiCjwAcCgYAmOtRZRtf/p1eXPz1JN1OwEVSrnghJP5KBA8XGsnBmQUTeMmHo3Wl7
rELKg0O2bsPtTTAvm5bfLsRgvee+EY28mAY6MA8xJNHB6OabOHuRHqX7ow/LOagK
15mUtZ9f8AaKamZ3Bmg/XWWJxNmeCt5LJDr1OnmCDyItbfF9DxnXXg==
-----END RSA PRIVATE KEY-----