refactor: app (WIP)
This commit is contained in:
parent
4c38cc4f5c
commit
db80989c81
8
.dockerignore
Normal file
8
.dockerignore
Normal file
@ -0,0 +1,8 @@
|
||||
.mockery.yaml
|
||||
.golangci.yaml
|
||||
.gitlab-ci.yaml
|
||||
.gitingore
|
||||
.Makefile
|
||||
.README.md
|
||||
deployments
|
||||
tests
|
16
.env.test
Normal file
16
.env.test
Normal file
@ -0,0 +1,16 @@
|
||||
HTTP_HOST=0.0.0.0
|
||||
HTTP_PORT=8080
|
||||
HTTP_DOMEN=http://localhost:8080
|
||||
|
||||
GRPC_HOST=0.0.0.0
|
||||
GRPC_PORT=8081
|
||||
|
||||
YOOMONEY_STORE_ID=storeid
|
||||
YOOMONEY_SECRET_KEY=secret
|
||||
|
||||
MONGO_HOST=mongo
|
||||
MONGO_PORT=27017
|
||||
MONGO_USER=admin
|
||||
MONGO_PASSWORD=admin
|
||||
MONGO_DB_NAME=admin
|
||||
MONGO_AUTH=admin
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -48,5 +48,4 @@ Thumbs.db
|
||||
*.mov
|
||||
*.wmv
|
||||
profile
|
||||
treasurer
|
||||
|
||||
|
164
.golangci.yaml
Normal file
164
.golangci.yaml
Normal file
@ -0,0 +1,164 @@
|
||||
run:
|
||||
timeout: 5m
|
||||
skip-files:
|
||||
- \.pb\.go$
|
||||
- \.pb\.validate\.go$
|
||||
- \.pb\.gw\.go$
|
||||
- \.gen\.go$
|
||||
skip-dirs:
|
||||
- mocks
|
||||
- proto
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- asasalint
|
||||
- asciicheck
|
||||
- bidichk
|
||||
- bodyclose
|
||||
- containedctx
|
||||
- depguard
|
||||
- dogsled
|
||||
- dupword
|
||||
- durationcheck
|
||||
- errcheck
|
||||
- errchkjson
|
||||
- exportloopref
|
||||
- goconst
|
||||
- gocritic
|
||||
- godot
|
||||
- gofmt
|
||||
- gci
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- importas
|
||||
- ineffassign
|
||||
- misspell
|
||||
- nakedret
|
||||
- nilerr
|
||||
- noctx
|
||||
- nolintlint
|
||||
- nosprintfhostport
|
||||
- prealloc
|
||||
- predeclared
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- staticcheck
|
||||
- stylecheck
|
||||
- thelper
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- usestdlibvars
|
||||
- whitespace
|
||||
|
||||
linters-settings:
|
||||
errcheck:
|
||||
exclude-functions:
|
||||
- (io.Closer).Close
|
||||
govet:
|
||||
check-shadowing: true
|
||||
gci:
|
||||
custom-order: false
|
||||
section-separators:
|
||||
- newLine
|
||||
sections:
|
||||
- standard # Standard section: captures all standard packages.
|
||||
- default # Default section: contains all imports that could not be matched to another section type.
|
||||
- blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled.
|
||||
- dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled.
|
||||
importas:
|
||||
no-unaliased: true
|
||||
alias:
|
||||
# Foundation libraries
|
||||
- pkg: git.sbercloud.tech/products/paas/shared/foundation/management-server
|
||||
alias: mgmtserver
|
||||
maligned:
|
||||
suggest-new: true
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 2
|
||||
lll:
|
||||
line-length: 140
|
||||
revive:
|
||||
rules:
|
||||
# The following rules are recommended https://github.com/mgechev/revive#recommended-configuration
|
||||
- name: blank-imports
|
||||
- name: context-as-argument
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
# - name: exported
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: var-declaration
|
||||
# - name: package-comments
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: time-naming
|
||||
- name: unexported-return
|
||||
- name: indent-error-flow
|
||||
- name: errorf
|
||||
- name: empty-block
|
||||
- name: superfluous-else
|
||||
- name: unused-parameter
|
||||
- name: unreachable-code
|
||||
- name: redefines-builtin-id
|
||||
#
|
||||
# Rules in addition to the recommended configuration above.
|
||||
#
|
||||
- name: bool-literal-in-expr
|
||||
- name: constant-logical-expr
|
||||
gosec:
|
||||
excludes:
|
||||
- G307 # Deferring unsafe method "Close" on type "\*os.File"
|
||||
- G108 # Profiling endpoint is automatically exposed on /debug/pprof
|
||||
gocritic:
|
||||
enabled-tags:
|
||||
- diagnostic
|
||||
- experimental
|
||||
- performance
|
||||
disabled-checks:
|
||||
- appendAssign
|
||||
- dupImport # https://github.com/go-critic/go-critic/issues/845
|
||||
- evalOrder
|
||||
- ifElseChain
|
||||
- octalLiteral
|
||||
- regexpSimplify
|
||||
- sloppyReassign
|
||||
- truncateCmp
|
||||
- typeDefFirst
|
||||
- unnamedResult
|
||||
- unnecessaryDefer
|
||||
- whyNoLint
|
||||
- wrapperFunc
|
||||
- rangeValCopy
|
||||
- hugeParam
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- text: "at least one file in a package should have a package comment"
|
||||
linters:
|
||||
- stylecheck
|
||||
- text: "should have a package comment, unless it's in another file for this package"
|
||||
linters:
|
||||
- golint
|
||||
- text: "should have comment or be unexported"
|
||||
linters:
|
||||
- golint
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- gosec
|
||||
- dupl
|
||||
exclude-use-default: false
|
||||
|
||||
output:
|
||||
# colored-line-number|line-number|json|tab|checkstyle, default is "colored-line-number"
|
||||
format: colored-line-number
|
||||
print-linter-name: true
|
6
.mockery.yaml
Normal file
6
.mockery.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
exported: True
|
||||
inpackage: False
|
||||
keeptree: True
|
||||
case: underscore
|
||||
with-expecter: True
|
||||
inpackage-suffix: True
|
82
Dockerfile
82
Dockerfile
@ -1,10 +1,72 @@
|
||||
FROM alpine
|
||||
ADD treasurer /
|
||||
COPY prod.crt /
|
||||
COPY prod.key /
|
||||
ENV APP_ADDR=:3000
|
||||
ENV DATABASE_URI=mongodb://mongodb,mongodb2
|
||||
ENV PAYWAY_DB_URI=mongodb://mongodb,mongodb2
|
||||
ENV DEVELOPMENT=false
|
||||
RUN apk add --no-cache ca-certificates
|
||||
CMD ["/treasurer"]
|
||||
# BUILD
|
||||
FROM golang:1.20.3-alpine AS build
|
||||
|
||||
# Update depences
|
||||
RUN apk update && apk add --no-cache curl
|
||||
# Create build directory
|
||||
RUN mkdir /app/bin -p
|
||||
RUN mkdir /bin/golang-migrate -p
|
||||
# Download migrate app
|
||||
RUN GOLANG_MIGRATE_VERSION=v4.15.1 && \
|
||||
curl -L https://github.com/golang-migrate/migrate/releases/download/${GOLANG_MIGRATE_VERSION}/migrate.linux-amd64.tar.gz |\
|
||||
tar xvz migrate -C /bin/golang-migrate
|
||||
# Download health check utility
|
||||
RUN GRPC_HEALTH_PROBE_VERSION=v0.4.6 && \
|
||||
wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \
|
||||
chmod +x /bin/grpc_health_probe
|
||||
# Set home directory
|
||||
WORKDIR /app
|
||||
# Copy go.mod
|
||||
ADD go.mod go.sum /app/
|
||||
# Download go depences
|
||||
RUN go mod download
|
||||
# Copy all local files
|
||||
ADD . /app
|
||||
# Build app
|
||||
RUN GOOS=linux go build -o bin ./...
|
||||
|
||||
|
||||
|
||||
# TEST
|
||||
FROM alpine:latest AS test
|
||||
|
||||
# Install packages
|
||||
RUN apk --no-cache add ca-certificates
|
||||
ENV GO111MODULE=off
|
||||
# Create home directory
|
||||
WORKDIR /app
|
||||
# Copy build file
|
||||
COPY --from=build /app/bin/app ./app
|
||||
# CMD
|
||||
CMD [ "./app" ]
|
||||
|
||||
|
||||
# MIGRATION
|
||||
FROM alpine:latest AS migration
|
||||
|
||||
# Install packages
|
||||
RUN apk --no-cache add ca-certificates
|
||||
# Create home directory
|
||||
WORKDIR /app
|
||||
# Copy migration dir
|
||||
COPY --from=build /app/migrations/test ./migrations
|
||||
# Install migrate tool
|
||||
COPY --from=build /bin/golang-migrate /usr/local/bin
|
||||
|
||||
|
||||
|
||||
# PRODUCTION
|
||||
FROM alpine:latest AS production
|
||||
|
||||
# Install packages
|
||||
RUN apk --no-cache add ca-certificates
|
||||
# Create home directory
|
||||
WORKDIR /app
|
||||
# Copy build file
|
||||
COPY --from=build /app/bin/app ./app
|
||||
# Copy grpc health probe dir
|
||||
COPY --from=build /bin/grpc_health_probe /bin/grpc_health_probe
|
||||
# Install migrate tool
|
||||
COPY --from=build /bin/golang-migrate /usr/local/bin
|
||||
# CMD
|
||||
CMD ["./app"]
|
||||
|
@ -1,10 +0,0 @@
|
||||
FROM alpine
|
||||
ADD treasurer /
|
||||
COPY prod.crt /
|
||||
COPY prod.key /
|
||||
ENV APP_ADDR=:3000
|
||||
ENV DATABASE_URI=mongodb://mongodb
|
||||
ENV PAYWAY_DB_URI=mongodb://mongodb
|
||||
ENV DEVELOPMENT=false
|
||||
RUN apk add --no-cache ca-certificates
|
||||
CMD ["/treasurer"]
|
78
Makefile
78
Makefile
@ -1,30 +1,50 @@
|
||||
GOCMD=go
|
||||
GOBUILD=$(GOCMD) build
|
||||
GOCLEAN=$(GOCMD) clean
|
||||
GOTEST=$(GOCMD) test
|
||||
RELEASE?=$(git tag)
|
||||
COMMIT?=$(shell git rev-parse --short HEAD)
|
||||
BUILD_TIME?=$(shell date -u '+%Y-%m-%d_%H:%M:%S')
|
||||
PROJECT?=bitbucket.org/skeris/treasurer
|
||||
GOOS?=linux
|
||||
GOARCH?=amd64
|
||||
BINARY_NAME=treasurer
|
||||
PORT?=3000
|
||||
|
||||
all: build run
|
||||
clean:
|
||||
$(GOCLEAN)
|
||||
rm -f $(BINARY_NAME)
|
||||
build: clean
|
||||
CGO_ENABLED=0 GOOS=${GOOS} GOARCH=${GOARCH} $(GOBUILD) \
|
||||
-ldflags "-s -w -X ${PROJECT}/version.Release=${RELEASE} \
|
||||
-X ${PROJECT}/version.Commit=${COMMIT} -X ${PROJECT}/version.BuildTime=${BUILD_TIME}" \
|
||||
-o ${BINARY_NAME}
|
||||
container: build
|
||||
docker build -t $(BINARY_NAME):$(RELEASE) .
|
||||
#run: container
|
||||
# docker stop $(BINARY_NAME):$(RELEASE) || true && docker rm $(BINARY_NAME):$(RELEASE)
|
||||
test-build:
|
||||
CGO_ENABLED=0 $(GOTEST) -c -o ./payway/test ./payway
|
||||
docker compose up --build --force-recreate --abort-on-container-exit --force-recreate --remove-orphans --exit-code-from test
|
||||
docker compose down
|
||||
help: ## show this help
|
||||
@echo 'usage: make [target] ...'
|
||||
@echo ''
|
||||
@echo 'targets:'
|
||||
@egrep '^(.+)\:\ .*##\ (.+)' ${MAKEFILE_LIST} | sed 's/:.*##/#/' | column -t -c 2 -s '#'
|
||||
|
||||
install: ## install all go dependencies
|
||||
go get \
|
||||
github.com/bufbuild/buf/cmd/buf \
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc \
|
||||
google.golang.org/protobuf/cmd/protoc-gen-go
|
||||
|
||||
generate: ## generate grpc proto for golang
|
||||
buf generate
|
||||
|
||||
test: ## run all layers tests
|
||||
@make test.unit
|
||||
@make test.integration
|
||||
|
||||
test.unit: ## run unit tests
|
||||
go test ./internal/...
|
||||
|
||||
test.integration: ## run integration tests
|
||||
@make test.integration.up
|
||||
@make test.integration.start
|
||||
@make test.integration.down
|
||||
|
||||
test.integration.up: ## build integration test environment
|
||||
docker-compose -f deployments/test/docker-compose.yaml up -d
|
||||
|
||||
test.integration.start: ## run integration test
|
||||
go test ./tests/integration/...
|
||||
|
||||
test.integration.down: ## shutting down integration environment
|
||||
docker-compose -f deployments/test/docker-compose.yaml down --volumes --rmi local
|
||||
|
||||
run: ## run app
|
||||
go run ./cmd/app/main.go
|
||||
|
||||
mock: ## run mock
|
||||
go run ./cmd/mock/main.go
|
||||
|
||||
dev.up: ## run dev environment
|
||||
docker-compose -f deployments/dev/docker-compose.yaml up -d
|
||||
|
||||
dev.down: ## shutting down dev environment
|
||||
docker-compose -f deployments/dev/docker-compose.yaml down --volumes --rmi local
|
30
README.md
Normal file
30
README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# customer
|
||||
|
||||
Сервис customer
|
||||
|
||||
| Branch | Pipeline | Code coverage |
|
||||
| ------------- |:-----------------:| --------------:|
|
||||
| master | [](https://penahub.gitlab.yandexcloud.net/external/treasurer/-/pipelines) | [](https://penahub.gitlab.yandexcloud.net/external/treasurer/-/pipelines) |
|
||||
| staging | [](https://penahub.gitlab.yandexcloud.net/external/treasurer/-/pipelines) | [](https://penahub.gitlab.yandexcloud.net/external/treasurer/-/pipelines) |
|
||||
| dev | [](https://penahub.gitlab.yandexcloud.net/external/treasurer/-/pipelines) | [](https://penahub.gitlab.yandexcloud.net/external/treasurer/-/pipelines) |
|
||||
|
||||
## Переменные окружения приложения
|
||||
|
||||
```
|
||||
HTTP_HOST - хост приложения (HTTP)
|
||||
HTTP_PORT - порт приложения (HTTP)
|
||||
HTTP_DOMEN - домен приложения (HTTP)
|
||||
|
||||
GRPC_HOST - хост приложения (GRPC)
|
||||
GRPC_PORT - порт приложения (GRPC)
|
||||
|
||||
MONGO_HOST - хост MongoDB
|
||||
MONGO_PORT - порт MongoDB
|
||||
MONGO_USER - пользователь MongoDB
|
||||
MONGO_DB_NAME - название базы данных для подключения
|
||||
MONGO_PASSWORD - пароль пользователя MongoDB
|
||||
MONGO_AUTH - имя базы данных Mongo, по которой будет производится авторизация
|
||||
|
||||
YOOMONEY_STORE_ID - id магазина, зарегистрированного на yoomoney
|
||||
YOOMONEY_SECRET_KEY - секретный ключ yoomoney
|
||||
```
|
293
app/app.go
293
app/app.go
@ -1,293 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/skeris/bbfoundation/middleware"
|
||||
"bitbucket.org/skeris/bbfoundation/role"
|
||||
r "bitbucket.org/skeris/bbfoundation/router"
|
||||
"bitbucket.org/skeris/treasurer/dal"
|
||||
h "bitbucket.org/skeris/treasurer/handlers"
|
||||
"bitbucket.org/skeris/treasurer/payway"
|
||||
v "bitbucket.org/skeris/treasurer/version"
|
||||
"github.com/danilsolovyov/validator"
|
||||
"github.com/skeris/appInit"
|
||||
"github.com/themakers/hlog"
|
||||
"go.uber.org/zap"
|
||||
tb "gopkg.in/tucnak/telebot.v2"
|
||||
)
|
||||
|
||||
//#region ======== Application Structs & Functions ========
|
||||
|
||||
type Options struct {
|
||||
IsProduction bool `env:"IS_PRODUCTION" default:"false"`
|
||||
Development bool `env:"DEVELOPMENT" default:"true"`
|
||||
AppName string `env:"APP_NAME" default:"treasurer"`
|
||||
AppAddr string `env:"APP_ADDR" default:"localhost:3001"` //localhost:3000
|
||||
AllowedOrigins string `env:"ALLOWED_ORIGINS" default:"*"`
|
||||
AllowedHeaders string `env:"ALLOWED_HEADERS" default:"*"`
|
||||
ExposeHeaders string `env:"EXPOSE_HEADERS" default:"*"`
|
||||
MongoDbUri string `env:"DATABASE_URI" default:"mongodb+srv://user_1:cEDxC8ptLMMeoA5m@cluster0.aomle.mongodb.net/test"`
|
||||
PayWayDbUri string `env:"PAYWAY_DB_URI" default:"mongodb+srv://user_2:vW3WNWViJaXYSraT@cluster0.aomle.mongodb.net/test"`
|
||||
MongoDbTable string `env:"DATABASE_TABLE" default:"treasurer"`
|
||||
MongoCollections string `env:"COLLECTION_NAME" default:"payment"`
|
||||
}
|
||||
|
||||
type App struct {
|
||||
logger *zap.Logger
|
||||
err chan error
|
||||
}
|
||||
|
||||
func (a App) GetLogger() *zap.Logger {
|
||||
return a.logger
|
||||
}
|
||||
|
||||
func (a App) GetErr() chan error {
|
||||
return a.err
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ======== Hl Info Structs ========
|
||||
|
||||
type InfoSvcStarted struct{}
|
||||
type InfoInterruptSignal struct{}
|
||||
type InfoTerminateSignal struct{}
|
||||
type InfoSvcShuttingDown struct{}
|
||||
type InfoSvcDone struct{}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ======== Hl ErrorTypeApp Structs ========
|
||||
|
||||
type ErrorTypeApp struct {
|
||||
Error error
|
||||
}
|
||||
type ErrorCanNotServe ErrorTypeApp
|
||||
type ErrorSvcShuttingDown ErrorTypeApp
|
||||
type ErrorZlogSync ErrorTypeApp
|
||||
type ErrorConnectToMongo ErrorTypeApp
|
||||
type ErrorDisconnectFromMongo ErrorTypeApp
|
||||
type ErrorConnectToToRoles ErrorTypeApp
|
||||
|
||||
//#endregion
|
||||
|
||||
func New(ctx context.Context, options interface{}) (appInit.CommonApp, error) {
|
||||
opts := options.(Options)
|
||||
var errCh chan error
|
||||
|
||||
// Create logger
|
||||
zlog, err := zap.NewDevelopment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
zlog = zlog.WithOptions(zap.AddCallerSkip(2))
|
||||
hlogger := hlog.New(zlog)
|
||||
hlogger = hlogger.With(v.GetVersion())
|
||||
|
||||
defer func() {
|
||||
err = zlog.Sync()
|
||||
if err != nil {
|
||||
hlogger.Emit(ErrorZlogSync{err})
|
||||
}
|
||||
}()
|
||||
|
||||
// Connect to MongoDb "Treasurer"
|
||||
connMongo, err := dal.CreateMongo(ctx, hlogger, dal.MongoDbOptions{
|
||||
DalName: "MongoDB",
|
||||
URI: opts.MongoDbUri,
|
||||
DbTable: opts.MongoDbTable,
|
||||
Collections: opts.MongoCollections,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
hlogger.Emit(ErrorConnectToMongo{err})
|
||||
return App{zlog, errCh}, err
|
||||
}
|
||||
ctxL, cancL := context.WithCancel(ctx)
|
||||
defer cancL()
|
||||
|
||||
go connMongo.ListenPayment(ctxL)
|
||||
|
||||
// Connect to MongoDb "PayWay"
|
||||
connPayWay, err := dal.CreateMongo(ctx, hlogger, dal.MongoDbOptions{
|
||||
DalName: "MongoPayWay",
|
||||
URI: opts.PayWayDbUri,
|
||||
DbTable: "payway",
|
||||
Collections: "payway,paywayPayment",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
hlogger.Emit(ErrorConnectToMongo{err})
|
||||
return App{zlog, errCh}, err
|
||||
}
|
||||
|
||||
payWay, err := payway.NewPayWay(ctx, hlogger, connPayWay, connMongo)
|
||||
if err != nil {
|
||||
fmt.Println("PAYWAYERR", err)
|
||||
//return nil, err
|
||||
}
|
||||
|
||||
go connPayWay.ListenPayWay(ctx, func(data *dal.PayWay) error {
|
||||
_, ok := payWay.Cache[data.ShortName]
|
||||
if !ok {
|
||||
errText := fmt.Sprintf("%v (%v) not found in cache", data.ID, data.ShortName)
|
||||
return errors.New(errText)
|
||||
}
|
||||
|
||||
payWay.Cache[data.ShortName].UpdateData(data)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
// TODO: remove roles logic from project
|
||||
// Start Roles
|
||||
roles, err := role.NewRoles(ctx, hlogger, role.MongoDalOptions{
|
||||
DalName: "MongoRoles",
|
||||
URI: opts.MongoDbUri,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
hlogger.Emit(ErrorConnectToToRoles{err})
|
||||
return App{zlog, errCh}, err
|
||||
}
|
||||
|
||||
// Set routers
|
||||
// TODO: remove
|
||||
validators := h.CreateValidators(
|
||||
&h.RequestCreatePayment{},
|
||||
&h.RequestCreatePayout{},
|
||||
)
|
||||
|
||||
chCommon := h.CommonOpts{
|
||||
AllowedOrigins: opts.AllowedOrigins,
|
||||
Mongo: connMongo,
|
||||
Hl: hlogger,
|
||||
}
|
||||
// TODO: remove unnecessary with all usages
|
||||
crucsNotifier, err := tb.NewBot(tb.Settings{
|
||||
Token: "",
|
||||
Verbose: false,
|
||||
ParseMode: tb.ModeHTML,
|
||||
Poller: &tb.LongPoller{
|
||||
Timeout: time.Second,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: use echo or gofiber. please remove this f*cking strange shit
|
||||
// TODO: actualise api for invoice and available methods
|
||||
// invoice используется для получения ссылки на оплату. по сути он выполняет 2 действия: складывает запись запроса в базу, чтобы хранились actions которые надо выполнить в ответ на события, и запросить у соответствующего платёжного сервиса правильную платёжную ссылку
|
||||
// TODO: для каждого платёжного аггрегатора надо реализовать хендлер типа /listener/{paywayId}, где paywayId - айди аггрегатора
|
||||
|
||||
router, svcRouter, allowedRoles := r.NewCombineRouter("", r.Handlers{
|
||||
"/listener/create/refill": {
|
||||
Handle: func(w http.ResponseWriter, r *http.Request) {
|
||||
ch := h.NewHandler(w, r, chCommon, validators["RequestCreatePayment"])
|
||||
h.CreatePaymentHandler(ch, payWay, crucsNotifier)
|
||||
},
|
||||
},
|
||||
"/listener/create/payout": {
|
||||
Handle: func(w http.ResponseWriter, r *http.Request) {
|
||||
ch := h.NewHandler(w, r, chCommon, validators["RequestCreatePayout"])
|
||||
h.CreatePayoutHandler(ch, payWay)
|
||||
},
|
||||
}, // pub 0b922668de7e440f263d36bf91c506d3 sek 82afd8dad1db3785d4a94e539e142a39
|
||||
"/listener/{payWay}": {
|
||||
Handle: func(w http.ResponseWriter, r *http.Request) {
|
||||
ch := h.NewHandler(w, r, chCommon, validator.Validator{})
|
||||
h.PaymentListenerHandler(ch, payWay)
|
||||
},
|
||||
},
|
||||
"/payoutListener/{payWay}": { //TODO: remove unnecessary
|
||||
Handle: func(w http.ResponseWriter, r *http.Request) {
|
||||
ch := h.NewHandler(w, r, chCommon, validator.Validator{})
|
||||
h.PayoutListenerHandler(ch, payWay)
|
||||
},
|
||||
},
|
||||
"/listener/getPayWays": {
|
||||
Handle: func(w http.ResponseWriter, r *http.Request) {
|
||||
ch := h.NewHandler(w, r, chCommon, validator.Validator{})
|
||||
h.GetPayWays(ch, payWay)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
// TODO: remove unnecessary
|
||||
// Set Middlewares
|
||||
mw := middleware.NewMiddleware(
|
||||
opts.IsProduction,
|
||||
hlogger,
|
||||
roles,
|
||||
opts.AllowedOrigins,
|
||||
opts.AllowedHeaders,
|
||||
allowedRoles,
|
||||
opts.ExposeHeaders,
|
||||
)
|
||||
|
||||
|
||||
//TODO: remove unnecessary
|
||||
router.Use(
|
||||
mw.MiddlewareLogger,
|
||||
mw.MiddlewareOriginAccess,
|
||||
mw.MiddlewareRecovery,
|
||||
)
|
||||
|
||||
// TODO: remove unnecessary
|
||||
svcRouter.Use(
|
||||
//mw.MiddlewareJwtCookie,
|
||||
//mw.MiddlewareJwt,
|
||||
//mw.MiddlewareGetJwt,
|
||||
//mw.MiddlewareRoleAccess,
|
||||
)
|
||||
|
||||
// Startup server
|
||||
srv := &http.Server{Addr: opts.AppAddr, Handler: router}
|
||||
|
||||
go func() {
|
||||
tmplKey := "%s.key"
|
||||
tmplCrt := "%s.crt"
|
||||
//if !options.LoggerDevMode {
|
||||
tmplCrt = fmt.Sprintf(tmplCrt, "prod")
|
||||
tmplKey = fmt.Sprintf(tmplKey, "prod")
|
||||
|
||||
if err := srv.ListenAndServeTLS(tmplCrt, tmplKey); err != http.ErrServerClosed && err != nil {
|
||||
hlogger.Emit(ErrorCanNotServe{Error: err})
|
||||
}
|
||||
}()
|
||||
hlogger.Emit(InfoSvcStarted{})
|
||||
|
||||
// Graceful Shutdown
|
||||
interrupt := make(chan os.Signal, 1)
|
||||
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
|
||||
killSignal := <-interrupt
|
||||
switch killSignal {
|
||||
case os.Interrupt:
|
||||
err = errors.New("interrupted")
|
||||
hlogger.Emit(InfoInterruptSignal{})
|
||||
case syscall.SIGTERM:
|
||||
err = errors.New("terminated")
|
||||
hlogger.Emit(InfoTerminateSignal{})
|
||||
}
|
||||
|
||||
hlogger.Emit(InfoSvcShuttingDown{})
|
||||
err = srv.Shutdown(ctx)
|
||||
if err != nil {
|
||||
hlogger.Emit(ErrorSvcShuttingDown{err})
|
||||
}
|
||||
hlogger.Emit(InfoSvcDone{})
|
||||
|
||||
err = errors.New("finished") // Костыль чтобы приложение нормально закрывалось...
|
||||
return App{zlog, errCh}, err
|
||||
}
|
8
buf.gen.yaml
Normal file
8
buf.gen.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
version: v1
|
||||
plugins:
|
||||
- name: go
|
||||
out: internal/proto
|
||||
- name: go-grpc
|
||||
out: internal/proto
|
||||
opt:
|
||||
- require_unimplemented_servers=false
|
3
buf.work.yaml
Normal file
3
buf.work.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
version: v1
|
||||
directories:
|
||||
- proto
|
4
buf.yaml
Normal file
4
buf.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
version: v1
|
||||
lint:
|
||||
use:
|
||||
- DEFAULT
|
39
cmd/app/main.go
Normal file
39
cmd/app/main.go
Normal file
@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/app"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/initialize"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
logger, err := zap.NewProduction(zap.AddStacktrace(zap.DPanicLevel))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to init zap logger: %v", err)
|
||||
}
|
||||
|
||||
defer cancel()
|
||||
defer func() {
|
||||
if syncErr := logger.Sync(); syncErr != nil {
|
||||
if !errors.Is(syncErr, syscall.EBADF) && !errors.Is(syncErr, syscall.ENOTTY) {
|
||||
log.Fatalf("failed to sync zap logger: %v", syncErr)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
config, err := initialize.Configuration(".env.test")
|
||||
if err != nil {
|
||||
logger.Fatal("failed to init config: %v", zap.Error(err))
|
||||
}
|
||||
|
||||
if err := app.Run(ctx, config, logger); err != nil {
|
||||
logger.Fatal("failed to run app: %v", zap.Error(err))
|
||||
}
|
||||
}
|
40
cmd/mock/main.go
Normal file
40
cmd/mock/main.go
Normal file
@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models/yandex"
|
||||
)
|
||||
|
||||
func main() {
|
||||
mocklient := wiremock.NewClient("http://localhost:8000")
|
||||
|
||||
if err := mocklient.StubFor(wiremock.
|
||||
Post(wiremock.URLPathEqualTo("/payments")).
|
||||
WithBodyPattern(wiremock.EqualToJson(`{
|
||||
"amount": {
|
||||
"value": "150.00",
|
||||
"currency": "RUB"
|
||||
},
|
||||
"payment_method_data": {
|
||||
"type": "bank_card"
|
||||
},
|
||||
"confirmation": {
|
||||
"type": "redirect",
|
||||
"enforce": true,
|
||||
"locale": "ru_RU",
|
||||
"return_url": "https://www.example.com/return_url"
|
||||
},
|
||||
}`)).
|
||||
WillReturnJSON(
|
||||
&yandex.Payment{},
|
||||
map[string]string{"Content-Type": "application/json"},
|
||||
200,
|
||||
).
|
||||
AtPriority(1),
|
||||
); err != nil {
|
||||
log.Fatal("failed to stub <create phone payments>: %w", err)
|
||||
}
|
||||
|
||||
}
|
3
cmd/mock/mock_payments.go
Normal file
3
cmd/mock/mock_payments.go
Normal file
@ -0,0 +1,3 @@
|
||||
package main
|
||||
|
||||
func MockWebhooks() {}
|
19
compose.yml
19
compose.yml
@ -1,19 +0,0 @@
|
||||
services:
|
||||
test:
|
||||
build: ./payway
|
||||
depends_on:
|
||||
- mongo
|
||||
- mongosetup
|
||||
mongo:
|
||||
image: mongo:6
|
||||
hostname: mongo
|
||||
restart: always
|
||||
entrypoint: ["/usr/bin/mongod", "--logpath", "/dev/null","--bind_ip_all","--replSet","rs0"]
|
||||
mongosetup:
|
||||
image: mongo:6
|
||||
depends_on:
|
||||
- mongo
|
||||
restart: "no"
|
||||
logging:
|
||||
driver: "none"
|
||||
entrypoint: [ "bash", "-c", "sleep 2 && mongosh --host mongo:27017 --eval 'rs.initiate()'"]
|
104
dal/hlogger.go
104
dal/hlogger.go
@ -1,104 +0,0 @@
|
||||
package dal
|
||||
|
||||
// This file contains Hl structs for Data Access Layer
|
||||
|
||||
//#region ======== HLOGGER ERRORS ========
|
||||
|
||||
//#region ======== Common ========
|
||||
|
||||
type ErrorType struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
type ErrorDalNewClient ErrorType
|
||||
type ErrorDalUnableToConnect ErrorType
|
||||
type ErrorDalPingFailed ErrorType
|
||||
type ErrorDalDisconnectFailure ErrorType
|
||||
type ErrorDalInit ErrorType
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ======== Postgre SQL ========
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ======== MongoDB ========
|
||||
|
||||
type ErrorInsertPayment ErrorType
|
||||
type ErrorUpdatePayment ErrorType
|
||||
type ErrorGetPayment ErrorType
|
||||
type ErrorListenPayment ErrorType
|
||||
|
||||
type ErrorInsertPayWay ErrorType
|
||||
type ErrorUpdatePayWay ErrorType
|
||||
type ErrorGetPayWay ErrorType
|
||||
type ErrorListenPayWay ErrorType
|
||||
|
||||
type ErrorInsertPayout ErrorType
|
||||
type ErrorUpdatePayout ErrorType
|
||||
type ErrorGetPayout ErrorType
|
||||
type ErrorListenPayout ErrorType
|
||||
|
||||
type ErrorInsertPayWayPayment ErrorType
|
||||
type ErrorUpdatePayWayPayment ErrorType
|
||||
type ErrorDeletePayWayPayment ErrorType
|
||||
type ErrorGetPayWayPayment ErrorType
|
||||
|
||||
//#endregion
|
||||
//#endregion
|
||||
|
||||
//#region ======== HLOGGER INFO ========
|
||||
|
||||
//#region ======== MongoDB ========
|
||||
|
||||
type InfoInsertPayWay InfoType
|
||||
type InfoUpdatePayWay InfoType
|
||||
type InfoGetPayWay InfoType
|
||||
type InfoListenPayWay InfoType
|
||||
|
||||
type InfoInsertPayment InfoType
|
||||
type InfoUpdatePayment InfoType
|
||||
type InfoGetPayment InfoType
|
||||
type InfoListenPayment InfoType
|
||||
|
||||
type InfoInsertPayout InfoType
|
||||
type InfoUpdatePayout InfoType
|
||||
type InfoGetPayout InfoType
|
||||
type InfoListenPayout InfoType
|
||||
|
||||
type InfoInsertPayWayPayment InfoType
|
||||
type InfoUpdatePayWayPayment InfoType
|
||||
type InfoDeletePayWayPayment InfoType
|
||||
type InfoGetPayWayPayment InfoType
|
||||
|
||||
type InfoPayWay struct {
|
||||
CtxPayWay string
|
||||
CtxName string
|
||||
CtxEvent string
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ======== Common ========
|
||||
|
||||
type InfoType struct {
|
||||
Info interface{}
|
||||
}
|
||||
|
||||
type InfoDalConnected InfoType
|
||||
type InfoDalDisconnected InfoType
|
||||
type InfoDalInit struct {
|
||||
Result string
|
||||
}
|
||||
|
||||
type InfoDalPing struct {
|
||||
Delay int64 // Milliseconds
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ======== Postgre SQL ========
|
||||
|
||||
//#endregion
|
||||
|
||||
//#endregion
|
139
dal/mongo.go
139
dal/mongo.go
@ -1,139 +0,0 @@
|
||||
package dal
|
||||
|
||||
import (
|
||||
//"bitbucket.org/skeris/bbfoundation/sse"
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/themakers/hlog"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"go.mongodb.org/mongo-driver/mongo/readpref"
|
||||
)
|
||||
|
||||
//#region ======== Data Access Layer structs ========
|
||||
|
||||
// MongoConnection - Constructor LayerMongoDb
|
||||
type MongoConnection struct {
|
||||
conn *mongo.Client // Mongo connected pairCache
|
||||
hl hlog.Logger // HLogger for Data Access Layer
|
||||
opts MongoDbOptions // Database options
|
||||
db *mongo.Database // Database
|
||||
coll map[string]*mongo.Collection // Collections map
|
||||
}
|
||||
|
||||
// MongoDbOptions - Connect params
|
||||
type MongoDbOptions struct {
|
||||
DalName string // Name of the Data Access Layer
|
||||
URI string // MongoDB URI
|
||||
DbTable string // MongoDB name
|
||||
Collections string // MongoDB list collection names
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ======== Data Access Layer Constructor ========
|
||||
|
||||
// CreateMongo подключается к MongoDB.
|
||||
//
|
||||
// Input:
|
||||
// ctx - Application context
|
||||
// hlogger - Application logger
|
||||
// opts - Application options for MongoDB
|
||||
//
|
||||
// Return: MongoConnection, error
|
||||
//
|
||||
// Logger:
|
||||
// ErrorDalNewClient - mongo.NewClient return error
|
||||
// ErrorDalUnableToConnect - Unable to connect to MongoDB
|
||||
// InfoDalConnected - Successfully connected to MongoDB
|
||||
func CreateMongo(ctx context.Context, hlogger hlog.Logger, opts MongoDbOptions) (*MongoConnection, error) {
|
||||
hlogger = hlogger.With(opts)
|
||||
|
||||
conn, err := mongo.NewClient(options.Client().ApplyURI(opts.URI))
|
||||
|
||||
if err != nil {
|
||||
hlogger.Emit(ErrorDalNewClient{err})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctxTO, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err = conn.Connect(ctxTO)
|
||||
|
||||
if err != nil {
|
||||
hlogger.Emit(ErrorDalUnableToConnect{err})
|
||||
}
|
||||
|
||||
collections := map[string]*mongo.Collection{}
|
||||
|
||||
for _, name := range strings.Split(opts.Collections, ",") {
|
||||
collections[name] = conn.Database(opts.DbTable).Collection(name)
|
||||
}
|
||||
|
||||
mongoConn := &MongoConnection{
|
||||
conn: conn,
|
||||
hl: hlogger,
|
||||
opts: opts,
|
||||
db: conn.Database(opts.DbTable),
|
||||
coll: collections,
|
||||
}
|
||||
|
||||
_, err = mongoConn.Ping(ctx)
|
||||
|
||||
if err == nil {
|
||||
hlogger.Emit(InfoDalConnected{})
|
||||
}
|
||||
|
||||
return mongoConn, err
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ======== Data Access Layer functions ========
|
||||
|
||||
// DisconnectFromDb разрывает соединение с MongoDB
|
||||
//
|
||||
// Return: error
|
||||
//
|
||||
// Logger:
|
||||
// ErrorDalDisconnectFailure - Something is wrong
|
||||
// InfoDalDisconnected - Successfully disconnected from MongoDB
|
||||
func (mc *MongoConnection) DisconnectFromDb() error {
|
||||
err := mc.conn.Disconnect(context.TODO())
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorDalDisconnectFailure{err})
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoDalDisconnected{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Ping пингует соединение MongoDB.
|
||||
//
|
||||
// Return:
|
||||
// int64 - ping delay in milliseconds
|
||||
// error
|
||||
//
|
||||
// Logger:
|
||||
// ErrorDalPingFailed - Ping received an error
|
||||
// InfoDalPing - Ping delay in milliseconds
|
||||
func (mc *MongoConnection) Ping(ctx context.Context) (int64, error) {
|
||||
start := time.Now()
|
||||
err := mc.conn.Ping(ctx, readpref.Primary())
|
||||
delay := time.Since(start).Milliseconds()
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorDalPingFailed{err})
|
||||
} else {
|
||||
mc.hl.Emit(InfoDalPing{delay})
|
||||
}
|
||||
|
||||
return delay, err
|
||||
}
|
||||
|
||||
//#endregion
|
363
dal/payment.go
363
dal/payment.go
@ -1,363 +0,0 @@
|
||||
package dal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
const PaymentTimeout = 15 * time.Minute
|
||||
|
||||
type Payment struct {
|
||||
ID string `json:"id" bson:"_id"`
|
||||
RequesterID string `json:"requester_id" bson:"requester_id"`
|
||||
UserIP string `json:"user_ip" bson:"user_ip"`
|
||||
Email string `json:"email" bson:"email"`
|
||||
Phone string `json:"phone" bson:"phone"`
|
||||
Description string `json:"description" bson:"description"`
|
||||
IsRefill bool `json:"is_refill" bson:"is_refill"` // Флаг описывает ввод/вывод средств
|
||||
Status string `json:"status" bson:"status"` // Значения: open, wait, pending, in_progress, timeout,
|
||||
// accepted, declined
|
||||
PayWayID string `json:"payway_id" bson:"payway_id"` //
|
||||
PaymentType string `json:"payment_type" bson:"payment_type"` //
|
||||
ServiceID string `json:"service_id" bson:"service_id"` // ID платежа в платежном сервисе
|
||||
Destination string `json:"destination" bson:"destination"` // Назначение платежа. Only for payout/withdrawal
|
||||
Amount float64 `json:"amount" bson:"amount"`
|
||||
Currency string `json:"currency" bson:"currency"`
|
||||
IsFake bool `json:"is_fake" bson:"is_fake"`
|
||||
OnAccept Action `json:"on_accept" bson:"on_accept"`
|
||||
OnDecline Action `json:"on_decline" bson:"on_decline"`
|
||||
OnTimeout Action `json:"on_timeout" bson:"on_timeout"`
|
||||
PendedAt time.Time `json:"pended_at" bson:"pended_at"`
|
||||
CreatedAt time.Time `json:"created_at" bson:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
|
||||
}
|
||||
|
||||
type Action struct {
|
||||
ActionType string `json:"action_type" bson:"action_type"` // Значения: mail, vk, tg, sms, request
|
||||
Target string `json:"target" bson:"target"`
|
||||
Data string `json:"data" bson:"data"`
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) InsertPayment(ctx context.Context, record *Payment) (string, error) {
|
||||
err := record.Prepare()
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorInsertPayment{err})
|
||||
return "", nil
|
||||
}
|
||||
|
||||
result, err := mc.coll["payment"].InsertOne(ctx, record)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorInsertPayment{err})
|
||||
return "", err
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoInsertPayment{result})
|
||||
|
||||
return result.InsertedID.(string), nil
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) GetPayment(ctx context.Context, id string) (*Payment, error) {
|
||||
filter := bson.M{"_id": id}
|
||||
|
||||
var result Payment
|
||||
|
||||
err := mc.coll["payment"].FindOne(ctx, filter).Decode(&result)
|
||||
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, nil
|
||||
} else {
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayment{err})
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoGetPayment{id})
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) GetPaymentByServiceID(ctx context.Context, serviceId, isRefill string) (*Payment,
|
||||
error) {
|
||||
filter := bson.M{"api_id": serviceId}
|
||||
|
||||
switch isRefill {
|
||||
case "yes", "true":
|
||||
filter["is_refill"] = true
|
||||
case "no", "false":
|
||||
filter["is_refill"] = false
|
||||
}
|
||||
|
||||
var result Payment
|
||||
|
||||
err := mc.coll["payment"].FindOne(ctx, filter).Decode(&result)
|
||||
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, nil
|
||||
} else {
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayment{err})
|
||||
}
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoGetPayment{fmt.Sprintf("by service_id %v", serviceId)})
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) GetPaymentListByStatus(ctx context.Context, status, isRefill string) ([]Payment,
|
||||
error) {
|
||||
err := CheckPaymentStatus(status)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayment{err})
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
filter := bson.M{"status": status}
|
||||
|
||||
switch isRefill {
|
||||
case "yes", "true":
|
||||
filter["is_refill"] = true
|
||||
case "no", "false":
|
||||
filter["is_refill"] = false
|
||||
}
|
||||
|
||||
cursor, err := mc.coll["payment"].Find(ctx, filter)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayment{err})
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var results []Payment
|
||||
err = cursor.All(ctx, &results)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayment{err})
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoGetPayment{fmt.Sprintf("by status %v", status)})
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) UpdatePaymentStatus(ctx context.Context, id, status string) error {
|
||||
err := CheckPaymentStatus(status)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorUpdatePayment{err})
|
||||
return err
|
||||
}
|
||||
|
||||
update := bson.M{
|
||||
"updated_at": time.Now(),
|
||||
"status": status,
|
||||
}
|
||||
|
||||
result, err := mc.coll["payment"].UpdateByID(ctx, id, bson.D{{"$set", update}})
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorUpdatePayment{err})
|
||||
return err
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoUpdatePayment{result})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) UpdatePaymentServiceID(ctx context.Context, id, serviceId string) error {
|
||||
update := bson.M{
|
||||
"updated_at": time.Now(),
|
||||
"service_id": serviceId,
|
||||
}
|
||||
|
||||
result, err := mc.coll["payment"].UpdateByID(ctx, id, bson.D{{"$set", update}})
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorUpdatePayment{err})
|
||||
return err
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoUpdatePayment{result})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) ListenPayment(ctx context.Context) {
|
||||
operationTypes := []bson.D{{{"operationType", "update"}}}
|
||||
|
||||
matchStage := bson.D{
|
||||
{"$match", bson.D{{"$or", operationTypes}}},
|
||||
}
|
||||
|
||||
opts := options.ChangeStream().SetFullDocument(options.UpdateLookup)
|
||||
|
||||
changeStream, err := mc.coll["payment"].Watch(ctx,
|
||||
mongo.Pipeline{matchStage}, opts)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayment{err})
|
||||
return
|
||||
}
|
||||
|
||||
// routine: SetTimeout - каждые 3 минуты проверяет БД на наличие записей с истекшим PaymentTimeout
|
||||
go func() {
|
||||
for {
|
||||
paymentList, err := mc.GetPaymentListByStatus(ctx, "open", "")
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayment{err})
|
||||
} else {
|
||||
for _, payment := range paymentList {
|
||||
if time.Since(payment.CreatedAt) >= PaymentTimeout {
|
||||
err = mc.UpdatePaymentStatus(ctx, payment.ID, "timeout")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayment{err})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Прерывание
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(3 * time.Minute): // Сладкий сон
|
||||
continue
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// routine: UpdateListener
|
||||
go func() {
|
||||
// Перехват паники (см. ниже)
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
mc.hl.Emit(ErrorListenPayment{err.(error)})
|
||||
}
|
||||
}()
|
||||
|
||||
for changeStream.Next(ctx) {
|
||||
// При закрытии приложения происходит паника (change_stream.go 561). context не важен...'
|
||||
current := changeStream.Current
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayment{err})
|
||||
return
|
||||
}
|
||||
|
||||
var payment Payment
|
||||
|
||||
err = bson.Unmarshal(current.Lookup("fullDocument").Value, &payment)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayment{err})
|
||||
return
|
||||
}
|
||||
var action Action
|
||||
switch payment.Status {
|
||||
case "accepted":
|
||||
action = payment.OnAccept
|
||||
case "timeout":
|
||||
action = payment.OnTimeout
|
||||
case "declined":
|
||||
action = payment.OnDecline
|
||||
}
|
||||
|
||||
// Some work with action
|
||||
if payment.Status == "accepted" && payment.IsRefill {
|
||||
switch action.ActionType {
|
||||
case "request":
|
||||
fmt.Println("CYCLE", payment )
|
||||
buf := bytes.Buffer{}
|
||||
buf.Write([]byte(action.Data))
|
||||
if _, err := http.Post("https://fynrods.ru/bet/increase", "application/json", &buf); err != nil {
|
||||
fmt.Println("ERRINC", err )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoListenPayment{fmt.Sprintf("%v %v done", payment.ID, payment.Status)})
|
||||
}
|
||||
if err = changeStream.Err(); err != nil {
|
||||
mc.hl.Emit(ErrorListenPayment{err})
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err = changeStream.Close(context.TODO())
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayment{err})
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Payment) Prepare() error {
|
||||
err := CheckPaymentStatus(p.Status)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = CheckActionType(p.OnAccept.ActionType)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = CheckActionType(p.OnDecline.ActionType)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = CheckActionType(p.OnTimeout.ActionType)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
if p.ID == "" {
|
||||
p.ID = primitive.NewObjectIDFromTimestamp(now).Hex()
|
||||
}
|
||||
|
||||
p.CreatedAt = now
|
||||
p.UpdatedAt = now
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CheckPaymentStatus(status string) error {
|
||||
allowedStatus := map[string]struct{}{"open": {}, "wait": {}, "pending": {}, "timeout": {}, "accepted": {},
|
||||
"declined": {}, "in_progress": {}}
|
||||
|
||||
if _, ok := allowedStatus[status]; !ok {
|
||||
return errors.New("got bad status: " + status)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CheckActionType(aType string) error {
|
||||
allowedType := map[string]struct{}{"mail": {}, "vk": {}, "tg": {}, "sms": {}, "request": {}}
|
||||
|
||||
if _, ok := allowedType[aType]; !ok {
|
||||
return errors.New("got bad type: " + aType)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
359
dal/payway.go
359
dal/payway.go
@ -1,359 +0,0 @@
|
||||
package dal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/aes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const BlockSize = 16
|
||||
const PrivateKey = "SomePrivateKey1!" //16 byte
|
||||
|
||||
type PayWay struct {
|
||||
ID string `bson:"_id"`
|
||||
Name string `bson:"name"`
|
||||
ShortName string `bson:"short_name"`
|
||||
MerchantID string `bson:"merchant_id"`
|
||||
WalletID string `bson:"wallet_id"`
|
||||
Secret1 string `bson:"secret_1"`
|
||||
Secret2 string `bson:"secret_2"`
|
||||
Secret3 string `bson:"secret_3"`
|
||||
PayoutTypeList []PayoutType `bson:"payout_type_list"` // TODO: перенести так же как и payment
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
UpdatedAt time.Time `bson:"updated_at"`
|
||||
}
|
||||
|
||||
type PayoutType struct {
|
||||
Name string `bson:"name"`
|
||||
IsEnabled bool `bson:"is_enabled"`
|
||||
Currency string `bson:"currency"` // Валюта вывода: RUB, EUR, USD и т.д.
|
||||
ApiId string `bson:"api_id"`
|
||||
Commission float64 `bson:"commission"`
|
||||
Minimum float64 `bson:"minimum"`
|
||||
Maximum float64 `bson:"maximum"`
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) InsertPayWay(ctx context.Context, record PayWay) (string, error) {
|
||||
now := time.Now()
|
||||
if record.ID == "" {
|
||||
record.ID = primitive.NewObjectIDFromTimestamp(now).Hex()
|
||||
}
|
||||
record.CreatedAt = now
|
||||
record.UpdatedAt = now
|
||||
|
||||
if record.Secret1 != "" {
|
||||
s, err := EncryptAES(PrivateKey, record.Secret1)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorInsertPayWay{err})
|
||||
return "", err
|
||||
}
|
||||
|
||||
record.Secret1 = s
|
||||
}
|
||||
|
||||
if record.Secret2 != "" {
|
||||
s, err := EncryptAES(PrivateKey, record.Secret2)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorInsertPayWay{err})
|
||||
return "", err
|
||||
}
|
||||
|
||||
record.Secret2 = s
|
||||
}
|
||||
|
||||
if record.Secret3 != "" {
|
||||
s, err := EncryptAES(PrivateKey, record.Secret3)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorInsertPayWay{err})
|
||||
return "", err
|
||||
}
|
||||
|
||||
record.Secret3 = s
|
||||
}
|
||||
|
||||
result, err := mc.coll["payway"].InsertOne(ctx, record)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorInsertPayWay{err})
|
||||
return "", err
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoInsertPayWay{result})
|
||||
return result.InsertedID.(string), nil
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) UpdatePayWay(ctx context.Context, record PayWay) error {
|
||||
update := bson.M{"updated_at": time.Now()}
|
||||
|
||||
if record.Name != "" {
|
||||
update["name"] = record.Name
|
||||
}
|
||||
|
||||
if record.ShortName != "" {
|
||||
update["short_name"] = record.ShortName
|
||||
}
|
||||
|
||||
if record.MerchantID != "" {
|
||||
update["merchant_id"] = record.MerchantID
|
||||
}
|
||||
|
||||
if record.WalletID != "" {
|
||||
update["wallet_id"] = record.WalletID
|
||||
}
|
||||
if record.PayoutTypeList != nil || len(record.PayoutTypeList) != 0 {
|
||||
update["payout_type_list"] = record.PayoutTypeList
|
||||
}
|
||||
|
||||
if record.Secret1 != "" {
|
||||
s, err := EncryptAES(PrivateKey, record.Secret1)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorUpdatePayWay{err})
|
||||
return err
|
||||
}
|
||||
|
||||
update["secret_1"] = s
|
||||
}
|
||||
|
||||
if record.Secret2 != "" {
|
||||
s, err := EncryptAES(PrivateKey, record.Secret2)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorUpdatePayWay{err})
|
||||
return err
|
||||
}
|
||||
|
||||
update["secret_2"] = s
|
||||
}
|
||||
|
||||
if record.Secret3 != "" {
|
||||
s, err := EncryptAES(PrivateKey, record.Secret3)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorUpdatePayWay{err})
|
||||
return err
|
||||
}
|
||||
|
||||
update["secret_3"] = s
|
||||
}
|
||||
|
||||
result, err := mc.coll["payway"].UpdateByID(ctx, record.ID, bson.D{{"$set", update}})
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorUpdatePayWay{err})
|
||||
return err
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoUpdatePayWay{result})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) GetPayWay(ctx context.Context, id string) (*PayWay, error) {
|
||||
filter := bson.M{"_id": id}
|
||||
|
||||
var result PayWay
|
||||
|
||||
err := mc.coll["payway"].FindOne(ctx, filter).Decode(&result)
|
||||
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, nil
|
||||
} else {
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWay{err})
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if result.Secret1 != "" {
|
||||
s, err := DecryptAES(PrivateKey, result.Secret1)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWay{err})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result.Secret1 = s
|
||||
}
|
||||
|
||||
if result.Secret2 != "" {
|
||||
s, err := DecryptAES(PrivateKey, result.Secret2)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWay{err})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result.Secret2 = s
|
||||
}
|
||||
|
||||
if result.Secret3 != "" {
|
||||
s, err := DecryptAES(PrivateKey, result.Secret3)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWay{err})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result.Secret3 = s
|
||||
}
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) GetPayWayByName(ctx context.Context, name string) (*PayWay, error) {
|
||||
filter := bson.M{"name": name}
|
||||
|
||||
var result PayWay
|
||||
|
||||
err := mc.coll["payway"].FindOne(ctx, filter).Decode(&result)
|
||||
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, err
|
||||
} else {
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWay{err})
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if result.Secret1 != "" {
|
||||
s, err := DecryptAES(PrivateKey, result.Secret1)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWay{err})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result.Secret1 = s
|
||||
}
|
||||
|
||||
if result.Secret2 != "" {
|
||||
s, err := DecryptAES(PrivateKey, result.Secret2)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWay{err})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result.Secret2 = s
|
||||
}
|
||||
|
||||
if result.Secret3 != "" {
|
||||
s, err := DecryptAES(PrivateKey, result.Secret3)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWay{err})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result.Secret3 = s
|
||||
}
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
//func (mc *MongoConnection) GetPayWayListByPayoutType(ctx context.Context, name string) ([]PayWay, error) {
|
||||
//
|
||||
//}
|
||||
|
||||
func (mc *MongoConnection) ListenPayWay(ctx context.Context, updateAction func(data *PayWay) error) {
|
||||
operationTypes := []bson.D{{{"operationType", "update"}}}
|
||||
|
||||
matchStage := bson.D{
|
||||
{"$match", bson.D{{"$or", operationTypes}}},
|
||||
}
|
||||
|
||||
opts := options.ChangeStream().SetFullDocument(options.UpdateLookup)
|
||||
|
||||
changeStream, err := mc.coll["payway"].Watch(ctx,
|
||||
mongo.Pipeline{matchStage}, opts)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayWay{err})
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
// Перехват паники (см. ниже)
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
mc.hl.Emit(ErrorListenPayWay{err.(error)})
|
||||
}
|
||||
}()
|
||||
|
||||
for changeStream.Next(ctx) {
|
||||
// При закрытии приложения происходит паника (change_stream.go 561). context не важен...'
|
||||
current := changeStream.Current
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayWay{err})
|
||||
return
|
||||
}
|
||||
|
||||
var payWay PayWay
|
||||
|
||||
err = bson.Unmarshal(current.Lookup("fullDocument").Value, &payWay)
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayWay{err})
|
||||
return
|
||||
}
|
||||
|
||||
err = updateAction(&payWay)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayWay{err})
|
||||
continue
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoListenPayWay{fmt.Sprintf("%v (%v) updated", payWay.ID, payWay.ShortName)})
|
||||
}
|
||||
if err = changeStream.Err(); err != nil {
|
||||
mc.hl.Emit(ErrorListenPayWay{err})
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err = changeStream.Close(context.TODO())
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorListenPayWay{err})
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func EncryptAES(key, data string) (string, error) {
|
||||
c, err := aes.NewCipher([]byte(key))
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// @TODO: Выглядит как костыль, но что поделать?
|
||||
// Для большей безопасности можно генерировать случайную строку с указателем конца информации. example = "...`randS"
|
||||
if len(data) < BlockSize {
|
||||
x := BlockSize - len(data)
|
||||
data += strings.Repeat("`", x)
|
||||
}
|
||||
|
||||
out := make([]byte, len(data))
|
||||
c.Encrypt(out, []byte(data))
|
||||
|
||||
return hex.EncodeToString(out), nil
|
||||
}
|
||||
|
||||
func DecryptAES(key, data string) (string, error) {
|
||||
ct, _ := hex.DecodeString(data)
|
||||
|
||||
c, err := aes.NewCipher([]byte(key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
pt := make([]byte, len(ct))
|
||||
c.Decrypt(pt, ct)
|
||||
|
||||
// @TODO: Выглядит как костыль, но что поделать?
|
||||
result := strings.ReplaceAll(string(pt[:]), "`", "")
|
||||
|
||||
return result, nil
|
||||
}
|
@ -1,180 +0,0 @@
|
||||
package dal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"time"
|
||||
)
|
||||
|
||||
// @TODO: Rename to PayWayRefill
|
||||
|
||||
type PayWayPayment struct {
|
||||
ID string `bson:"_id"` // PayWay-ApiId
|
||||
ApiId string `bson:"api_id"`
|
||||
Name string `bson:"name"`
|
||||
PayWay string `bson:"payWay"`
|
||||
Currency string `bson:"currency"`
|
||||
Commission float64 `bson:"commission"`
|
||||
Minimum float64 `bson:"minimum"`
|
||||
Maximum float64 `bson:"maximum"`
|
||||
Status string `bson:"status"` // active, inactive
|
||||
CreatedAt time.Time `bson:"created_at"`
|
||||
UpdatedAt time.Time `bson:"updated_at"`
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) InsertPayWayPayment(ctx context.Context, record PayWayPayment) (string, error) {
|
||||
now := time.Now()
|
||||
|
||||
if record.ApiId == "" {
|
||||
err := errors.New("got empty apiId")
|
||||
mc.hl.Emit(ErrorInsertPayWayPayment{err})
|
||||
return "", err
|
||||
}
|
||||
|
||||
if record.PayWay == "" {
|
||||
err := errors.New("got empty payWay")
|
||||
mc.hl.Emit(ErrorInsertPayWayPayment{err})
|
||||
return "", err
|
||||
}
|
||||
|
||||
record.ID = fmt.Sprintf("%v-%v", record.PayWay, record.ApiId)
|
||||
|
||||
record.CreatedAt = now
|
||||
record.UpdatedAt = now
|
||||
|
||||
result, err := mc.coll["paywayPayment"].InsertOne(ctx, record)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorInsertPayWayPayment{err})
|
||||
return "", err
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoInsertPayWayPayment{result})
|
||||
|
||||
mc.hl.Emit(InfoPayWay{
|
||||
CtxPayWay: record.PayWay,
|
||||
CtxName: record.Name,
|
||||
CtxEvent: "add",
|
||||
})
|
||||
|
||||
return result.InsertedID.(string), nil
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) UpdatePayWayPayment(ctx context.Context, record PayWayPayment) error {
|
||||
//update := bson.M{"updated_at": time.Now()}
|
||||
|
||||
//if record.ID == "" {
|
||||
// err := errors.New("got empty id")
|
||||
// mc.hl.Emit(ErrorUpdatePayWayPayment{err})
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//if record.Name != "" {
|
||||
// update["name"] = record.Name
|
||||
//}
|
||||
//
|
||||
//if record.PayWay != "" {
|
||||
// update["payway"] = record.Name
|
||||
//}
|
||||
//
|
||||
//if record.Status != "" {
|
||||
// update["status"] = record.Name
|
||||
//}
|
||||
record.UpdatedAt = time.Now()
|
||||
|
||||
opts := options.FindOneAndUpdate().SetUpsert(true)
|
||||
|
||||
err := mc.coll["paywayPayment"].FindOneAndUpdate(ctx, bson.M{
|
||||
"_id": record.ID,
|
||||
}, bson.D{{"$set", record}}, opts).Decode(&PayWayPayment{})
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorUpdatePayWayPayment{err})
|
||||
return err
|
||||
}
|
||||
|
||||
//mc.hl.Emit(InfoInsertPayWayPayment{result})
|
||||
|
||||
if record.Status != "" {
|
||||
//update["status"] = record.Name
|
||||
|
||||
pw, _ := mc.GetPayWayPayment(ctx, record.ID)
|
||||
|
||||
if pw.Status != record.Status {
|
||||
event := "stop"
|
||||
if record.Status == "active" {
|
||||
event = "start"
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoPayWay{
|
||||
CtxPayWay: pw.PayWay,
|
||||
CtxName: pw.Name,
|
||||
CtxEvent: event,
|
||||
})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) GetPayWayPayment(ctx context.Context, id string) (*PayWayPayment, error) {
|
||||
filter := bson.M{"_id": id}
|
||||
|
||||
var result PayWayPayment
|
||||
|
||||
err := mc.coll["paywayPayment"].FindOne(ctx, filter).Decode(&result)
|
||||
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, nil
|
||||
} else {
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWayPayment{err})
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoGetPayWayPayment{result.ID})
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) GetPayWayPaymentByPayWay(ctx context.Context, payWay string) ([]PayWayPayment, error) {
|
||||
filter := bson.M{"payWay": payWay}
|
||||
|
||||
var results []PayWayPayment
|
||||
cursor, err := mc.coll["paywayPayment"].Find(ctx, filter)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWayPayment{err})
|
||||
return results, nil
|
||||
}
|
||||
|
||||
err = cursor.All(ctx, &results)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorGetPayWayPayment{err})
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoGetPayWayPayment{fmt.Sprintf("by status %v", payWay)})
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (mc *MongoConnection) DeletePayWayPayment(ctx context.Context, id string) error {
|
||||
filter := bson.M{"_id": id}
|
||||
|
||||
result, err := mc.coll["paywayPayment"].DeleteOne(ctx, filter)
|
||||
|
||||
if err != nil {
|
||||
mc.hl.Emit(ErrorDeletePayWayPayment{err})
|
||||
return err
|
||||
}
|
||||
|
||||
mc.hl.Emit(InfoDeletePayWayPayment{result})
|
||||
|
||||
return nil
|
||||
}
|
70
deployments/dev/docker-compose.yaml
Normal file
70
deployments/dev/docker-compose.yaml
Normal file
@ -0,0 +1,70 @@
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
treasurer-app:
|
||||
build:
|
||||
context: ../../.
|
||||
dockerfile: Dockerfile
|
||||
target: test
|
||||
environment:
|
||||
- HTTP_HOST=0.0.0.0
|
||||
- HTTP_PORT=8080
|
||||
- HTTP_DOMEN=http://localhost:8080
|
||||
|
||||
- GRPC_HOST=0.0.0.0
|
||||
- GRPC_PORT=8081
|
||||
|
||||
- YOOMONEY_STORE_ID = id
|
||||
- YOOMONEY_SECRET_KEY = secret
|
||||
|
||||
- MONGO_HOST=mongo
|
||||
- MONGO_PORT=27017
|
||||
- MONGO_USER=admin
|
||||
- MONGO_PASSWORD=admin
|
||||
- MONGO_DB_NAME=admin
|
||||
- MONGO_AUTH=admin
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 8081:8081
|
||||
depends_on:
|
||||
- migration
|
||||
networks:
|
||||
- dev
|
||||
|
||||
migration:
|
||||
build:
|
||||
context: ../../.
|
||||
dockerfile: Dockerfile
|
||||
target: migration
|
||||
command:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
'migrate -source file://migrations -database "mongodb://admin:admin@localhost:27017/admin?authSource=admin" up',
|
||||
]
|
||||
depends_on:
|
||||
- mongo
|
||||
networks:
|
||||
- dev
|
||||
|
||||
mongo:
|
||||
image: 'mongo:6.0.3'
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: admin
|
||||
MONGO_INITDB_ROOT_PASSWORD: admin
|
||||
ports:
|
||||
- '27017:27017'
|
||||
networks:
|
||||
- dev
|
||||
|
||||
mock:
|
||||
image: 'wiremock/wiremock:2.35.0'
|
||||
ports:
|
||||
- 8000:8080
|
||||
networks:
|
||||
- dev
|
||||
depends_on:
|
||||
- app
|
||||
|
||||
networks:
|
||||
dev:
|
54
deployments/test/docker-compose.yaml
Normal file
54
deployments/test/docker-compose.yaml
Normal file
@ -0,0 +1,54 @@
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
treasurer-app:
|
||||
build:
|
||||
context: ../../.
|
||||
dockerfile: Dockerfile
|
||||
target: test
|
||||
environment:
|
||||
- HTTP_HOST=0.0.0.0
|
||||
- HTTP_PORT=8080
|
||||
- HTTP_DOMEN=http://localhost:8080
|
||||
|
||||
- GRPC_HOST=0.0.0.0
|
||||
- GRPC_PORT=8081
|
||||
|
||||
- YOOMONEY_STORE_ID=storeid
|
||||
- YOOMONEY_SECRET_KEY=secret
|
||||
|
||||
- MONGO_HOST=mongo
|
||||
- MONGO_PORT=27017
|
||||
- MONGO_USER=admin
|
||||
- MONGO_PASSWORD=admin
|
||||
- MONGO_DB_NAME=admin
|
||||
- MONGO_AUTH=admin
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 8081:8081
|
||||
networks:
|
||||
- dev
|
||||
depends_on:
|
||||
- mongo
|
||||
|
||||
mongo:
|
||||
image: 'mongo:6.0.3'
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: admin
|
||||
MONGO_INITDB_ROOT_PASSWORD: admin
|
||||
ports:
|
||||
- '27017:27017'
|
||||
networks:
|
||||
- dev
|
||||
|
||||
mock:
|
||||
image: 'wiremock/wiremock:2.35.0'
|
||||
ports:
|
||||
- 8000:8080
|
||||
networks:
|
||||
- dev
|
||||
depends_on:
|
||||
- treasurer-app
|
||||
|
||||
networks:
|
||||
dev:
|
85
go.mod
85
go.mod
@ -1,55 +1,56 @@
|
||||
module bitbucket.org/skeris/treasurer
|
||||
module penahub.gitlab.yandexcloud.net/external/treasurer
|
||||
|
||||
go 1.18
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
bitbucket.org/skeris/bbfoundation v0.0.0-20210610132656-b53719699505
|
||||
github.com/danilsolovyov/validator v0.0.9
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/gofiber/fiber/v2 v2.38.1
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/schema v1.2.0
|
||||
github.com/rs/xid v1.3.0
|
||||
github.com/skeris/appInit v0.1.12
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33
|
||||
github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf
|
||||
go.mongodb.org/mongo-driver v1.10.1
|
||||
go.uber.org/zap v1.23.0
|
||||
gopkg.in/tucnak/telebot.v2 v2.5.0
|
||||
github.com/getkin/kin-openapi v0.118.0
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/labstack/echo/v4 v4.10.2
|
||||
github.com/sethvargo/go-envconfig v0.9.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/walkerus/go-wiremock v1.5.0
|
||||
go.mongodb.org/mongo-driver v1.11.7
|
||||
go.uber.org/zap v1.24.0
|
||||
google.golang.org/grpc v1.55.0
|
||||
google.golang.org/protobuf v1.30.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/MarsherSusanin/pena_hub_packages_common v0.0.0-20220912173602-40f15e2b8a39 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/aws/aws-sdk-go v1.34.28 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||
github.com/fatih/color v1.10.0 // indirect
|
||||
github.com/go-stack/stack v1.8.0 // indirect
|
||||
github.com/gofiber/fiber v1.14.6 // indirect
|
||||
github.com/gofiber/utils v0.0.10 // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/klauspost/compress v1.15.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/swag v0.22.4 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/invopop/yaml v0.2.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/labstack/gommon v0.4.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.4 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/themakers/identity v0.0.0-20200703212242-9142bb6b35e1 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.40.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sync v0.2.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
407
go.sum
407
go.sum
@ -1,146 +1,110 @@
|
||||
bitbucket.org/skeris/bbfoundation v0.0.0-20210610132656-b53719699505 h1:fVCLuKNCoXjNjzfz9/evcNcx2EA+WxoTjf27Ek1ANd8=
|
||||
bitbucket.org/skeris/bbfoundation v0.0.0-20210610132656-b53719699505/go.mod h1:QVOC6t15n9LpOSIgL2UjKzFdpnOsOptuZJfbrg2v0xk=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/MarsherSusanin/pena_hub_packages_common v0.0.0-20220912173602-40f15e2b8a39 h1:8IlSS2NqXq0/fvviP0tr88LJP8+qOIChikFoSeKLhEo=
|
||||
github.com/MarsherSusanin/pena_hub_packages_common v0.0.0-20220912173602-40f15e2b8a39/go.mod h1:ojl1vRFZav2wB+L603ewTi6nSJRAVSd+w4d/AednibU=
|
||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk=
|
||||
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||
github.com/danilsolovyov/validator v0.0.9 h1:XlbB/lxrfLw2Gk4QTMrrEW8wM0NzWHQmEvSHEZqScGM=
|
||||
github.com/danilsolovyov/validator v0.0.9/go.mod h1:2jwh4O+5hyKFNRQQTo395fW+l2gyRKPtv+V+uMzAbGM=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/getkin/kin-openapi v0.118.0 h1:z43njxPmJ7TaPpMSCQb7PN0dEYno4tyBPQcrFdHoLuM=
|
||||
github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
||||
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
|
||||
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
|
||||
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
|
||||
github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
||||
github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
||||
github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
|
||||
github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
|
||||
github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
|
||||
github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
|
||||
github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
|
||||
github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
|
||||
github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
|
||||
github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
|
||||
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
|
||||
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||
github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||
github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
|
||||
github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
|
||||
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
|
||||
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
|
||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||
github.com/gofiber/fiber v1.14.6 h1:QRUPvPmr8ijQuGo1MgupHBn8E+wW0IKqiOvIZPtV70o=
|
||||
github.com/gofiber/fiber v1.14.6/go.mod h1:Yw2ekF1YDPreO9V6TMYjynu94xRxZBdaa8X5HhHsjCM=
|
||||
github.com/gofiber/fiber/v2 v2.38.1 h1:GEQ/Yt3Wsf2a30iTqtLXlBYJZso0JXPovt/tmj5H9jU=
|
||||
github.com/gofiber/fiber/v2 v2.38.1/go.mod h1:t0NlbaXzuGH7I+7M4paE848fNWInZ7mfxI/Er1fTth8=
|
||||
github.com/gofiber/utils v0.0.10 h1:3Mr7X7JdCUo7CWf/i5sajSaDmArEDtti8bM1JUVso2U=
|
||||
github.com/gofiber/utils v0.0.10/go.mod h1:9J5aHFUIjq0XfknT4+hdSMG6/jzfaAgCu4HEbWDeBlo=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
|
||||
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
|
||||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
|
||||
github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
|
||||
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
|
||||
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U=
|
||||
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
|
||||
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
|
||||
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.2 h1:HFB2fbVIlhIfCfOW81bZFbiC/RvnpXSdhbF2/DJr134=
|
||||
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.12.0 h1:p4oGGk2M2UJc0wWN4lHFvIB71lxsh0T/UiKCCgFADY8=
|
||||
github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
|
||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
|
||||
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw=
|
||||
github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4=
|
||||
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/sethvargo/go-envconfig v0.9.0 h1:Q6FQ6hVEeTECULvkJZakq3dZMeBQ3JUpcKMfPQbKMDE=
|
||||
github.com/sethvargo/go-envconfig v0.9.0/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/skeris/appInit v0.1.12 h1:osGnk4d0vzUVsEV66JOmXcqiHbC2+N9IiOBjOiSCzm0=
|
||||
github.com/skeris/appInit v0.1.12/go.mod h1:4ElEeXWVGzU3dlYq/eMWJ/U5hd+LKisc1z3+ySh1XmY=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
@ -148,172 +112,165 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33 h1:N9f/Q+2Ssa+yDcbfaoLTYvXmdeyUUxsJKdPUVsjSmiA=
|
||||
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33/go.mod h1:rpcH99JknBh8seZmlOlUg51gasZH6QH34oXNsIwYT6E=
|
||||
github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf h1:TJJm6KcBssmbWzplF5lzixXl1RBAi/ViPs1GaSOkhwo=
|
||||
github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf/go.mod h1:1FsorU3vnXO9xS9SrhUp8fRb/6H/Zfll0rPt1i4GWaA=
|
||||
github.com/themakers/identity v0.0.0-20200703212242-9142bb6b35e1 h1:DuzLgIqC0AxW3Gy+Mhwn15R9KvFe8nifO6Pbe3j07Ng=
|
||||
github.com/themakers/identity v0.0.0-20200703212242-9142bb6b35e1/go.mod h1:lHYuLs7VL+KVZpEzfXnrv8YwlGXcuZgUZjV5pSRb+Fc=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=
|
||||
github.com/valyala/fasthttp v1.40.0 h1:CRq/00MfruPGFLTQKY8b+8SfdK60TxNztjRMnH0t1Yc=
|
||||
github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/walkerus/go-wiremock v1.5.0 h1:ipaYzaZnnOJRQS4wNFqz4YFphC/sM9GM+EiLEzv3KLc=
|
||||
github.com/walkerus/go-wiremock v1.5.0/go.mod h1:gMzQpReT5mG5T/PaW8pSFiPhazrcHb1mnf6JHdKwY5w=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
|
||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
|
||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
||||
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.mongodb.org/mongo-driver v1.5.2 h1:AsxOLoJTgP6YNM0fXWw4OjdluYmWzQYp+lFJL7xu9fU=
|
||||
go.mongodb.org/mongo-driver v1.5.2/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw=
|
||||
go.mongodb.org/mongo-driver v1.10.1 h1:NujsPveKwHaWuKUer/ceo9DzEe7HIj1SlJ6uvXZG0S4=
|
||||
go.mongodb.org/mongo-driver v1.10.1/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJvcs=
|
||||
go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
|
||||
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
|
||||
go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
|
||||
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
|
||||
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/tucnak/telebot.v2 v2.5.0 h1:i+NynLo443Vp+Zn3Gv9JBjh3Z/PaiKAQwcnhNI7y6Po=
|
||||
gopkg.in/tucnak/telebot.v2 v2.5.0/go.mod h1:BgaIIx50PSRS9pG59JH+geT82cfvoJU/IaI5TJdN3v8=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
@ -1,164 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"bitbucket.org/skeris/bbfoundation/jwt_adapter"
|
||||
"bitbucket.org/skeris/treasurer/dal"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/danilsolovyov/validator"
|
||||
"github.com/gorilla/schema"
|
||||
"github.com/themakers/hlog"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
//#region ======== Handler Struct ========
|
||||
|
||||
type Handler struct {
|
||||
w http.ResponseWriter
|
||||
r *http.Request
|
||||
origins string
|
||||
mongo *dal.MongoConnection
|
||||
hl hlog.Logger
|
||||
validator validator.Validator
|
||||
}
|
||||
|
||||
type CommonOpts struct {
|
||||
AllowedOrigins string
|
||||
Mongo *dal.MongoConnection
|
||||
Hl hlog.Logger
|
||||
}
|
||||
|
||||
func NewHandler(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
common CommonOpts,
|
||||
validator validator.Validator) *Handler {
|
||||
return &Handler{
|
||||
w: w, r: r,
|
||||
origins: common.AllowedOrigins,
|
||||
mongo: common.Mongo,
|
||||
hl: common.Hl,
|
||||
validator: validator,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) Prepare(w http.ResponseWriter, r *http.Request, validator validator.Validator) {
|
||||
h.w = w
|
||||
h.r = r
|
||||
h.validator = validator
|
||||
}
|
||||
|
||||
func (h *Handler) getJwtUserId() (string, error) {
|
||||
if jwtAdapter, ok := h.r.Context().Value("JWT").(*jwt_adapter.JwtAdapter); ok {
|
||||
return jwtAdapter.GetUserID(), nil
|
||||
}
|
||||
return "", errors.New("no token in context")
|
||||
}
|
||||
|
||||
// report Error - Send false Response with string error
|
||||
func (h *Handler) reportError(status int, errClient string, errLog error) {
|
||||
h.w.Header().Set("Access-Control-Allow-Origin", h.origins)
|
||||
h.w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
h.w.WriteHeader(status)
|
||||
errEncode := json.NewEncoder(h.w).Encode(Response{false, errClient})
|
||||
|
||||
if errEncode != nil {
|
||||
h.hl.Emit(ErrorReportCanNotSend{errEncode})
|
||||
}
|
||||
|
||||
h.hl.Emit(ErrorHandler{h.r.URL.String(), errLog})
|
||||
}
|
||||
|
||||
// send Response struct with http status 200
|
||||
func (h *Handler) sendResponse(response Response) {
|
||||
h.w.Header().Set("Access-Control-Allow-Origin", h.origins)
|
||||
h.w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
h.w.WriteHeader(http.StatusOK)
|
||||
err := json.NewEncoder(h.w).Encode(response)
|
||||
|
||||
if err != nil {
|
||||
h.reportError(http.StatusInternalServerError, "response failed", err)
|
||||
}
|
||||
}
|
||||
|
||||
// send response as sse
|
||||
func (h *Handler) sendSseData(data interface{}, flusher http.Flusher) {
|
||||
response, err := json.Marshal(data)
|
||||
|
||||
if err != nil {
|
||||
h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(h.w, "data: %s\n\n", response)
|
||||
flusher.Flush()
|
||||
|
||||
if err != nil {
|
||||
h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) handlePostRequest(request interface{}) error {
|
||||
decoder := validator.Decoder{Decoder: json.NewDecoder(h.r.Body)}
|
||||
err := decoder.DecodeAndValidate(request, h.validator)
|
||||
if err != nil {
|
||||
h.reportError(http.StatusBadRequest, err.Error(), err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Handler) handleGetRequest(request interface{}) error {
|
||||
//query := query
|
||||
err := h.r.ParseForm()
|
||||
if err != nil {
|
||||
h.reportError(http.StatusBadRequest, err.Error(), err)
|
||||
return err
|
||||
}
|
||||
fmt.Println("DATAAAA",h.r.Form)
|
||||
err = schema.NewDecoder().Decode(request, h.r.Form)
|
||||
|
||||
if err != nil {
|
||||
h.reportError(http.StatusBadRequest, err.Error(), err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
// MB Size constants
|
||||
const (
|
||||
MB = 1 << 20
|
||||
)
|
||||
|
||||
//#region ======== Response Structs ========
|
||||
|
||||
type Response struct {
|
||||
Success bool `json:"success"` // True if OK
|
||||
Message interface{} `json:"message"` // Message Response body
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ======== Hl Handlers Errors ========
|
||||
|
||||
type ErrorReportCanNotSend struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
type ErrorHandler struct {
|
||||
URL string
|
||||
Err error
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ======== Other functions ========
|
||||
|
||||
//#endregion
|
@ -1,196 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"bitbucket.org/skeris/treasurer/dal"
|
||||
"bitbucket.org/skeris/treasurer/payway"
|
||||
"github.com/gorilla/mux"
|
||||
tb "gopkg.in/tucnak/telebot.v2"
|
||||
)
|
||||
|
||||
type RequestCreatePayment struct {
|
||||
RequesterID string `json:"requester_id" validate:"required"`
|
||||
Amount float64 `json:"amount" validate:">0"`
|
||||
PaymentType string `json:"payment_type" validate:"required"` // Тип пополнения dal.PayWayPayment.ApiId
|
||||
Currency string `json:"currency"`
|
||||
PayWayID string `json:"payway_id" validate:"required"` // Присылать именно ID, а не shortName! id: fk1, sn: fk
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
OnAccept Action `json:"on_accept"`
|
||||
OnDecline Action `json:"on_decline"`
|
||||
OnTimeout Action `json:"on_timeout"`
|
||||
}
|
||||
|
||||
type Action struct {
|
||||
ActionType string `json:"action_type" validate:"required,format=^(mail|vk|tg|sms|request)$"`
|
||||
Target string `json:"target" validate:"required"`
|
||||
Data string `json:"data" validate:"required"`
|
||||
}
|
||||
|
||||
func CreatePaymentHandler(h *Handler, pwc *payway.PayWay, crush *tb.Bot) {
|
||||
var request RequestCreatePayment
|
||||
err := h.handlePostRequest(&request)
|
||||
if err != nil {
|
||||
fmt.Println("handlePostRequest", err)
|
||||
return
|
||||
}
|
||||
fmt.Println("Skeris1")
|
||||
|
||||
record := &dal.Payment{
|
||||
RequesterID: request.RequesterID,
|
||||
UserIP: h.r.RemoteAddr,
|
||||
Email: request.Email,
|
||||
Phone: request.Phone,
|
||||
Status: "open",
|
||||
Amount: request.Amount,
|
||||
PaymentType: request.PaymentType,
|
||||
Currency: request.Currency,
|
||||
PayWayID: request.PayWayID,
|
||||
IsRefill: true,
|
||||
OnAccept: dal.Action{ActionType: request.OnAccept.ActionType, Data: request.OnAccept.Data},
|
||||
OnDecline: dal.Action{ActionType: request.OnDecline.ActionType, Data: request.OnDecline.Data},
|
||||
OnTimeout: dal.Action{ActionType: request.OnTimeout.ActionType, Data: request.OnTimeout.Data},
|
||||
}
|
||||
fmt.Println("Skeris2")
|
||||
|
||||
id, err := h.mongo.InsertPayment(h.r.Context(), record)
|
||||
|
||||
fmt.Println("Skeris3")
|
||||
if err != nil {
|
||||
fmt.Println("InsertPayment", err)
|
||||
h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Skeris4")
|
||||
pw := pwc.GetPayWayById(request.PayWayID)
|
||||
|
||||
fmt.Println("Skeris5")
|
||||
if pw == nil {
|
||||
errs := "got bad pay_way: " + request.PayWayID
|
||||
h.reportError(http.StatusBadRequest, errs, errors.New(errs))
|
||||
return
|
||||
}
|
||||
|
||||
if request.Email == "" {
|
||||
request.Email = "solovyevdanil@yandex.ru"
|
||||
}
|
||||
if request.Phone == "" {
|
||||
request.Phone = "+79885895677"
|
||||
}
|
||||
|
||||
if request.PaymentType == "2" {
|
||||
request.PaymentType = "Qiwi"
|
||||
}
|
||||
fmt.Println("Skeris6")
|
||||
url, err := pw.CreatePaymentUrl(
|
||||
fmt.Sprintf("%.2f", request.Amount),
|
||||
id,
|
||||
request.PaymentType, // Использовать значение -1 для тестов
|
||||
request.Currency,
|
||||
"ru",
|
||||
request.Email,
|
||||
request.Phone,
|
||||
request.RequesterID,
|
||||
h.r.RemoteAddr,
|
||||
)
|
||||
|
||||
fmt.Println("Skeris7")
|
||||
if err != nil {
|
||||
fmt.Println("CreatePaymentUrl", err)
|
||||
if _, err := crush.Send(tb.ChatID(-1001572699960),
|
||||
fmt.Sprintf("Платёжка %s не справилась создать ссылку и вот почему: %s", request.PayWayID, err.Error())); err != nil {
|
||||
fmt.Println("CAN NOT NOTIFY", err)
|
||||
}
|
||||
h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Skeris8")
|
||||
h.sendResponse(Response{
|
||||
Success: true,
|
||||
Message: map[string]string{"id": id, "url": url},
|
||||
})
|
||||
}
|
||||
|
||||
func PaymentListenerHandler(h *Handler, pwc *payway.PayWay) {
|
||||
payWay := mux.Vars(h.r)["payWay"]
|
||||
var err error
|
||||
|
||||
switch payWay {
|
||||
case "fk":
|
||||
var request payway.ReqPaymentListenerFk
|
||||
err = h.handleGetRequest(&request)
|
||||
if err != nil {
|
||||
h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = pwc.Cache[payWay].PaymentListener(h.r.Context(), h.r.RemoteAddr, &request, h.mongo)
|
||||
|
||||
if err != nil {
|
||||
h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
// уведомляем фрикассу о получении данных
|
||||
// @TODO: не уверен что надо слать в конце, а не в начале... Может случиться так что фрикасса начнет бесконечно
|
||||
// долбить сервис даже если имеется ошибка в данных.
|
||||
_, err = fmt.Fprint(h.w, "YES")
|
||||
if err != nil {
|
||||
h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
return
|
||||
}
|
||||
case "bt":
|
||||
var request payway.ReqPaymentListenerBt
|
||||
|
||||
if err := h.r.ParseForm(); err != nil {
|
||||
return
|
||||
}
|
||||
request.Sign = h.r.Form.Get("sign")
|
||||
request.OrderId = h.r.Form.Get("orderId")
|
||||
request.UserComment = h.r.Form.Get("user_comment")
|
||||
amt, err := strconv.ParseFloat(h.r.Form.Get("amount"), 64)
|
||||
request.Amount = amt
|
||||
|
||||
err = pwc.Cache[payWay].PaymentListener(h.r.Context(), h.r.RemoteAddr, &request, h.mongo)
|
||||
|
||||
if err != nil {
|
||||
h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
//// уведомляем фрикассу о получении данных
|
||||
//// @TODO: не уверен что надо слать в конце, а не в начале... Может случиться так что фрикасса начнет бесконечно
|
||||
//// долбить сервис даже если имеется ошибка в данных.
|
||||
_, err = fmt.Fprint(h.w, "OK")
|
||||
//if err != nil {
|
||||
// h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
// return
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
type GetPayWaysResp struct {
|
||||
Name string `json:"name"`
|
||||
ID string `json:"ID"`
|
||||
}
|
||||
|
||||
func GetPayWays(h *Handler, pwc *payway.PayWay) {
|
||||
paymentList, err := pwc.GetPaymentList()
|
||||
|
||||
if err != nil {
|
||||
h.reportError(http.StatusInternalServerError, fmt.Sprint(err), err)
|
||||
return
|
||||
}
|
||||
|
||||
h.sendResponse(Response{
|
||||
Success: true,
|
||||
Message: paymentList,
|
||||
})
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"bitbucket.org/skeris/treasurer/dal"
|
||||
"bitbucket.org/skeris/treasurer/payway"
|
||||
"github.com/gorilla/mux"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type RequestCreatePayout struct {
|
||||
RequesterID string `json:"requester_id" validate:"required"`
|
||||
Amount float64 `json:"amount" validate:">0"` // Сумма для вывода
|
||||
Destination string `json:"destination" validate:"required"` // Счет на который выводим
|
||||
PayWayID string `json:"payway_id" validate:"required"` // Присылать именно ID, а не shortName! id: fk1, sn: fk
|
||||
PayoutType string `json:"payout_type" validate:"required"` // Тип вывода: payoutType.CommonID
|
||||
Currency string `json:"currency"`
|
||||
Description string `json:"description"` // Пока не придумал что сюда заполнять
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
IsFake bool `json:"is_fake"`
|
||||
OnAccept Action `json:"on_accept"`
|
||||
OnDecline Action `json:"on_decline"`
|
||||
OnTimeout Action `json:"on_timeout"`
|
||||
}
|
||||
|
||||
func CreatePayoutHandler(h *Handler, pwc *payway.PayWay) {
|
||||
var request RequestCreatePayout
|
||||
|
||||
err := h.handlePostRequest(&request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Добавить в монгу запись
|
||||
record := &dal.Payment{
|
||||
RequesterID: request.RequesterID,
|
||||
Amount: request.Amount,
|
||||
Destination: request.Destination,
|
||||
PayWayID: request.PayWayID,
|
||||
PaymentType: request.PayoutType,
|
||||
Currency: request.Currency,
|
||||
Description: request.Description, // Пока не придумал что сюда заполнять
|
||||
Email: request.Email,
|
||||
Phone: request.Phone,
|
||||
IsFake: request.IsFake,
|
||||
UserIP: h.r.RemoteAddr,
|
||||
Status: "open",
|
||||
OnAccept: dal.Action{ActionType: request.OnAccept.ActionType, Data: request.OnAccept.Data},
|
||||
OnDecline: dal.Action{ActionType: request.OnDecline.ActionType, Data: request.OnDecline.Data},
|
||||
OnTimeout: dal.Action{ActionType: request.OnTimeout.ActionType, Data: request.OnTimeout.Data},
|
||||
IsRefill: false,
|
||||
}
|
||||
|
||||
id, err := h.mongo.InsertPayment(h.r.Context(), record)
|
||||
|
||||
if err != nil {
|
||||
h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Добавить в очередь запись
|
||||
pwc.QueuePayout.Enqueue(id)
|
||||
|
||||
h.sendResponse(Response{
|
||||
Success: true,
|
||||
Message: map[string]string{"id": id},
|
||||
})
|
||||
}
|
||||
|
||||
func PayoutListenerHandler(h *Handler, pwc *payway.PayWay) {
|
||||
payWay := mux.Vars(h.r)["payWay"]
|
||||
var err error
|
||||
|
||||
switch payWay {
|
||||
case "fk":
|
||||
var request payway.ReqPayoutListenerFk
|
||||
err = h.handleGetRequest(&request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = pwc.Cache[payWay].PayoutListener(h.r.Context(), h.r.RemoteAddr, &request, h.mongo)
|
||||
|
||||
if err != nil {
|
||||
h.reportError(http.StatusInternalServerError, "failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/danilsolovyov/validator"
|
||||
)
|
||||
|
||||
type Validators map[string]validator.Validator
|
||||
|
||||
func CreateValidators(s ...interface{}) Validators {
|
||||
validators := Validators{}
|
||||
|
||||
for _, val := range s {
|
||||
v := validator.NewValidator(val)
|
||||
validators[v.GetName()] = v
|
||||
}
|
||||
|
||||
return validators
|
||||
}
|
115
internal/app/app.go
Normal file
115
internal/app/app.go
Normal file
@ -0,0 +1,115 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/initialize"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/server"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/swagger"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/pkg/closer"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/pkg/mongo"
|
||||
)
|
||||
|
||||
const (
|
||||
shutdownTimeout = 5 * time.Second
|
||||
)
|
||||
|
||||
func Run(ctx context.Context, config *models.Config, logger *zap.Logger) error {
|
||||
mongoDB, connectionErr := mongo.Connect(ctx, &mongo.ConnectDeps{
|
||||
Configuration: &config.Database,
|
||||
Timeout: 10 * time.Second,
|
||||
})
|
||||
if connectionErr != nil {
|
||||
return fmt.Errorf("failed connection to db: %w", connectionErr)
|
||||
}
|
||||
|
||||
closer := closer.New()
|
||||
|
||||
openapi, swaggerErr := swagger.GetSwagger()
|
||||
if swaggerErr != nil {
|
||||
return fmt.Errorf("failed to loading openapi spec: %w", swaggerErr)
|
||||
}
|
||||
|
||||
repositories, err := initialize.NewRepositories(initialize.RepositoriesDeps{
|
||||
Logger: logger,
|
||||
Database: mongoDB,
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize repositories")
|
||||
}
|
||||
|
||||
clients, err := initialize.NewClients(initialize.ClientsDeps{
|
||||
Logger: logger,
|
||||
YoomoneyConfiguration: &config.Service.YoomomeyConfiguration,
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize clients")
|
||||
}
|
||||
|
||||
services, err := initialize.NewServices(initialize.ServicesDeps{
|
||||
Logger: logger,
|
||||
Repositories: *repositories,
|
||||
Clients: *clients,
|
||||
ConfigurationHTTP: &config.HTTP,
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize services")
|
||||
}
|
||||
|
||||
controllers, err := initialize.NewControllers(initialize.ControllersDeps{
|
||||
Logger: logger,
|
||||
Services: *services,
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize controllers")
|
||||
}
|
||||
|
||||
api, err := initialize.NewAPI(controllers)
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize api")
|
||||
}
|
||||
|
||||
httpServer, err := server.NewHTTP(server.DepsHTTP{
|
||||
Logger: logger,
|
||||
Swagger: openapi,
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize http server")
|
||||
}
|
||||
|
||||
httpServer.Register(api)
|
||||
|
||||
grpcServer, err := server.NewGRPC(server.DepsGRPC{
|
||||
Logger: logger,
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize grpc server")
|
||||
}
|
||||
|
||||
grpcServer.Register(controllers.PaymentGRPC)
|
||||
|
||||
go httpServer.Run(&config.HTTP)
|
||||
go grpcServer.Run(&config.GRPC)
|
||||
|
||||
closer.Add(mongoDB.Client().Disconnect)
|
||||
closer.Add(httpServer.Stop)
|
||||
closer.Add(grpcServer.Stop)
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
logger.Info("shutting down app gracefully")
|
||||
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
|
||||
|
||||
defer cancel()
|
||||
|
||||
if err := closer.Close(shutdownCtx); err != nil {
|
||||
return fmt.Errorf("closer: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
64
internal/errors/errors.go
Normal file
64
internal/errors/errors.go
Normal file
@ -0,0 +1,64 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ErrorType error
|
||||
|
||||
var (
|
||||
ErrInternalError ErrorType = errors.New("internal error")
|
||||
ErrInvalidArgs ErrorType = errors.New("invalid arguments")
|
||||
ErrMethodNotImplemented ErrorType = errors.New("method is not implemented")
|
||||
ErrNotFound ErrorType = errors.New("record not found")
|
||||
ErrNoAccess ErrorType = errors.New("no access")
|
||||
ErrConflict ErrorType = errors.New("record already exist")
|
||||
ErrInsufficientFunds ErrorType = errors.New("insufficient funds")
|
||||
)
|
||||
|
||||
type Error interface {
|
||||
Error() string
|
||||
Type() ErrorType
|
||||
Wrap(message string) Error
|
||||
SetType(errorType ErrorType) Error
|
||||
}
|
||||
|
||||
type customError struct {
|
||||
errorType ErrorType
|
||||
err error
|
||||
}
|
||||
|
||||
func NewWithError(err error, errorType ErrorType) Error {
|
||||
return &customError{
|
||||
errorType: errorType,
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func NewWithMessage(message string, errorType ErrorType) Error {
|
||||
return &customError{
|
||||
errorType: errorType,
|
||||
err: errors.New(message),
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *customError) Error() string {
|
||||
return receiver.err.Error()
|
||||
}
|
||||
|
||||
func (receiver *customError) Type() ErrorType {
|
||||
return receiver.errorType
|
||||
}
|
||||
|
||||
func (receiver *customError) Wrap(message string) Error {
|
||||
receiver.err = fmt.Errorf("%s: %w", message, receiver.err)
|
||||
|
||||
return receiver
|
||||
}
|
||||
|
||||
func (receiver *customError) SetType(errorType ErrorType) Error {
|
||||
receiver.errorType = errorType
|
||||
|
||||
return receiver
|
||||
}
|
27
internal/errors/grpc.go
Normal file
27
internal/errors/grpc.go
Normal file
@ -0,0 +1,27 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const defaultGRPCCode = codes.Internal
|
||||
|
||||
var grpcCodes = map[error]codes.Code{
|
||||
ErrInvalidArgs: codes.InvalidArgument,
|
||||
ErrConflict: codes.AlreadyExists,
|
||||
ErrInsufficientFunds: codes.Unavailable,
|
||||
ErrInternalError: codes.Internal,
|
||||
ErrMethodNotImplemented: codes.Unimplemented,
|
||||
ErrNoAccess: codes.Unavailable,
|
||||
ErrNotFound: codes.NotFound,
|
||||
}
|
||||
|
||||
func GRPC(message string, err Error) error {
|
||||
currentStatus, ok := grpcCodes[err]
|
||||
if !ok {
|
||||
return status.Errorf(defaultGRPCCode, message, err)
|
||||
}
|
||||
|
||||
return status.Errorf(currentStatus, message, err)
|
||||
}
|
33
internal/errors/http.go
Normal file
33
internal/errors/http.go
Normal file
@ -0,0 +1,33 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
)
|
||||
|
||||
var httpStatuses = map[ErrorType]int{
|
||||
ErrInternalError: http.StatusInternalServerError,
|
||||
ErrInvalidArgs: http.StatusBadRequest,
|
||||
ErrNoAccess: http.StatusForbidden,
|
||||
ErrNotFound: http.StatusNotFound,
|
||||
ErrMethodNotImplemented: http.StatusNotImplemented,
|
||||
ErrConflict: http.StatusConflict,
|
||||
ErrInsufficientFunds: http.StatusPaymentRequired,
|
||||
}
|
||||
|
||||
func HTTP(ctx echo.Context, err Error) error {
|
||||
status, ok := httpStatuses[err.Type()]
|
||||
if !ok {
|
||||
return ctx.JSON(http.StatusInternalServerError, models.ResponseErrorHTTP{
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return ctx.JSON(status, models.ResponseErrorHTTP{
|
||||
StatusCode: status,
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
13
internal/initialize/api.go
Normal file
13
internal/initialize/api.go
Normal file
@ -0,0 +1,13 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/swagger"
|
||||
)
|
||||
|
||||
func NewAPI(controllers *Controllers) (*swagger.API, errors.Error) {
|
||||
return swagger.New(swagger.Deps{
|
||||
CommonController: controllers.CommonREST,
|
||||
YandexStatusController: controllers.YandexStatusREST,
|
||||
})
|
||||
}
|
38
internal/initialize/clients.go
Normal file
38
internal/initialize/clients.go
Normal file
@ -0,0 +1,38 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/interface/client"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
)
|
||||
|
||||
type ClientsDeps struct {
|
||||
Logger *zap.Logger
|
||||
YoomoneyConfiguration *models.YoomomeyConfiguration
|
||||
}
|
||||
|
||||
type Clients struct {
|
||||
Callback *client.CallbackClient
|
||||
Yandex *client.YandexClient
|
||||
}
|
||||
|
||||
func NewClients(deps ClientsDeps) (*Clients, errors.Error) {
|
||||
callbackClient, err := client.NewCallbackClient(client.CallbackClientDeps{Logger: deps.Logger})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
yandexClient, err := client.NewYandexClient(client.YandexClientDeps{
|
||||
Logger: deps.Logger,
|
||||
Configuration: deps.YoomoneyConfiguration,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Clients{
|
||||
Callback: callbackClient,
|
||||
Yandex: yandexClient,
|
||||
}, nil
|
||||
}
|
15
internal/initialize/config.go
Normal file
15
internal/initialize/config.go
Normal file
@ -0,0 +1,15 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/pkg/env"
|
||||
)
|
||||
|
||||
func Configuration(path string) (*models.Config, error) {
|
||||
config, err := env.Parse[models.Config](path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
52
internal/initialize/controllers.go
Normal file
52
internal/initialize/controllers.go
Normal file
@ -0,0 +1,52 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/interface/controller/grpc"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/interface/controller/rest"
|
||||
)
|
||||
|
||||
type ControllersDeps struct {
|
||||
Logger *zap.Logger
|
||||
Services Services
|
||||
}
|
||||
|
||||
type Controllers struct {
|
||||
CommonREST *rest.CommonController
|
||||
YandexStatusREST *rest.YandexStatusController
|
||||
PaymentGRPC *grpc.PaymentController
|
||||
}
|
||||
|
||||
func NewControllers(deps ControllersDeps) (*Controllers, errors.Error) {
|
||||
commonControllerREST, err := rest.NewCommonController(rest.CommonControllerDeps{
|
||||
Logger: deps.Logger,
|
||||
PaymentService: deps.Services.Payment,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
yandexStatusControllerREST, err := rest.NewYandexStatusController(rest.YandexStatusControllerDeps{
|
||||
Logger: deps.Logger,
|
||||
StatusService: deps.Services.Status,
|
||||
CallbackService: deps.Services.Callback,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
paymentControllerGRPC, err := grpc.NewPaymentController(grpc.PaymentControllerDeps{
|
||||
Logger: deps.Logger,
|
||||
PaymentService: deps.Services.Payment,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Controllers{
|
||||
CommonREST: commonControllerREST,
|
||||
YandexStatusREST: yandexStatusControllerREST,
|
||||
PaymentGRPC: paymentControllerGRPC,
|
||||
}, nil
|
||||
}
|
29
internal/initialize/repositories.go
Normal file
29
internal/initialize/repositories.go
Normal file
@ -0,0 +1,29 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/interface/repository"
|
||||
)
|
||||
|
||||
type RepositoriesDeps struct {
|
||||
Logger *zap.Logger
|
||||
Database *mongo.Database
|
||||
}
|
||||
|
||||
type Repositories struct {
|
||||
Payment *repository.PaymentRepository
|
||||
}
|
||||
|
||||
func NewRepositories(deps RepositoriesDeps) (*Repositories, errors.Error) {
|
||||
paymentRepository, err := repository.NewPaymentRepository(repository.PaymentRepositoryDeps{
|
||||
Logger: deps.Logger,
|
||||
Collection: deps.Database.Collection("payments"),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Repositories{Payment: paymentRepository}, nil
|
||||
}
|
79
internal/initialize/services.go
Normal file
79
internal/initialize/services.go
Normal file
@ -0,0 +1,79 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/service/callback"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/service/payment"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/service/status"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/service/webhook"
|
||||
)
|
||||
|
||||
type ServicesDeps struct {
|
||||
Logger *zap.Logger
|
||||
Repositories Repositories
|
||||
Clients Clients
|
||||
ConfigurationHTTP *models.ConfigurationHTTP
|
||||
}
|
||||
|
||||
type Services struct {
|
||||
Callback *callback.Service
|
||||
Payment *payment.Service
|
||||
YandexPayment *payment.Yandex
|
||||
Status *status.Service
|
||||
YandexWebhook *webhook.Yandex
|
||||
}
|
||||
|
||||
func NewServices(deps ServicesDeps) (*Services, errors.Error) {
|
||||
callbackService, err := callback.New(callback.Deps{
|
||||
Logger: deps.Logger,
|
||||
CallbackClient: deps.Clients.Callback,
|
||||
PaymentRepository: deps.Repositories.Payment,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
yandexPaymentService, err := payment.NewYandex(payment.YandexPaymentServiceDeps{
|
||||
Logger: deps.Logger,
|
||||
YandexPaymentClient: deps.Clients.Yandex,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
paymentService, err := payment.New(payment.Deps{
|
||||
Logger: deps.Logger,
|
||||
PaymentRepository: deps.Repositories.Payment,
|
||||
PaymentStrategyService: yandexPaymentService,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
statusService, err := status.New(status.Deps{
|
||||
Logger: deps.Logger,
|
||||
PaymentRepository: deps.Repositories.Payment,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
yandexWebhookService, err := webhook.NewYandex(webhook.YandexDeps{
|
||||
Logger: deps.Logger,
|
||||
YandexWebhookClient: deps.Clients.Yandex,
|
||||
Configuration: deps.ConfigurationHTTP,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Services{
|
||||
Callback: callbackService,
|
||||
Payment: paymentService,
|
||||
YandexPayment: yandexPaymentService,
|
||||
Status: statusService,
|
||||
YandexWebhook: yandexWebhookService,
|
||||
}, nil
|
||||
}
|
109
internal/interface/client/callback.go
Normal file
109
internal/interface/client/callback.go
Normal file
@ -0,0 +1,109 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/proto/payment_callback"
|
||||
)
|
||||
|
||||
type CallbackClientDeps struct {
|
||||
Logger *zap.Logger
|
||||
}
|
||||
|
||||
type CallbackClient struct {
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewCallbackClient(deps CallbackClientDeps) (*CallbackClient, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("logger is nil on <NewCallbackClient>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &CallbackClient{logger: deps.Logger}, nil
|
||||
}
|
||||
|
||||
func (receiver *CallbackClient) SendOnSuccess(ctx context.Context, host string, event *models.Event) errors.Error {
|
||||
connection, err := grpc.Dial(host, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to connect on <SendOnSuccess> of <CallbackClient>", zap.Error(err), zap.String("host", host))
|
||||
return errors.NewWithError(fmt.Errorf("failed connect to callback service: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
defer func() {
|
||||
if closeErr := connection.Close(); closeErr != nil {
|
||||
receiver.logger.Error("failed to close connection on <SendOnSuccess> of <CallbackClient>", zap.Error(closeErr))
|
||||
}
|
||||
}()
|
||||
|
||||
client := payment_callback.NewPaymentCallbackServiceClient(connection)
|
||||
|
||||
if _, err := client.OnSuccess(ctx, &payment_callback.Event{
|
||||
Key: event.Key,
|
||||
Message: event.Message,
|
||||
Payment: &payment_callback.Payment{
|
||||
ID: event.Payment.ID,
|
||||
UserID: event.Payment.UserID,
|
||||
PaymentID: event.Payment.PaymentID,
|
||||
IdempotencePaymentID: event.Payment.IdempotencePaymentID,
|
||||
Amount: event.Payment.Amount,
|
||||
Currency: event.Payment.Currency,
|
||||
Type: string(event.Payment.Type),
|
||||
Status: string(event.Payment.Status),
|
||||
Completed: event.Payment.Completed,
|
||||
},
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to send success callback on <SendOnSuccess> of <CallbackClient>",
|
||||
zap.Error(err),
|
||||
zap.String("host", host),
|
||||
zap.Any("event", event),
|
||||
)
|
||||
return errors.NewWithError(fmt.Errorf("failed to send success callback: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *CallbackClient) SendOnFailure(ctx context.Context, host string, event *models.Event) errors.Error {
|
||||
connection, err := grpc.Dial(host, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to connect on <SendOnFailure> of <CallbackClient>", zap.Error(err), zap.String("host", host))
|
||||
return errors.NewWithError(fmt.Errorf("failed connect to callback service: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
defer func() {
|
||||
if closeErr := connection.Close(); closeErr != nil {
|
||||
receiver.logger.Error("failed to close connection on <SendOnFailure> of <CallbackClient>", zap.Error(closeErr))
|
||||
}
|
||||
}()
|
||||
|
||||
client := payment_callback.NewPaymentCallbackServiceClient(connection)
|
||||
|
||||
if _, err := client.OnFailure(ctx, &payment_callback.Event{
|
||||
Key: event.Key,
|
||||
Message: event.Message,
|
||||
Payment: &payment_callback.Payment{
|
||||
ID: event.Payment.ID,
|
||||
UserID: event.Payment.UserID,
|
||||
PaymentID: event.Payment.PaymentID,
|
||||
IdempotencePaymentID: event.Payment.IdempotencePaymentID,
|
||||
Amount: event.Payment.Amount,
|
||||
Currency: event.Payment.Currency,
|
||||
Type: string(event.Payment.Type),
|
||||
Status: string(event.Payment.Status),
|
||||
Completed: event.Payment.Completed,
|
||||
},
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to send failure callback on <SendOnFailure> of <CallbackClient>",
|
||||
zap.Error(err),
|
||||
zap.String("host", host),
|
||||
zap.Any("event", event),
|
||||
)
|
||||
return errors.NewWithError(fmt.Errorf("failed to send failure callback: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
253
internal/interface/client/yandex.go
Normal file
253
internal/interface/client/yandex.go
Normal file
@ -0,0 +1,253 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models/yandex"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/utils"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/pkg/client"
|
||||
)
|
||||
|
||||
const (
|
||||
yandexPaymentsMockURL = "http://mock:8080/payments"
|
||||
yandexPaymentsProdURL = "https://api.yookassa.ru/v3/payments"
|
||||
|
||||
yandexWebhooksMockURL = "http://mock:8080/webhooks"
|
||||
yandexWebhooksProdURL = "https://api.yookassa.ru/v3/webhooks"
|
||||
)
|
||||
|
||||
const (
|
||||
yandexPaymentsURL = yandexPaymentsMockURL
|
||||
yandexWebhooksURL = yandexWebhooksMockURL
|
||||
)
|
||||
|
||||
type YandexClientDeps struct {
|
||||
Logger *zap.Logger
|
||||
Configuration *models.YoomomeyConfiguration
|
||||
}
|
||||
|
||||
type YandexClient struct {
|
||||
logger *zap.Logger
|
||||
configuration *models.YoomomeyConfiguration
|
||||
}
|
||||
|
||||
func NewYandexClient(deps YandexClientDeps) (*YandexClient, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("Logger is nil on <NewYandexClient>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.Configuration == nil {
|
||||
return nil, errors.NewWithMessage("Configuration is nil on <NewYandexClient>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &YandexClient{
|
||||
logger: deps.Logger,
|
||||
configuration: deps.Configuration,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *YandexClient) CreatePayment(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodType]) (*yandex.Payment, errors.Error) {
|
||||
response, err := client.Post[yandex.Payment, any](ctx, &client.RequestSettings{
|
||||
URL: yandexPaymentsURL,
|
||||
Body: request,
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
"Idempotence-Key": idempotenceKey,
|
||||
"Authorization": utils.ConvertYoomoneySercetsToAuth("Basic", receiver.configuration.StoreID, receiver.configuration.SecretKey),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to make request on <CreatePayment> of <YandexClient>", zap.Error(err))
|
||||
return nil, errors.NewWithError(fmt.Errorf("failed to make request: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
if response.Error != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePayment> of <YandexClient>", zap.Any("response", response.Error))
|
||||
return nil, errors.NewWithMessage("failed to create payment", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return response.Body, nil
|
||||
}
|
||||
|
||||
func (receiver *YandexClient) CreatePaymentB2B(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodB2B]) (*yandex.Payment, errors.Error) {
|
||||
response, err := client.Post[yandex.Payment, any](ctx, &client.RequestSettings{
|
||||
URL: yandexPaymentsURL,
|
||||
Body: request,
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
"Idempotence-Key": idempotenceKey,
|
||||
"Authorization": utils.ConvertYoomoneySercetsToAuth("Basic", receiver.configuration.StoreID, receiver.configuration.SecretKey),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to make request on <CreatePaymentB2B> of <YandexClient>", zap.Error(err))
|
||||
return nil, errors.NewWithError(fmt.Errorf("failed to make request: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
if response.Error != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentB2B> of <YandexClient>", zap.Any("response", response.Error))
|
||||
return nil, errors.NewWithMessage("failed to create payment", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return response.Body, nil
|
||||
}
|
||||
|
||||
func (receiver *YandexClient) CreatePaymentBankCard(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodBankCard]) (*yandex.Payment, errors.Error) {
|
||||
response, err := client.Post[yandex.Payment, any](ctx, &client.RequestSettings{
|
||||
URL: yandexPaymentsURL,
|
||||
Body: request,
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
"Idempotence-Key": idempotenceKey,
|
||||
"Authorization": utils.ConvertYoomoneySercetsToAuth("Basic", receiver.configuration.StoreID, receiver.configuration.SecretKey),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to make request on <CreatePaymentBankCard> of <YandexClient>", zap.Error(err))
|
||||
return nil, errors.NewWithError(fmt.Errorf("failed to make request: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
if response.Error != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentBankCard> of <YandexClient>", zap.Any("response", response.Error))
|
||||
return nil, errors.NewWithMessage("failed to create payment", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return response.Body, nil
|
||||
}
|
||||
|
||||
func (receiver *YandexClient) CreatePaymentLogin(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodLogin]) (*yandex.Payment, errors.Error) {
|
||||
response, err := client.Post[yandex.Payment, any](ctx, &client.RequestSettings{
|
||||
URL: yandexPaymentsURL,
|
||||
Body: request,
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
"Idempotence-Key": idempotenceKey,
|
||||
"Authorization": utils.ConvertYoomoneySercetsToAuth("Basic", receiver.configuration.StoreID, receiver.configuration.SecretKey),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to make request on <CreatePaymentLogin> of <YandexClient>", zap.Error(err))
|
||||
return nil, errors.NewWithError(fmt.Errorf("failed to make request: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
if response.Error != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentLogin> of <YandexClient>", zap.Any("response", response.Error))
|
||||
return nil, errors.NewWithMessage("failed to create payment", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return response.Body, nil
|
||||
}
|
||||
|
||||
func (receiver *YandexClient) CreatePaymentPhone(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodPhone]) (*yandex.Payment, errors.Error) {
|
||||
response, err := client.Post[yandex.Payment, any](ctx, &client.RequestSettings{
|
||||
URL: yandexPaymentsURL,
|
||||
Body: request,
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
"Idempotence-Key": idempotenceKey,
|
||||
"Authorization": utils.ConvertYoomoneySercetsToAuth("Basic", receiver.configuration.StoreID, receiver.configuration.SecretKey),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to make request on <CreatePaymentPhone> of <YandexClient>", zap.Error(err))
|
||||
return nil, errors.NewWithError(fmt.Errorf("failed to make request: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
if response.Error != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentPhone> of <YandexClient>", zap.Any("response", response.Error))
|
||||
return nil, errors.NewWithMessage("failed to create payment", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return response.Body, nil
|
||||
}
|
||||
|
||||
func (receiver *YandexClient) DeleteWebhook(ctx context.Context, webhookID string) errors.Error {
|
||||
url, err := url.JoinPath(yandexWebhooksURL, webhookID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to join path url on <DeleteWebhook> of <YandexClient>",
|
||||
zap.Error(err),
|
||||
zap.String("yandex webhook url", yandexWebhooksURL),
|
||||
zap.String("webhookID", webhookID),
|
||||
)
|
||||
|
||||
return errors.NewWithError(fmt.Errorf("failed to join url path: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
response, err := client.Delete[any, any](ctx, &client.RequestSettings{
|
||||
URL: url,
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
|
||||
// TODO: узнать о получении access token
|
||||
"Authorization": utils.ConvertYoomoneySercetsToAuth("Basic", receiver.configuration.StoreID, receiver.configuration.SecretKey),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to make request on <DeleteWebhook> of <YandexClient>", zap.Error(err))
|
||||
return errors.NewWithError(fmt.Errorf("failed to make request: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
if response.Error != nil {
|
||||
receiver.logger.Error("failed to delete webhook on <DeleteWebhook> of <YandexClient>",
|
||||
zap.Any("response", response.Error),
|
||||
zap.String("url", url),
|
||||
)
|
||||
|
||||
return errors.NewWithMessage("failed to create payment", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *YandexClient) GetWebhookEvents(ctx context.Context) ([]yandex.Webhook, errors.Error) {
|
||||
response, err := client.Delete[[]yandex.Webhook, any](ctx, &client.RequestSettings{
|
||||
URL: yandexWebhooksURL,
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
|
||||
// TODO: узнать о получении access token
|
||||
"Authorization": utils.ConvertYoomoneySercetsToAuth("Basic", receiver.configuration.StoreID, receiver.configuration.SecretKey),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to make request on <DeleteWebhook> of <YandexClient>", zap.Error(err))
|
||||
return []yandex.Webhook{}, errors.NewWithError(fmt.Errorf("failed to make request: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
if response.Error != nil {
|
||||
receiver.logger.Error("failed to delete webhook on <DeleteWebhook> of <YandexClient>",
|
||||
zap.Any("response", response.Error),
|
||||
zap.String("url", yandexWebhooksURL),
|
||||
)
|
||||
|
||||
return []yandex.Webhook{}, errors.NewWithMessage("failed to create payment", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return *response.Body, nil
|
||||
}
|
||||
|
||||
func (receiver *YandexClient) SetWebhookEvent(ctx context.Context, idempotenceKey string, request *yandex.CreateWebhookRequest) (string, errors.Error) {
|
||||
response, err := client.Post[yandex.Webhook, any](ctx, &client.RequestSettings{
|
||||
URL: yandexWebhooksURL,
|
||||
Body: request,
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
"Idempotence-Key": idempotenceKey,
|
||||
|
||||
// TODO: узнать о получении access token
|
||||
"Authorization": utils.ConvertYoomoneySercetsToAuth("Basic", receiver.configuration.StoreID, receiver.configuration.SecretKey),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to make request on <DeleteWebhook> of <YandexClient>", zap.Error(err))
|
||||
return "", errors.NewWithError(fmt.Errorf("failed to make request: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
if response.Error != nil {
|
||||
receiver.logger.Error("failed to delete webhook on <DeleteWebhook> of <YandexClient>",
|
||||
zap.Any("response", response.Error),
|
||||
zap.String("url", yandexWebhooksURL),
|
||||
)
|
||||
|
||||
return "", errors.NewWithMessage("failed to create payment", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return response.Body.ID, nil
|
||||
}
|
240
internal/interface/controller/grpc/payment.go
Normal file
240
internal/interface/controller/grpc/payment.go
Normal file
@ -0,0 +1,240 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/proto/treasurer"
|
||||
)
|
||||
|
||||
type PaymentService interface {
|
||||
CreatePaymentPhone(context.Context, *models.CreatePayment[string]) (string, errors.Error)
|
||||
CreatePaymentBankCard(context.Context, *models.CreatePayment[*models.BankCard]) (string, errors.Error)
|
||||
CreatePayment(context.Context, *models.CreatePayment[*any]) (string, errors.Error)
|
||||
CreatePaymentLogin(context.Context, *models.CreatePayment[string]) (string, errors.Error)
|
||||
}
|
||||
|
||||
type PaymentControllerDeps struct {
|
||||
Logger *zap.Logger
|
||||
PaymentService PaymentService
|
||||
}
|
||||
|
||||
type PaymentController struct {
|
||||
logger *zap.Logger
|
||||
paymentService PaymentService
|
||||
}
|
||||
|
||||
func NewPaymentController(deps PaymentControllerDeps) (*PaymentController, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("Logger in nil on <NewPaymentController>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.PaymentService == nil {
|
||||
return nil, errors.NewWithMessage("PaymentService in nil on <NewPaymentController>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &PaymentController{
|
||||
logger: deps.Logger,
|
||||
paymentService: deps.PaymentService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkBankCard(ctx context.Context, in *treasurer.GetBankCardPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePaymentBankCard(ctx, &models.CreatePayment[*models.BankCard]{
|
||||
Type: models.PaymentTypeBankCard,
|
||||
Currency: in.MainSettings.Currency,
|
||||
UserID: in.MainSettings.UserID,
|
||||
ClientIP: in.MainSettings.ClientIP,
|
||||
Amount: in.MainSettings.Amount,
|
||||
CallbackHostGRPC: in.MainSettings.CallbackHostGRPC,
|
||||
ReturnURL: in.MainSettings.ReturnURL,
|
||||
Requisites: &models.BankCard{
|
||||
Number: in.BankCard.Number,
|
||||
ExpiryYear: in.BankCard.ExpiryYear,
|
||||
ExpiryMonth: in.BankCard.ExpiryMonth,
|
||||
CSC: in.BankCard.CSC,
|
||||
CardHolderName: in.BankCard.CardHolderName,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkBankCard> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkYooMoney(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePayment(ctx, &models.CreatePayment[*any]{
|
||||
Type: models.PaymentTypeYoomoney,
|
||||
Currency: in.MainSettings.Currency,
|
||||
UserID: in.MainSettings.UserID,
|
||||
ClientIP: in.MainSettings.ClientIP,
|
||||
Amount: in.MainSettings.Amount,
|
||||
CallbackHostGRPC: in.MainSettings.CallbackHostGRPC,
|
||||
ReturnURL: in.MainSettings.ReturnURL,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkYooMoney> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkQIWI(ctx context.Context, in *treasurer.GetPhonePaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePaymentPhone(ctx, &models.CreatePayment[string]{
|
||||
Type: models.PaymentTypeQiwi,
|
||||
Currency: in.MainSettings.Currency,
|
||||
UserID: in.MainSettings.UserID,
|
||||
ClientIP: in.MainSettings.ClientIP,
|
||||
Amount: in.MainSettings.Amount,
|
||||
CallbackHostGRPC: in.MainSettings.CallbackHostGRPC,
|
||||
ReturnURL: in.MainSettings.ReturnURL,
|
||||
Requisites: in.Phone,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkQIWI> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkSberPay(ctx context.Context, in *treasurer.GetPhonePaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePaymentPhone(ctx, &models.CreatePayment[string]{
|
||||
Type: models.PaymentTypeSberPay,
|
||||
Currency: in.MainSettings.Currency,
|
||||
UserID: in.MainSettings.UserID,
|
||||
ClientIP: in.MainSettings.ClientIP,
|
||||
Amount: in.MainSettings.Amount,
|
||||
CallbackHostGRPC: in.MainSettings.CallbackHostGRPC,
|
||||
ReturnURL: in.MainSettings.ReturnURL,
|
||||
Requisites: in.Phone,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkSberPay> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkAlfaClick(ctx context.Context, in *treasurer.GetLoginPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePaymentLogin(ctx, &models.CreatePayment[string]{
|
||||
Type: models.PaymentTypeAlfabank,
|
||||
Currency: in.MainSettings.Currency,
|
||||
UserID: in.MainSettings.UserID,
|
||||
ClientIP: in.MainSettings.ClientIP,
|
||||
Amount: in.MainSettings.Amount,
|
||||
CallbackHostGRPC: in.MainSettings.CallbackHostGRPC,
|
||||
ReturnURL: in.MainSettings.ReturnURL,
|
||||
Requisites: in.Login,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkAlfaClick> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkTinkoff(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePayment(ctx, &models.CreatePayment[*any]{
|
||||
Type: models.PaymentTypeTinkoff,
|
||||
Currency: in.MainSettings.Currency,
|
||||
UserID: in.MainSettings.UserID,
|
||||
ClientIP: in.MainSettings.ClientIP,
|
||||
Amount: in.MainSettings.Amount,
|
||||
CallbackHostGRPC: in.MainSettings.CallbackHostGRPC,
|
||||
ReturnURL: in.MainSettings.ReturnURL,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkTinkoff> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkSBP(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePayment(ctx, &models.CreatePayment[*any]{
|
||||
Type: models.PaymentTypeSBP,
|
||||
Currency: in.MainSettings.Currency,
|
||||
UserID: in.MainSettings.UserID,
|
||||
ClientIP: in.MainSettings.ClientIP,
|
||||
Amount: in.MainSettings.Amount,
|
||||
CallbackHostGRPC: in.MainSettings.CallbackHostGRPC,
|
||||
ReturnURL: in.MainSettings.ReturnURL,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkSBP> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkMobile(ctx context.Context, in *treasurer.GetPhonePaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePaymentPhone(ctx, &models.CreatePayment[string]{
|
||||
Type: models.PaymentTypeMobile,
|
||||
Currency: in.MainSettings.Currency,
|
||||
UserID: in.MainSettings.UserID,
|
||||
ClientIP: in.MainSettings.ClientIP,
|
||||
Amount: in.MainSettings.Amount,
|
||||
CallbackHostGRPC: in.MainSettings.CallbackHostGRPC,
|
||||
ReturnURL: in.MainSettings.ReturnURL,
|
||||
Requisites: in.Phone,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkMobile> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkCash(ctx context.Context, in *treasurer.GetPhonePaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePaymentPhone(ctx, &models.CreatePayment[string]{
|
||||
Type: models.PaymentTypeCash,
|
||||
Currency: in.MainSettings.Currency,
|
||||
UserID: in.MainSettings.UserID,
|
||||
ClientIP: in.MainSettings.ClientIP,
|
||||
Amount: in.MainSettings.Amount,
|
||||
CallbackHostGRPC: in.MainSettings.CallbackHostGRPC,
|
||||
ReturnURL: in.MainSettings.ReturnURL,
|
||||
Requisites: in.Phone,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkCash> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkInstallments(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePayment(ctx, &models.CreatePayment[*any]{
|
||||
Type: models.PaymentTypeInstallments,
|
||||
Currency: in.MainSettings.Currency,
|
||||
UserID: in.MainSettings.UserID,
|
||||
ClientIP: in.MainSettings.ClientIP,
|
||||
Amount: in.MainSettings.Amount,
|
||||
CallbackHostGRPC: in.MainSettings.CallbackHostGRPC,
|
||||
ReturnURL: in.MainSettings.ReturnURL,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkInstallments> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentController) GetPaymentLinkSberbankB2B(_ context.Context, _ *treasurer.GetB2BPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method not implemented")
|
||||
}
|
50
internal/interface/controller/rest/common.go
Normal file
50
internal/interface/controller/rest/common.go
Normal file
@ -0,0 +1,50 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
)
|
||||
|
||||
type PaymentService interface {
|
||||
GetAvailablePaymentMethods(context.Context) ([]models.PaymentType, errors.Error)
|
||||
}
|
||||
|
||||
type CommonControllerDeps struct {
|
||||
Logger *zap.Logger
|
||||
PaymentService PaymentService
|
||||
}
|
||||
|
||||
type CommonController struct {
|
||||
logger *zap.Logger
|
||||
paymentService PaymentService
|
||||
}
|
||||
|
||||
func NewCommonController(deps CommonControllerDeps) (*CommonController, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("Logger in nil on <NewCommonController>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.PaymentService == nil {
|
||||
return nil, errors.NewWithMessage("PaymentService in nil on <NewCommonController>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &CommonController{
|
||||
logger: deps.Logger,
|
||||
paymentService: deps.PaymentService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *CommonController) GetAvailablePayments(ctx echo.Context) error {
|
||||
methods, err := receiver.paymentService.GetAvailablePaymentMethods(ctx.Request().Context())
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetAvailablePayments> of <CommonController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, methods)
|
||||
}
|
137
internal/interface/controller/rest/yandex.go
Normal file
137
internal/interface/controller/rest/yandex.go
Normal file
@ -0,0 +1,137 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models/yandex"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/utils/echotools"
|
||||
)
|
||||
|
||||
type StatusService interface {
|
||||
SetStatusCanceled(context.Context, string) (*models.Payment, errors.Error)
|
||||
SetStatusSuccess(context.Context, string) (*models.Payment, errors.Error)
|
||||
SetStatusWaiting(context.Context, string) (*models.Payment, errors.Error)
|
||||
SetStatusRefund(context.Context, string) (*models.Payment, errors.Error)
|
||||
}
|
||||
|
||||
type CallbackService interface {
|
||||
OnSuccess(context.Context, *models.Event) errors.Error
|
||||
OnFailure(context.Context, *models.Event) errors.Error
|
||||
}
|
||||
|
||||
type YandexStatusControllerDeps struct {
|
||||
Logger *zap.Logger
|
||||
StatusService StatusService
|
||||
CallbackService CallbackService
|
||||
}
|
||||
|
||||
type YandexStatusController struct {
|
||||
logger *zap.Logger
|
||||
statusService StatusService
|
||||
callbackService CallbackService
|
||||
}
|
||||
|
||||
func NewYandexStatusController(deps YandexStatusControllerDeps) (*YandexStatusController, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("logger is nil on <NewYandexStatusController>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.StatusService == nil {
|
||||
return nil, errors.NewWithMessage("StatusService is nil on <NewYandexStatusController>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.CallbackService == nil {
|
||||
return nil, errors.NewWithMessage("CallbackService is nil on <NewYandexStatusController>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &YandexStatusController{
|
||||
logger: deps.Logger,
|
||||
statusService: deps.StatusService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *YandexStatusController) SetPaymentStatusCanceled(ctx echo.Context) error {
|
||||
request, err := echotools.Bind[yandex.WebhookNotification[yandex.Payment]](ctx)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to parse body on <SetPaymentStatusCanceled> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse input body: %w", err), errors.ErrInternalError))
|
||||
}
|
||||
|
||||
payment, setStatusErr := receiver.statusService.SetStatusCanceled(ctx.Request().Context(), request.Object.ID)
|
||||
if setStatusErr != nil {
|
||||
receiver.logger.Error("failed to set canceled payment status on <SetPaymentStatusCanceled> of <YandexStatusController>", zap.Error(setStatusErr))
|
||||
return errors.HTTP(ctx, setStatusErr)
|
||||
}
|
||||
|
||||
if err := receiver.callbackService.OnFailure(ctx.Request().Context(), &models.Event{
|
||||
Key: string(request.Event),
|
||||
Message: "yandex send event: payment canceled",
|
||||
Payment: payment,
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed send success callback on <SetPaymentStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, nil)
|
||||
}
|
||||
|
||||
func (receiver *YandexStatusController) SetPaymentStatusSucceeded(ctx echo.Context) error {
|
||||
request, err := echotools.Bind[yandex.WebhookNotification[yandex.Payment]](ctx)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to parse body on <SetPaymentStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse input body: %w", err), errors.ErrInternalError))
|
||||
}
|
||||
|
||||
payment, setStatusErr := receiver.statusService.SetStatusSuccess(ctx.Request().Context(), request.Object.ID)
|
||||
if setStatusErr != nil {
|
||||
receiver.logger.Error("failed to set success payment status on <SetPaymentStatusSucceeded> of <YandexStatusController>", zap.Error(setStatusErr))
|
||||
return errors.HTTP(ctx, setStatusErr)
|
||||
}
|
||||
|
||||
if err := receiver.callbackService.OnSuccess(ctx.Request().Context(), &models.Event{
|
||||
Key: string(request.Event),
|
||||
Message: "yandex send event: payment succeeded",
|
||||
Payment: payment,
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed send success callback on <SetPaymentStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, nil)
|
||||
}
|
||||
|
||||
func (receiver *YandexStatusController) SetPaymentStatusWaiting(ctx echo.Context) error {
|
||||
request, err := echotools.Bind[yandex.WebhookNotification[yandex.Payment]](ctx)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to parse body on <SetPaymentStatusWaiting> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse input body: %w", err), errors.ErrInternalError))
|
||||
}
|
||||
|
||||
if _, err := receiver.statusService.SetStatusWaiting(ctx.Request().Context(), request.Object.ID); err != nil {
|
||||
receiver.logger.Error("failed to set waiting payment status on <SetPaymentStatusWaiting> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, nil)
|
||||
}
|
||||
|
||||
func (receiver *YandexStatusController) SetRefundStatusSucceeded(ctx echo.Context) error {
|
||||
request, err := echotools.Bind[yandex.WebhookNotification[yandex.Payment]](ctx)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to parse body on <SetRefundStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse input body: %w", err), errors.ErrInternalError))
|
||||
}
|
||||
|
||||
if _, err := receiver.statusService.SetStatusRefund(ctx.Request().Context(), request.Object.ID); err != nil {
|
||||
receiver.logger.Error("failed to set payment status refund on <SetRefundStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, nil)
|
||||
}
|
158
internal/interface/repository/payment.go
Normal file
158
internal/interface/repository/payment.go
Normal file
@ -0,0 +1,158 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
)
|
||||
|
||||
var PaymentFields = struct {
|
||||
ID string
|
||||
UserID string
|
||||
PaymentID string
|
||||
IdempotencePaymentID string
|
||||
ClientIP string
|
||||
Currency string
|
||||
Amount string
|
||||
Type string
|
||||
Status string
|
||||
Completed string
|
||||
IsDeleted string
|
||||
CreatedAt string
|
||||
UpdatedAt string
|
||||
DeletedAt string
|
||||
RawPaymentBody string
|
||||
CallbackHostGRPC string
|
||||
}{
|
||||
ID: "_id",
|
||||
UserID: "userId",
|
||||
PaymentID: "paymentId",
|
||||
IdempotencePaymentID: "idempotencePaymentId",
|
||||
ClientIP: "clientIp",
|
||||
Currency: "currency",
|
||||
Amount: "amount",
|
||||
Type: "type",
|
||||
Status: "status",
|
||||
Completed: "completed",
|
||||
IsDeleted: "isDeleted",
|
||||
CreatedAt: "createdAt",
|
||||
UpdatedAt: "updatedAt",
|
||||
DeletedAt: "deletedAt",
|
||||
RawPaymentBody: "rawPaymentBody",
|
||||
CallbackHostGRPC: "callbackHostGrpc",
|
||||
}
|
||||
|
||||
type PaymentRepositoryDeps struct {
|
||||
Logger *zap.Logger
|
||||
Collection *mongo.Collection
|
||||
}
|
||||
|
||||
type PaymentRepository struct {
|
||||
logger *zap.Logger
|
||||
collection *mongo.Collection
|
||||
}
|
||||
|
||||
func NewPaymentRepository(deps PaymentRepositoryDeps) (*PaymentRepository, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("Logger in nil on <NewPaymentRepository>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.Collection == nil {
|
||||
return nil, errors.NewWithMessage("Collection in nil on <NewPaymentRepository>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &PaymentRepository{
|
||||
logger: deps.Logger,
|
||||
collection: deps.Collection,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentRepository) SetPaymentComplete(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
payment := models.Payment{}
|
||||
options := options.FindOneAndUpdate().SetReturnDocument(options.After)
|
||||
filter := bson.M{PaymentFields.PaymentID: paymentID}
|
||||
update := bson.M{"$set": bson.M{
|
||||
PaymentFields.Completed: true,
|
||||
PaymentFields.UpdatedAt: time.Now(),
|
||||
}}
|
||||
|
||||
if err := receiver.collection.FindOneAndUpdate(ctx, filter, update, options).Decode(&payment); err != nil {
|
||||
receiver.logger.Error("failed to set payment complete on <SetPaymentComplete> of <PaymentRepository>",
|
||||
zap.Error(err),
|
||||
zap.String("paymentID", paymentID),
|
||||
)
|
||||
|
||||
removeErr := errors.NewWithError(
|
||||
fmt.Errorf("failed to set payment complete with <%s> on <SetPaymentComplete> of <PaymentRepository>: %w", paymentID, err),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, removeErr.SetType(errors.ErrNotFound)
|
||||
}
|
||||
|
||||
return nil, removeErr
|
||||
}
|
||||
|
||||
return &payment, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentRepository) Insert(ctx context.Context, payment *models.Payment) (*models.Payment, errors.Error) {
|
||||
sanitizedPayment := payment.Sanitize()
|
||||
|
||||
result, err := receiver.collection.InsertOne(ctx, sanitizedPayment)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to insert payment on <Insert> of <PaymentRepository>",
|
||||
zap.Any("payment", sanitizedPayment),
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
return nil, errors.NewWithError(
|
||||
fmt.Errorf("failed to insert payment on <Insert> of <AccountRepository>: %w", err),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
}
|
||||
|
||||
insertedID := result.InsertedID.(primitive.ObjectID).Hex()
|
||||
sanitizedPayment.ID = insertedID
|
||||
|
||||
return sanitizedPayment, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentRepository) SetPaymentStatus(ctx context.Context, paymentID string, status models.PaymentStatus) (*models.Payment, errors.Error) {
|
||||
payment := models.Payment{}
|
||||
options := options.FindOneAndUpdate().SetReturnDocument(options.After)
|
||||
filter := bson.M{PaymentFields.PaymentID: paymentID}
|
||||
update := bson.M{"$set": bson.M{
|
||||
PaymentFields.Status: status,
|
||||
PaymentFields.UpdatedAt: time.Now(),
|
||||
}}
|
||||
|
||||
if err := receiver.collection.FindOneAndUpdate(ctx, filter, update, options).Decode(&payment); err != nil {
|
||||
receiver.logger.Error("failed to set payment status on <SetPaymentStatus> of <PaymentRepository>",
|
||||
zap.Error(err),
|
||||
zap.String("paymentID", paymentID),
|
||||
)
|
||||
|
||||
removeErr := errors.NewWithError(
|
||||
fmt.Errorf("failed to set payment status with <%s> on <SetPaymentStatus> of <PaymentRepository>: %w", paymentID, err),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, removeErr.SetType(errors.ErrNotFound)
|
||||
}
|
||||
|
||||
return nil, removeErr
|
||||
}
|
||||
|
||||
return &payment, nil
|
||||
}
|
6
internal/models/common.go
Normal file
6
internal/models/common.go
Normal file
@ -0,0 +1,6 @@
|
||||
package models
|
||||
|
||||
type ResponseErrorHTTP struct {
|
||||
StatusCode int `json:"statusCode"`
|
||||
Message string `json:"message"`
|
||||
}
|
32
internal/models/config.go
Normal file
32
internal/models/config.go
Normal file
@ -0,0 +1,32 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/pkg/mongo"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
HTTP ConfigurationHTTP
|
||||
GRPC ConfigurationGRPC
|
||||
Service ServiceConfiguration
|
||||
Database mongo.Configuration
|
||||
}
|
||||
|
||||
type ConfigurationHTTP struct {
|
||||
Host string `env:"HTTP_HOST,default=localhost"`
|
||||
Port string `env:"HTTP_PORT,default=8080"`
|
||||
Domen string `env:"HTTP_DOMEN,required"`
|
||||
}
|
||||
|
||||
type ConfigurationGRPC struct {
|
||||
Host string `env:"GRPC_HOST,default=0.0.0.0"`
|
||||
Port string `env:"GRPC_PORT,default=8081"`
|
||||
}
|
||||
|
||||
type ServiceConfiguration struct {
|
||||
YoomomeyConfiguration YoomomeyConfiguration
|
||||
}
|
||||
|
||||
type YoomomeyConfiguration struct {
|
||||
StoreID string `env:"YOOMONEY_STORE_ID,required"`
|
||||
SecretKey string `env:"YOOMONEY_SECRET_KEY,required"`
|
||||
}
|
7
internal/models/event.go
Normal file
7
internal/models/event.go
Normal file
@ -0,0 +1,7 @@
|
||||
package models
|
||||
|
||||
type Event struct {
|
||||
Key string
|
||||
Message string
|
||||
Payment *Payment
|
||||
}
|
101
internal/models/payment.go
Normal file
101
internal/models/payment.go
Normal file
@ -0,0 +1,101 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models/yandex"
|
||||
)
|
||||
|
||||
type Payment struct {
|
||||
ID string `json:"id" bson:"_id,omitempty"`
|
||||
UserID string `json:"userId" bson:"userId"`
|
||||
PaymentID string `json:"paymentId" bson:"paymentId"`
|
||||
IdempotencePaymentID string `json:"idempotencePaymentId" bson:"idempotencePaymentId"`
|
||||
ClientIP string `json:"clientIp" bson:"clientIp"`
|
||||
Currency string `json:"currency" bson:"currency"`
|
||||
Amount int64 `json:"amount" bson:"amount"`
|
||||
Type PaymentType `json:"type" bson:"type"`
|
||||
Status PaymentStatus `json:"status" bson:"status"`
|
||||
Completed bool `json:"completed" bson:"completed"`
|
||||
IsDeleted bool `json:"isDeleted" bson:"isDeleted"`
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"`
|
||||
DeletedAt *time.Time `json:"deletedAt,omitempty" bson:"deletedAt,omitempty"`
|
||||
RawPaymentBody any `json:"rawPaymentBody,omitempty" bson:"rawPaymentBody,omitempty"`
|
||||
|
||||
/*
|
||||
Список адресов в формате host:port, куда будет отправляться платёж при успешной операции
|
||||
|
||||
Запрос будет отправляться по протоколу GRPC
|
||||
*/
|
||||
CallbackHostGRPC []string `json:"callbackHostGrpc" bson:"callbackHostGrpc"`
|
||||
}
|
||||
|
||||
func (receiver *Payment) Sanitize() *Payment {
|
||||
now := time.Now()
|
||||
|
||||
receiver.ID = ""
|
||||
receiver.CreatedAt = now
|
||||
receiver.UpdatedAt = now
|
||||
receiver.DeletedAt = nil
|
||||
receiver.IsDeleted = false
|
||||
receiver.Completed = false
|
||||
|
||||
return receiver
|
||||
}
|
||||
|
||||
type CreatePaymentResult struct {
|
||||
RedirectURL string
|
||||
Payment *Payment
|
||||
}
|
||||
|
||||
type CreatePayment[T any] struct {
|
||||
Type PaymentType
|
||||
Currency string
|
||||
Amount int64
|
||||
CallbackHostGRPC []string
|
||||
ReturnURL string
|
||||
UserID string
|
||||
ClientIP string
|
||||
Requisites T
|
||||
}
|
||||
|
||||
type BankCard struct {
|
||||
Number string
|
||||
ExpiryYear string
|
||||
ExpiryMonth string
|
||||
CSC *string
|
||||
CardHolderName *string
|
||||
}
|
||||
|
||||
type PaymentType string
|
||||
|
||||
const (
|
||||
PaymentTypeBankCard PaymentType = "bankCard"
|
||||
PaymentTypeTinkoff PaymentType = "tinkoffBank"
|
||||
PaymentTypeQiwi PaymentType = "qiwi"
|
||||
PaymentTypeSberPay PaymentType = "sberbank"
|
||||
PaymentTypeYoomoney PaymentType = "yoomoney"
|
||||
PaymentTypeMobile PaymentType = "mobile"
|
||||
PaymentTypeInstallments PaymentType = "installments"
|
||||
PaymentTypeCash PaymentType = "cash"
|
||||
PaymentTypeSBP PaymentType = "sbp"
|
||||
PaymentTypeSberB2B PaymentType = "b2bSberbank"
|
||||
PaymentTypeAlfabank PaymentType = "alfabank"
|
||||
)
|
||||
|
||||
var (
|
||||
YandexPaymentTypeMap = map[PaymentType]yandex.PaymentType{
|
||||
PaymentTypeBankCard: yandex.PaymentTypeBankCard,
|
||||
PaymentTypeTinkoff: yandex.PaymentTypeTinkoff,
|
||||
PaymentTypeQiwi: yandex.PaymentTypeQiwi,
|
||||
PaymentTypeSberPay: yandex.PaymentTypeSberPay,
|
||||
PaymentTypeYoomoney: yandex.PaymentTypeYoomoney,
|
||||
PaymentTypeMobile: yandex.PaymentTypeMobile,
|
||||
PaymentTypeInstallments: yandex.PaymentTypeInstallments,
|
||||
PaymentTypeCash: yandex.PaymentTypeCash,
|
||||
PaymentTypeSBP: yandex.PaymentTypeSBP,
|
||||
PaymentTypeSberB2B: yandex.PaymentTypeSberB2B,
|
||||
PaymentTypeAlfabank: yandex.PaymentTypeAlfabank,
|
||||
}
|
||||
)
|
29
internal/models/status.go
Normal file
29
internal/models/status.go
Normal file
@ -0,0 +1,29 @@
|
||||
package models
|
||||
|
||||
import "penahub.gitlab.yandexcloud.net/external/treasurer/internal/models/yandex"
|
||||
|
||||
type PaymentStatus string
|
||||
|
||||
const (
|
||||
PaymentStatusPending PaymentStatus = "pending"
|
||||
PaymentStatusWaiting PaymentStatus = "waiting"
|
||||
PaymentStatusSuccessfully PaymentStatus = "success"
|
||||
PaymentStatusCanceled PaymentStatus = "canceled"
|
||||
PaymentStatusRefund PaymentStatus = "refund"
|
||||
)
|
||||
|
||||
var (
|
||||
YandexPaymentStatusMap = map[PaymentStatus]yandex.PaymentStatus{
|
||||
PaymentStatusPending: yandex.PaymentStatusPending,
|
||||
PaymentStatusWaiting: yandex.PaymentStatusWaiting,
|
||||
PaymentStatusSuccessfully: yandex.PaymentStatusSuccessfully,
|
||||
PaymentStatusCanceled: yandex.PaymentStatusCanceled,
|
||||
}
|
||||
|
||||
PaymentStatusMap = map[string]PaymentStatus{
|
||||
string(yandex.PaymentStatusPending): PaymentStatusPending,
|
||||
string(yandex.PaymentStatusWaiting): PaymentStatusWaiting,
|
||||
string(yandex.PaymentStatusSuccessfully): PaymentStatusSuccessfully,
|
||||
string(yandex.PaymentStatusCanceled): PaymentStatusCanceled,
|
||||
}
|
||||
)
|
14
internal/models/yandex/common.go
Normal file
14
internal/models/yandex/common.go
Normal file
@ -0,0 +1,14 @@
|
||||
package yandex
|
||||
|
||||
type Amount struct {
|
||||
Value string `json:"value" bson:"value"`
|
||||
Currency string `json:"currency" bson:"currency"`
|
||||
}
|
||||
|
||||
type BankCardInformation struct {
|
||||
Number string `json:"number"`
|
||||
ExpiryYear string `json:"expiry_year"`
|
||||
ExpiryMonth string `json:"expiry_month"`
|
||||
CSC string `json:"csc,omitempty"`
|
||||
CardHolderName string `json:"cardholder,omitempty"`
|
||||
}
|
44
internal/models/yandex/payment.go
Normal file
44
internal/models/yandex/payment.go
Normal file
@ -0,0 +1,44 @@
|
||||
package yandex
|
||||
|
||||
// Payment description https://yookassa.ru/developers/api#payment_object
|
||||
type Payment struct {
|
||||
ID string `json:"id" bson:"id"`
|
||||
Status PaymentStatus `json:"status" bson:"status"`
|
||||
Amount Amount `json:"amount" bson:"amount"`
|
||||
Confirmation *ConfirmationRedirect `json:"confirmation" bson:"confirmation"`
|
||||
IncomeAmount *Amount `json:"income_amount,omitempty" bson:"income_amount,omitempty"`
|
||||
Description string `json:"description,omitempty" bson:"description,omitempty"`
|
||||
PaymentMethod any `json:"payment_method,omitempty" bson:"payment_method,omitempty"`
|
||||
Recipient Recipient `json:"recipient" bson:"recipient"`
|
||||
CapturedAt string `json:"captured_at,omitempty" bson:"captured_at,omitempty"`
|
||||
ExpiresAt string `json:"expires_at,omitempty" bson:"expires_at,omitempty"`
|
||||
CreatedAt string `json:"created_at" bson:"created_at"`
|
||||
IsTest bool `json:"test" bson:"test"`
|
||||
RefundedAmount *Amount `json:"refunded_amount,omitempty" bson:"refunded_amount,omitempty"`
|
||||
IsPaid bool `json:"paid" bson:"paid"`
|
||||
IsRefundable bool `json:"refundable" bson:"refundable"`
|
||||
ReceiptRegistration string `json:"receipt_registration,omitempty" bson:"receipt_registration,omitempty"`
|
||||
Metadata any `json:"metadata,omitempty" bson:"metadata,omitempty"`
|
||||
CancellationDetails any `json:"cancellation_details,omitempty" bson:"cancellation_details,omitempty"`
|
||||
AuthorizationDetails any `json:"authorization_details,omitempty" bson:"authorization_details,omitempty"`
|
||||
Transfers []any `json:"transfers,omitempty" bson:"transfers,omitempty"`
|
||||
Deal any `json:"deal,omitempty" bson:"deal,omitempty"`
|
||||
MerchantCustomerID string `json:"merchant_customer_id,omitempty" bson:"merchant_customer_id,omitempty"`
|
||||
}
|
||||
|
||||
type Recipient struct {
|
||||
AccountID string `json:"account_id" bson:"account_id"`
|
||||
GatewayID string `json:"gateway_id" bson:"gateway_id"`
|
||||
}
|
||||
|
||||
type Confirmation struct {
|
||||
}
|
||||
|
||||
type PaymentStatus string
|
||||
|
||||
const (
|
||||
PaymentStatusPending PaymentStatus = "pending"
|
||||
PaymentStatusWaiting PaymentStatus = "waiting_for_capture"
|
||||
PaymentStatusSuccessfully PaymentStatus = "succeeded"
|
||||
PaymentStatusCanceled PaymentStatus = "canceled"
|
||||
)
|
55
internal/models/yandex/payment_confirmation.go
Normal file
55
internal/models/yandex/payment_confirmation.go
Normal file
@ -0,0 +1,55 @@
|
||||
package yandex
|
||||
|
||||
type ConfirmationType string
|
||||
|
||||
const (
|
||||
ConfirmationTypeEmbedded ConfirmationType = "embedded"
|
||||
ConfirmationTypeExternal ConfirmationType = "external"
|
||||
ConfirmationTypeMobile ConfirmationType = "mobile_application"
|
||||
ConfirmationTypeQR ConfirmationType = "qr"
|
||||
ConfirmationTypeRedirect ConfirmationType = "redirect"
|
||||
)
|
||||
|
||||
type ConfirmationEmbedded struct {
|
||||
Type ConfirmationType `json:"type"`
|
||||
ConfirmationToken string `json:"confirmation_token"`
|
||||
}
|
||||
|
||||
type ConfirmationExternal struct {
|
||||
Type ConfirmationType `json:"type"`
|
||||
}
|
||||
|
||||
type ConfirmationMobile struct {
|
||||
Type ConfirmationType `json:"type"`
|
||||
ConfirmationURL string `json:"confirmation_url"`
|
||||
}
|
||||
|
||||
type ConfirmationQR struct {
|
||||
Type ConfirmationType `json:"type"`
|
||||
ConfirmationData string `json:"confirmation_data"`
|
||||
}
|
||||
|
||||
type ConfirmationRedirect struct {
|
||||
Type ConfirmationType `json:"type"`
|
||||
ConfirmationURL string `json:"confirmation_url"`
|
||||
ReturnURL *string `json:"return_url,omitempty"`
|
||||
Enforce *bool `json:"enforce,omitempty"`
|
||||
}
|
||||
|
||||
type CreateConfirmationLocale struct {
|
||||
Type ConfirmationType `json:"type"`
|
||||
Locale string `json:"locale,omitempty"`
|
||||
}
|
||||
|
||||
type CreateConfirmationMobile struct {
|
||||
Type ConfirmationType `json:"type"`
|
||||
Locale string `json:"locale,omitempty"`
|
||||
ReturnURL string `json:"return_url"`
|
||||
}
|
||||
|
||||
type CreateConfirmationRedirect struct {
|
||||
Type ConfirmationType `json:"type"`
|
||||
Locale string `json:"locale,omitempty"`
|
||||
ReturnURL string `json:"return_url"`
|
||||
Enforce bool `json:"enforce,omitempty"`
|
||||
}
|
19
internal/models/yandex/payment_create.go
Normal file
19
internal/models/yandex/payment_create.go
Normal file
@ -0,0 +1,19 @@
|
||||
package yandex
|
||||
|
||||
// CreatePaymentRequest description https://yookassa.ru/developers/api#create_payment
|
||||
type CreatePaymentRequest[T any] struct {
|
||||
Amount Amount `json:"amount"`
|
||||
Description string `json:"description,omitempty"`
|
||||
PaymentMethodID *string `json:"payment_method_id,omitempty"`
|
||||
PaymentMethodData *T `json:"payment_method_data,omitempty"`
|
||||
Confirmation *CreateConfirmationRedirect `json:"confirmation,omitempty"`
|
||||
SavePaymentMethod bool `json:"save_payment_method,omitempty"`
|
||||
Capture bool `json:"capture,omitempty"`
|
||||
ClientIP string `json:"client_ip,omitempty"`
|
||||
Metadata any `json:"metadata,omitempty"`
|
||||
Airline any `json:"airline,omitempty"`
|
||||
Transfers []any `json:"transfers,omitempty"`
|
||||
Deal any `json:"deal,omitempty"`
|
||||
FraudData any `json:"fraud_data,omitempty"`
|
||||
MerchantCustomerID any `json:"merchant_customer_id,omitempty"`
|
||||
}
|
42
internal/models/yandex/payment_method.go
Normal file
42
internal/models/yandex/payment_method.go
Normal file
@ -0,0 +1,42 @@
|
||||
package yandex
|
||||
|
||||
type PaymentType string
|
||||
|
||||
const (
|
||||
PaymentTypeBankCard PaymentType = "bank_card"
|
||||
PaymentTypeTinkoff PaymentType = "tinkoff_bank"
|
||||
PaymentTypeQiwi PaymentType = "qiwi"
|
||||
PaymentTypeSberPay PaymentType = "sberbank"
|
||||
PaymentTypeYoomoney PaymentType = "yoo_money"
|
||||
PaymentTypeMobile PaymentType = "mobile_balance"
|
||||
PaymentTypeInstallments PaymentType = "installments"
|
||||
PaymentTypeCash PaymentType = "cash"
|
||||
PaymentTypeSBP PaymentType = "sbp"
|
||||
PaymentTypeSberB2B PaymentType = "b2b_sberbank"
|
||||
PaymentTypeAlfabank PaymentType = "alfabank"
|
||||
)
|
||||
|
||||
type PaymentMethodBankCard struct {
|
||||
Type PaymentType `json:"type"`
|
||||
Card *BankCardInformation `json:"card,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentMethodLogin struct {
|
||||
Type PaymentType `json:"type"`
|
||||
Login string `json:"login,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentMethodB2B struct {
|
||||
Type PaymentType `json:"type"`
|
||||
PaymentPurpose string `json:"payment_purpose"`
|
||||
VatData any `json:"vat_data"`
|
||||
}
|
||||
|
||||
type PaymentMethodPhone struct {
|
||||
Type PaymentType `json:"type"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentMethodType struct {
|
||||
Type PaymentType `json:"type"`
|
||||
}
|
54
internal/models/yandex/webhook.go
Normal file
54
internal/models/yandex/webhook.go
Normal file
@ -0,0 +1,54 @@
|
||||
package yandex
|
||||
|
||||
type WebhookEventType string
|
||||
|
||||
const (
|
||||
/* Платеж перешел в статус ожидания. */
|
||||
WebhookEventPaymentWaiting WebhookEventType = "payment.waiting_for_capture"
|
||||
|
||||
/* Платеж перешел в статус "Успешно". */
|
||||
WebhookEventPaymentSucceeded WebhookEventType = "payment.succeeded"
|
||||
|
||||
/* Платеж перешел в статус "Отменён". */
|
||||
WebhookEventPaymentCanceled WebhookEventType = "payment.canceled"
|
||||
)
|
||||
|
||||
const (
|
||||
/* Возврат перешел в статус "Успешно". */
|
||||
WebhookEventRefundSucceeded WebhookEventType = "refund.succeeded"
|
||||
)
|
||||
|
||||
const (
|
||||
/* Сделка перешла в статус "Закрыта". */
|
||||
WebhookEventDealClosed WebhookEventType = "deal.closed"
|
||||
)
|
||||
|
||||
const (
|
||||
/* Выплата перешла в статус "Отменено". */
|
||||
WebhookEventPayoutCanceled WebhookEventType = "payout.canceled"
|
||||
|
||||
/* Выплата перешла в статус "Успешно". */
|
||||
WebhookEventPayoutSucceeded WebhookEventType = "payout.succeeded"
|
||||
)
|
||||
|
||||
type CreateWebhookRequest struct {
|
||||
Event WebhookEventType `json:"event"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type GetWebhooksResponse struct {
|
||||
Type string `json:"type"`
|
||||
Webhooks []Webhook `json:"items"`
|
||||
}
|
||||
|
||||
type Webhook struct {
|
||||
ID string `json:"id"`
|
||||
Event WebhookEventType `json:"event"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type WebhookNotification[T any] struct {
|
||||
Type string `json:"type"`
|
||||
Event WebhookEventType `json:"event"`
|
||||
Object T `json:"object"`
|
||||
}
|
325
internal/proto/payment_callback/service.pb.go
Normal file
325
internal/proto/payment_callback/service.pb.go
Normal file
@ -0,0 +1,325 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc (unknown)
|
||||
// source: callback/service.proto
|
||||
|
||||
package payment_callback
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
_ "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Key string `protobuf:"bytes,1,opt,name=Key,proto3" json:"Key,omitempty"`
|
||||
Message string `protobuf:"bytes,2,opt,name=Message,proto3" json:"Message,omitempty"`
|
||||
Payment *Payment `protobuf:"bytes,3,opt,name=Payment,proto3" json:"Payment,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Event) Reset() {
|
||||
*x = Event{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_callback_service_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Event) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Event) ProtoMessage() {}
|
||||
|
||||
func (x *Event) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_callback_service_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Event.ProtoReflect.Descriptor instead.
|
||||
func (*Event) Descriptor() ([]byte, []int) {
|
||||
return file_callback_service_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Event) GetKey() string {
|
||||
if x != nil {
|
||||
return x.Key
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Event) GetMessage() string {
|
||||
if x != nil {
|
||||
return x.Message
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Event) GetPayment() *Payment {
|
||||
if x != nil {
|
||||
return x.Payment
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Payment struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
UserID string `protobuf:"bytes,2,opt,name=UserID,proto3" json:"UserID,omitempty"`
|
||||
PaymentID string `protobuf:"bytes,3,opt,name=PaymentID,proto3" json:"PaymentID,omitempty"`
|
||||
IdempotencePaymentID string `protobuf:"bytes,4,opt,name=IdempotencePaymentID,proto3" json:"IdempotencePaymentID,omitempty"`
|
||||
Amount int64 `protobuf:"varint,5,opt,name=Amount,proto3" json:"Amount,omitempty"`
|
||||
Currency string `protobuf:"bytes,6,opt,name=Currency,proto3" json:"Currency,omitempty"`
|
||||
Type string `protobuf:"bytes,7,opt,name=Type,proto3" json:"Type,omitempty"`
|
||||
Status string `protobuf:"bytes,8,opt,name=Status,proto3" json:"Status,omitempty"`
|
||||
Completed bool `protobuf:"varint,9,opt,name=Completed,proto3" json:"Completed,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Payment) Reset() {
|
||||
*x = Payment{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_callback_service_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Payment) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Payment) ProtoMessage() {}
|
||||
|
||||
func (x *Payment) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_callback_service_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Payment.ProtoReflect.Descriptor instead.
|
||||
func (*Payment) Descriptor() ([]byte, []int) {
|
||||
return file_callback_service_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Payment) GetID() string {
|
||||
if x != nil {
|
||||
return x.ID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetUserID() string {
|
||||
if x != nil {
|
||||
return x.UserID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetPaymentID() string {
|
||||
if x != nil {
|
||||
return x.PaymentID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetIdempotencePaymentID() string {
|
||||
if x != nil {
|
||||
return x.IdempotencePaymentID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetAmount() int64 {
|
||||
if x != nil {
|
||||
return x.Amount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Payment) GetCurrency() string {
|
||||
if x != nil {
|
||||
return x.Currency
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetStatus() string {
|
||||
if x != nil {
|
||||
return x.Status
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetCompleted() bool {
|
||||
if x != nil {
|
||||
return x.Completed
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_callback_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_callback_service_proto_rawDesc = []byte{
|
||||
0x0a, 0x16, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
|
||||
0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x68, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e,
|
||||
0x74, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
|
||||
0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x33, 0x0a,
|
||||
0x07, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
|
||||
0x2e, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
|
||||
0x6b, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x22, 0x81, 0x02, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e,
|
||||
0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x49, 0x44, 0x12, 0x32, 0x0a, 0x14, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65,
|
||||
0x6e, 0x63, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x14, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x50,
|
||||
0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x43, 0x6f, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x32, 0x98, 0x01, 0x0a, 0x16, 0x50, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x12, 0x3e, 0x0a, 0x09, 0x4f, 0x6e, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x17,
|
||||
0x2e, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
|
||||
0x6b, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
|
||||
0x00, 0x12, 0x3e, 0x0a, 0x09, 0x4f, 0x6e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x17,
|
||||
0x2e, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
|
||||
0x6b, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
|
||||
0x00, 0x42, 0x14, 0x5a, 0x12, 0x2e, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63,
|
||||
0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_callback_service_proto_rawDescOnce sync.Once
|
||||
file_callback_service_proto_rawDescData = file_callback_service_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_callback_service_proto_rawDescGZIP() []byte {
|
||||
file_callback_service_proto_rawDescOnce.Do(func() {
|
||||
file_callback_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_callback_service_proto_rawDescData)
|
||||
})
|
||||
return file_callback_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_callback_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_callback_service_proto_goTypes = []interface{}{
|
||||
(*Event)(nil), // 0: payment_callback.Event
|
||||
(*Payment)(nil), // 1: payment_callback.Payment
|
||||
(*emptypb.Empty)(nil), // 2: google.protobuf.Empty
|
||||
}
|
||||
var file_callback_service_proto_depIdxs = []int32{
|
||||
1, // 0: payment_callback.Event.Payment:type_name -> payment_callback.Payment
|
||||
0, // 1: payment_callback.PaymentCallbackService.OnSuccess:input_type -> payment_callback.Event
|
||||
0, // 2: payment_callback.PaymentCallbackService.OnFailure:input_type -> payment_callback.Event
|
||||
2, // 3: payment_callback.PaymentCallbackService.OnSuccess:output_type -> google.protobuf.Empty
|
||||
2, // 4: payment_callback.PaymentCallbackService.OnFailure:output_type -> google.protobuf.Empty
|
||||
3, // [3:5] is the sub-list for method output_type
|
||||
1, // [1:3] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_callback_service_proto_init() }
|
||||
func file_callback_service_proto_init() {
|
||||
if File_callback_service_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_callback_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Event); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_callback_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Payment); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_callback_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_callback_service_proto_goTypes,
|
||||
DependencyIndexes: file_callback_service_proto_depIdxs,
|
||||
MessageInfos: file_callback_service_proto_msgTypes,
|
||||
}.Build()
|
||||
File_callback_service_proto = out.File
|
||||
file_callback_service_proto_rawDesc = nil
|
||||
file_callback_service_proto_goTypes = nil
|
||||
file_callback_service_proto_depIdxs = nil
|
||||
}
|
136
internal/proto/payment_callback/service_grpc.pb.go
Normal file
136
internal/proto/payment_callback/service_grpc.pb.go
Normal file
@ -0,0 +1,136 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
|
||||
package payment_callback
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
// PaymentCallbackServiceClient is the client API for PaymentCallbackService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type PaymentCallbackServiceClient interface {
|
||||
OnSuccess(ctx context.Context, in *Event, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
OnFailure(ctx context.Context, in *Event, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
}
|
||||
|
||||
type paymentCallbackServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewPaymentCallbackServiceClient(cc grpc.ClientConnInterface) PaymentCallbackServiceClient {
|
||||
return &paymentCallbackServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *paymentCallbackServiceClient) OnSuccess(ctx context.Context, in *Event, opts ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||
out := new(emptypb.Empty)
|
||||
err := c.cc.Invoke(ctx, "/payment_callback.PaymentCallbackService/OnSuccess", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *paymentCallbackServiceClient) OnFailure(ctx context.Context, in *Event, opts ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||
out := new(emptypb.Empty)
|
||||
err := c.cc.Invoke(ctx, "/payment_callback.PaymentCallbackService/OnFailure", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// PaymentCallbackServiceServer is the server API for PaymentCallbackService service.
|
||||
// All implementations should embed UnimplementedPaymentCallbackServiceServer
|
||||
// for forward compatibility
|
||||
type PaymentCallbackServiceServer interface {
|
||||
OnSuccess(context.Context, *Event) (*emptypb.Empty, error)
|
||||
OnFailure(context.Context, *Event) (*emptypb.Empty, error)
|
||||
}
|
||||
|
||||
// UnimplementedPaymentCallbackServiceServer should be embedded to have forward compatible implementations.
|
||||
type UnimplementedPaymentCallbackServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedPaymentCallbackServiceServer) OnSuccess(context.Context, *Event) (*emptypb.Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method OnSuccess not implemented")
|
||||
}
|
||||
func (UnimplementedPaymentCallbackServiceServer) OnFailure(context.Context, *Event) (*emptypb.Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method OnFailure not implemented")
|
||||
}
|
||||
|
||||
// UnsafePaymentCallbackServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to PaymentCallbackServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafePaymentCallbackServiceServer interface {
|
||||
mustEmbedUnimplementedPaymentCallbackServiceServer()
|
||||
}
|
||||
|
||||
func RegisterPaymentCallbackServiceServer(s grpc.ServiceRegistrar, srv PaymentCallbackServiceServer) {
|
||||
s.RegisterService(&PaymentCallbackService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _PaymentCallbackService_OnSuccess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Event)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PaymentCallbackServiceServer).OnSuccess(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/payment_callback.PaymentCallbackService/OnSuccess",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PaymentCallbackServiceServer).OnSuccess(ctx, req.(*Event))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _PaymentCallbackService_OnFailure_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Event)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PaymentCallbackServiceServer).OnFailure(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/payment_callback.PaymentCallbackService/OnFailure",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PaymentCallbackServiceServer).OnFailure(ctx, req.(*Event))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// PaymentCallbackService_ServiceDesc is the grpc.ServiceDesc for PaymentCallbackService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var PaymentCallbackService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "payment_callback.PaymentCallbackService",
|
||||
HandlerType: (*PaymentCallbackServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "OnSuccess",
|
||||
Handler: _PaymentCallbackService_OnSuccess_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "OnFailure",
|
||||
Handler: _PaymentCallbackService_OnFailure_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "callback/service.proto",
|
||||
}
|
531
internal/proto/treasurer/payment.model.pb.go
Normal file
531
internal/proto/treasurer/payment.model.pb.go
Normal file
@ -0,0 +1,531 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc (unknown)
|
||||
// source: treasurer/payment.model.proto
|
||||
|
||||
package treasurer
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type MainPaymentSettings struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Currency string `protobuf:"bytes,1,opt,name=Currency,proto3" json:"Currency,omitempty"`
|
||||
Amount int64 `protobuf:"varint,2,opt,name=Amount,proto3" json:"Amount,omitempty"`
|
||||
CallbackHostGRPC []string `protobuf:"bytes,3,rep,name=CallbackHostGRPC,proto3" json:"CallbackHostGRPC,omitempty"`
|
||||
ReturnURL string `protobuf:"bytes,4,opt,name=ReturnURL,proto3" json:"ReturnURL,omitempty"`
|
||||
UserID string `protobuf:"bytes,5,opt,name=UserID,proto3" json:"UserID,omitempty"`
|
||||
ClientIP string `protobuf:"bytes,6,opt,name=ClientIP,proto3" json:"ClientIP,omitempty"`
|
||||
}
|
||||
|
||||
func (x *MainPaymentSettings) Reset() {
|
||||
*x = MainPaymentSettings{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_treasurer_payment_model_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MainPaymentSettings) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MainPaymentSettings) ProtoMessage() {}
|
||||
|
||||
func (x *MainPaymentSettings) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_treasurer_payment_model_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use MainPaymentSettings.ProtoReflect.Descriptor instead.
|
||||
func (*MainPaymentSettings) Descriptor() ([]byte, []int) {
|
||||
return file_treasurer_payment_model_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *MainPaymentSettings) GetCurrency() string {
|
||||
if x != nil {
|
||||
return x.Currency
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *MainPaymentSettings) GetAmount() int64 {
|
||||
if x != nil {
|
||||
return x.Amount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *MainPaymentSettings) GetCallbackHostGRPC() []string {
|
||||
if x != nil {
|
||||
return x.CallbackHostGRPC
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *MainPaymentSettings) GetReturnURL() string {
|
||||
if x != nil {
|
||||
return x.ReturnURL
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *MainPaymentSettings) GetUserID() string {
|
||||
if x != nil {
|
||||
return x.UserID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *MainPaymentSettings) GetClientIP() string {
|
||||
if x != nil {
|
||||
return x.ClientIP
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type BankCardInformation struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Number string `protobuf:"bytes,1,opt,name=Number,proto3" json:"Number,omitempty"`
|
||||
ExpiryYear string `protobuf:"bytes,2,opt,name=ExpiryYear,proto3" json:"ExpiryYear,omitempty"`
|
||||
ExpiryMonth string `protobuf:"bytes,3,opt,name=ExpiryMonth,proto3" json:"ExpiryMonth,omitempty"`
|
||||
CSC *string `protobuf:"bytes,4,opt,name=CSC,proto3,oneof" json:"CSC,omitempty"`
|
||||
CardHolderName *string `protobuf:"bytes,5,opt,name=CardHolderName,proto3,oneof" json:"CardHolderName,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BankCardInformation) Reset() {
|
||||
*x = BankCardInformation{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_treasurer_payment_model_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BankCardInformation) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BankCardInformation) ProtoMessage() {}
|
||||
|
||||
func (x *BankCardInformation) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_treasurer_payment_model_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use BankCardInformation.ProtoReflect.Descriptor instead.
|
||||
func (*BankCardInformation) Descriptor() ([]byte, []int) {
|
||||
return file_treasurer_payment_model_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *BankCardInformation) GetNumber() string {
|
||||
if x != nil {
|
||||
return x.Number
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *BankCardInformation) GetExpiryYear() string {
|
||||
if x != nil {
|
||||
return x.ExpiryYear
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *BankCardInformation) GetExpiryMonth() string {
|
||||
if x != nil {
|
||||
return x.ExpiryMonth
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *BankCardInformation) GetCSC() string {
|
||||
if x != nil && x.CSC != nil {
|
||||
return *x.CSC
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *BankCardInformation) GetCardHolderName() string {
|
||||
if x != nil && x.CardHolderName != nil {
|
||||
return *x.CardHolderName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Payment struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
UserID string `protobuf:"bytes,2,opt,name=UserID,proto3" json:"UserID,omitempty"`
|
||||
PaymentID string `protobuf:"bytes,3,opt,name=PaymentID,proto3" json:"PaymentID,omitempty"`
|
||||
IdempotencePaymentID string `protobuf:"bytes,4,opt,name=IdempotencePaymentID,proto3" json:"IdempotencePaymentID,omitempty"`
|
||||
ClientIP string `protobuf:"bytes,5,opt,name=ClientIP,proto3" json:"ClientIP,omitempty"`
|
||||
Currency string `protobuf:"bytes,6,opt,name=Currency,proto3" json:"Currency,omitempty"`
|
||||
Amount int64 `protobuf:"varint,7,opt,name=Amount,proto3" json:"Amount,omitempty"`
|
||||
Type string `protobuf:"bytes,8,opt,name=Type,proto3" json:"Type,omitempty"`
|
||||
Status string `protobuf:"bytes,9,opt,name=Status,proto3" json:"Status,omitempty"`
|
||||
RawPaymentBody *anypb.Any `protobuf:"bytes,10,opt,name=RawPaymentBody,proto3" json:"RawPaymentBody,omitempty"`
|
||||
CallbackHostGRPC []string `protobuf:"bytes,11,rep,name=CallbackHostGRPC,proto3" json:"CallbackHostGRPC,omitempty"`
|
||||
Completed bool `protobuf:"varint,12,opt,name=Completed,proto3" json:"Completed,omitempty"`
|
||||
IsDeleted bool `protobuf:"varint,13,opt,name=IsDeleted,proto3" json:"IsDeleted,omitempty"`
|
||||
UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,14,opt,name=UpdatedAt,proto3" json:"UpdatedAt,omitempty"`
|
||||
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,15,opt,name=CreatedAt,proto3" json:"CreatedAt,omitempty"`
|
||||
DeletedAt *timestamppb.Timestamp `protobuf:"bytes,16,opt,name=DeletedAt,proto3,oneof" json:"DeletedAt,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Payment) Reset() {
|
||||
*x = Payment{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_treasurer_payment_model_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Payment) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Payment) ProtoMessage() {}
|
||||
|
||||
func (x *Payment) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_treasurer_payment_model_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Payment.ProtoReflect.Descriptor instead.
|
||||
func (*Payment) Descriptor() ([]byte, []int) {
|
||||
return file_treasurer_payment_model_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *Payment) GetID() string {
|
||||
if x != nil {
|
||||
return x.ID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetUserID() string {
|
||||
if x != nil {
|
||||
return x.UserID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetPaymentID() string {
|
||||
if x != nil {
|
||||
return x.PaymentID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetIdempotencePaymentID() string {
|
||||
if x != nil {
|
||||
return x.IdempotencePaymentID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetClientIP() string {
|
||||
if x != nil {
|
||||
return x.ClientIP
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetCurrency() string {
|
||||
if x != nil {
|
||||
return x.Currency
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetAmount() int64 {
|
||||
if x != nil {
|
||||
return x.Amount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Payment) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetStatus() string {
|
||||
if x != nil {
|
||||
return x.Status
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Payment) GetRawPaymentBody() *anypb.Any {
|
||||
if x != nil {
|
||||
return x.RawPaymentBody
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Payment) GetCallbackHostGRPC() []string {
|
||||
if x != nil {
|
||||
return x.CallbackHostGRPC
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Payment) GetCompleted() bool {
|
||||
if x != nil {
|
||||
return x.Completed
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Payment) GetIsDeleted() bool {
|
||||
if x != nil {
|
||||
return x.IsDeleted
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Payment) GetUpdatedAt() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.UpdatedAt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Payment) GetCreatedAt() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.CreatedAt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Payment) GetDeletedAt() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.DeletedAt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_treasurer_payment_model_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_treasurer_payment_model_proto_rawDesc = []byte{
|
||||
0x0a, 0x1d, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2f, 0x70, 0x61, 0x79, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
|
||||
0x09, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc7, 0x01, 0x0a, 0x13, 0x4d, 0x61, 0x69, 0x6e, 0x50,
|
||||
0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a,
|
||||
0x0a, 0x08, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x08, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x48, 0x6f,
|
||||
0x73, 0x74, 0x47, 0x52, 0x50, 0x43, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x43, 0x61,
|
||||
0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x48, 0x6f, 0x73, 0x74, 0x47, 0x52, 0x50, 0x43, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x55, 0x52, 0x4c, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x55, 0x52, 0x4c, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x55, 0x73,
|
||||
0x65, 0x72, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50,
|
||||
0x22, 0xce, 0x01, 0x0a, 0x13, 0x42, 0x61, 0x6e, 0x6b, 0x43, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x4e, 0x75, 0x6d, 0x62,
|
||||
0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72,
|
||||
0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x59, 0x65, 0x61, 0x72, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x59, 0x65, 0x61, 0x72,
|
||||
0x12, 0x20, 0x0a, 0x0b, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x4d, 0x6f, 0x6e,
|
||||
0x74, 0x68, 0x12, 0x15, 0x0a, 0x03, 0x43, 0x53, 0x43, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48,
|
||||
0x00, 0x52, 0x03, 0x43, 0x53, 0x43, 0x88, 0x01, 0x01, 0x12, 0x2b, 0x0a, 0x0e, 0x43, 0x61, 0x72,
|
||||
0x64, 0x48, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x09, 0x48, 0x01, 0x52, 0x0e, 0x43, 0x61, 0x72, 0x64, 0x48, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x4e,
|
||||
0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x43, 0x53, 0x43, 0x42, 0x11,
|
||||
0x0a, 0x0f, 0x5f, 0x43, 0x61, 0x72, 0x64, 0x48, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d,
|
||||
0x65, 0x22, 0xe6, 0x04, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a,
|
||||
0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x55,
|
||||
0x73, 0x65, 0x72, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x49, 0x44, 0x12, 0x32, 0x0a, 0x14, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e,
|
||||
0x63, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x14, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e,
|
||||
0x74, 0x49, 0x50, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e,
|
||||
0x74, 0x49, 0x50, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x12, 0x3c, 0x0a, 0x0e, 0x52, 0x61, 0x77, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x42, 0x6f, 0x64, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e,
|
||||
0x79, 0x52, 0x0e, 0x52, 0x61, 0x77, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x6f, 0x64,
|
||||
0x79, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x48, 0x6f, 0x73,
|
||||
0x74, 0x47, 0x52, 0x50, 0x43, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x43, 0x61, 0x6c,
|
||||
0x6c, 0x62, 0x61, 0x63, 0x6b, 0x48, 0x6f, 0x73, 0x74, 0x47, 0x52, 0x50, 0x43, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x49,
|
||||
0x73, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09,
|
||||
0x49, 0x73, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
|
||||
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x64, 0x41, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
|
||||
0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
|
||||
0x6d, 0x70, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3d, 0x0a,
|
||||
0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x09,
|
||||
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a,
|
||||
0x5f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, 0x0d, 0x5a, 0x0b, 0x2e, 0x2f,
|
||||
0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_treasurer_payment_model_proto_rawDescOnce sync.Once
|
||||
file_treasurer_payment_model_proto_rawDescData = file_treasurer_payment_model_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_treasurer_payment_model_proto_rawDescGZIP() []byte {
|
||||
file_treasurer_payment_model_proto_rawDescOnce.Do(func() {
|
||||
file_treasurer_payment_model_proto_rawDescData = protoimpl.X.CompressGZIP(file_treasurer_payment_model_proto_rawDescData)
|
||||
})
|
||||
return file_treasurer_payment_model_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_treasurer_payment_model_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_treasurer_payment_model_proto_goTypes = []interface{}{
|
||||
(*MainPaymentSettings)(nil), // 0: treasurer.MainPaymentSettings
|
||||
(*BankCardInformation)(nil), // 1: treasurer.BankCardInformation
|
||||
(*Payment)(nil), // 2: treasurer.Payment
|
||||
(*anypb.Any)(nil), // 3: google.protobuf.Any
|
||||
(*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp
|
||||
}
|
||||
var file_treasurer_payment_model_proto_depIdxs = []int32{
|
||||
3, // 0: treasurer.Payment.RawPaymentBody:type_name -> google.protobuf.Any
|
||||
4, // 1: treasurer.Payment.UpdatedAt:type_name -> google.protobuf.Timestamp
|
||||
4, // 2: treasurer.Payment.CreatedAt:type_name -> google.protobuf.Timestamp
|
||||
4, // 3: treasurer.Payment.DeletedAt:type_name -> google.protobuf.Timestamp
|
||||
4, // [4:4] is the sub-list for method output_type
|
||||
4, // [4:4] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_treasurer_payment_model_proto_init() }
|
||||
func file_treasurer_payment_model_proto_init() {
|
||||
if File_treasurer_payment_model_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_treasurer_payment_model_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MainPaymentSettings); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_treasurer_payment_model_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BankCardInformation); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_treasurer_payment_model_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Payment); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_treasurer_payment_model_proto_msgTypes[1].OneofWrappers = []interface{}{}
|
||||
file_treasurer_payment_model_proto_msgTypes[2].OneofWrappers = []interface{}{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_treasurer_payment_model_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_treasurer_payment_model_proto_goTypes,
|
||||
DependencyIndexes: file_treasurer_payment_model_proto_depIdxs,
|
||||
MessageInfos: file_treasurer_payment_model_proto_msgTypes,
|
||||
}.Build()
|
||||
File_treasurer_payment_model_proto = out.File
|
||||
file_treasurer_payment_model_proto_rawDesc = nil
|
||||
file_treasurer_payment_model_proto_goTypes = nil
|
||||
file_treasurer_payment_model_proto_depIdxs = nil
|
||||
}
|
634
internal/proto/treasurer/service.pb.go
Normal file
634
internal/proto/treasurer/service.pb.go
Normal file
@ -0,0 +1,634 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc (unknown)
|
||||
// source: treasurer/service.proto
|
||||
|
||||
package treasurer
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type GetBankCardPaymentLinkRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
MainSettings *MainPaymentSettings `protobuf:"bytes,1,opt,name=MainSettings,proto3" json:"MainSettings,omitempty"`
|
||||
BankCard *BankCardInformation `protobuf:"bytes,2,opt,name=BankCard,proto3" json:"BankCard,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetBankCardPaymentLinkRequest) Reset() {
|
||||
*x = GetBankCardPaymentLinkRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_treasurer_service_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetBankCardPaymentLinkRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetBankCardPaymentLinkRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetBankCardPaymentLinkRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_treasurer_service_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetBankCardPaymentLinkRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetBankCardPaymentLinkRequest) Descriptor() ([]byte, []int) {
|
||||
return file_treasurer_service_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *GetBankCardPaymentLinkRequest) GetMainSettings() *MainPaymentSettings {
|
||||
if x != nil {
|
||||
return x.MainSettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetBankCardPaymentLinkRequest) GetBankCard() *BankCardInformation {
|
||||
if x != nil {
|
||||
return x.BankCard
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetPaymentLinkRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
MainSettings *MainPaymentSettings `protobuf:"bytes,1,opt,name=MainSettings,proto3" json:"MainSettings,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetPaymentLinkRequest) Reset() {
|
||||
*x = GetPaymentLinkRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_treasurer_service_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetPaymentLinkRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetPaymentLinkRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetPaymentLinkRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_treasurer_service_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetPaymentLinkRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetPaymentLinkRequest) Descriptor() ([]byte, []int) {
|
||||
return file_treasurer_service_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *GetPaymentLinkRequest) GetMainSettings() *MainPaymentSettings {
|
||||
if x != nil {
|
||||
return x.MainSettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetPhonePaymentLinkRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
MainSettings *MainPaymentSettings `protobuf:"bytes,1,opt,name=MainSettings,proto3" json:"MainSettings,omitempty"`
|
||||
Phone string `protobuf:"bytes,2,opt,name=Phone,proto3" json:"Phone,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetPhonePaymentLinkRequest) Reset() {
|
||||
*x = GetPhonePaymentLinkRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_treasurer_service_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetPhonePaymentLinkRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetPhonePaymentLinkRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetPhonePaymentLinkRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_treasurer_service_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetPhonePaymentLinkRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetPhonePaymentLinkRequest) Descriptor() ([]byte, []int) {
|
||||
return file_treasurer_service_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *GetPhonePaymentLinkRequest) GetMainSettings() *MainPaymentSettings {
|
||||
if x != nil {
|
||||
return x.MainSettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetPhonePaymentLinkRequest) GetPhone() string {
|
||||
if x != nil {
|
||||
return x.Phone
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetLoginPaymentLinkRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
MainSettings *MainPaymentSettings `protobuf:"bytes,1,opt,name=MainSettings,proto3" json:"MainSettings,omitempty"`
|
||||
Login string `protobuf:"bytes,2,opt,name=Login,proto3" json:"Login,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetLoginPaymentLinkRequest) Reset() {
|
||||
*x = GetLoginPaymentLinkRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_treasurer_service_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetLoginPaymentLinkRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetLoginPaymentLinkRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetLoginPaymentLinkRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_treasurer_service_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetLoginPaymentLinkRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetLoginPaymentLinkRequest) Descriptor() ([]byte, []int) {
|
||||
return file_treasurer_service_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *GetLoginPaymentLinkRequest) GetMainSettings() *MainPaymentSettings {
|
||||
if x != nil {
|
||||
return x.MainSettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetLoginPaymentLinkRequest) GetLogin() string {
|
||||
if x != nil {
|
||||
return x.Login
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetB2BPaymentLinkRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
MainSettings *MainPaymentSettings `protobuf:"bytes,1,opt,name=MainSettings,proto3" json:"MainSettings,omitempty"`
|
||||
PaymentPurpose string `protobuf:"bytes,2,opt,name=PaymentPurpose,proto3" json:"PaymentPurpose,omitempty"`
|
||||
VatData *emptypb.Empty `protobuf:"bytes,3,opt,name=VatData,proto3" json:"VatData,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetB2BPaymentLinkRequest) Reset() {
|
||||
*x = GetB2BPaymentLinkRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_treasurer_service_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetB2BPaymentLinkRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetB2BPaymentLinkRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetB2BPaymentLinkRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_treasurer_service_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetB2BPaymentLinkRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetB2BPaymentLinkRequest) Descriptor() ([]byte, []int) {
|
||||
return file_treasurer_service_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *GetB2BPaymentLinkRequest) GetMainSettings() *MainPaymentSettings {
|
||||
if x != nil {
|
||||
return x.MainSettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetB2BPaymentLinkRequest) GetPaymentPurpose() string {
|
||||
if x != nil {
|
||||
return x.PaymentPurpose
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetB2BPaymentLinkRequest) GetVatData() *emptypb.Empty {
|
||||
if x != nil {
|
||||
return x.VatData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetPaymentLinkResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
RedirectURL string `protobuf:"bytes,1,opt,name=RedirectURL,proto3" json:"RedirectURL,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetPaymentLinkResponse) Reset() {
|
||||
*x = GetPaymentLinkResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_treasurer_service_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetPaymentLinkResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetPaymentLinkResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetPaymentLinkResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_treasurer_service_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetPaymentLinkResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetPaymentLinkResponse) Descriptor() ([]byte, []int) {
|
||||
return file_treasurer_service_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *GetPaymentLinkResponse) GetRedirectURL() string {
|
||||
if x != nil {
|
||||
return x.RedirectURL
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_treasurer_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_treasurer_service_proto_rawDesc = []byte{
|
||||
0x0a, 0x17, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x74, 0x72, 0x65, 0x61, 0x73,
|
||||
0x75, 0x72, 0x65, 0x72, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x1a, 0x1d, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2f, 0x70, 0x61, 0x79,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x22, 0x9f, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6e, 0x6b, 0x43, 0x61, 0x72, 0x64,
|
||||
0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x42, 0x0a, 0x0c, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
|
||||
0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73,
|
||||
0x75, 0x72, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0c, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x65,
|
||||
0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x0a, 0x08, 0x42, 0x61, 0x6e, 0x6b, 0x43, 0x61,
|
||||
0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73,
|
||||
0x75, 0x72, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6e, 0x6b, 0x43, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x42, 0x61, 0x6e, 0x6b, 0x43, 0x61,
|
||||
0x72, 0x64, 0x22, 0x5b, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0c, 0x4d,
|
||||
0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x4d, 0x61,
|
||||
0x69, 0x6e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67,
|
||||
0x73, 0x52, 0x0c, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22,
|
||||
0x76, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a,
|
||||
0x0c, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e,
|
||||
0x4d, 0x61, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69,
|
||||
0x6e, 0x67, 0x73, 0x52, 0x0c, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67,
|
||||
0x73, 0x12, 0x14, 0x0a, 0x05, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x05, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x22, 0x76, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4c, 0x6f,
|
||||
0x67, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0c, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74,
|
||||
0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x72,
|
||||
0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0c, 0x4d, 0x61, 0x69,
|
||||
0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x6f, 0x67,
|
||||
0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x22,
|
||||
0xb8, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x42, 0x32, 0x42, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0c,
|
||||
0x4d, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x4d,
|
||||
0x61, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
|
||||
0x67, 0x73, 0x52, 0x0c, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73,
|
||||
0x12, 0x26, 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x75, 0x72, 0x70, 0x6f,
|
||||
0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x50, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x56, 0x61, 0x74, 0x44,
|
||||
0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x52, 0x07, 0x56, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x0a, 0x16, 0x47, 0x65,
|
||||
0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
|
||||
0x55, 0x52, 0x4c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x52, 0x65, 0x64, 0x69, 0x72,
|
||||
0x65, 0x63, 0x74, 0x55, 0x52, 0x4c, 0x32, 0xd8, 0x08, 0x0a, 0x10, 0x54, 0x72, 0x65, 0x61, 0x73,
|
||||
0x75, 0x72, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x67, 0x0a, 0x16, 0x47,
|
||||
0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x42, 0x61, 0x6e,
|
||||
0x6b, 0x43, 0x61, 0x72, 0x64, 0x12, 0x28, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
|
||||
0x72, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6e, 0x6b, 0x43, 0x61, 0x72, 0x64, 0x50, 0x61, 0x79,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x21, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50,
|
||||
0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x59, 0x6f, 0x6f, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x12, 0x20,
|
||||
0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x21, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x51, 0x49, 0x57, 0x49, 0x12, 0x25, 0x2e, 0x74, 0x72,
|
||||
0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x6f, 0x6e, 0x65,
|
||||
0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47,
|
||||
0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x62, 0x65, 0x72, 0x50, 0x61, 0x79,
|
||||
0x12, 0x25, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x50, 0x68, 0x6f, 0x6e, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75,
|
||||
0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69,
|
||||
0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x17,
|
||||
0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x6c,
|
||||
0x66, 0x61, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x25, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75,
|
||||
0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
|
||||
0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x54, 0x69, 0x6e, 0x6b, 0x6f, 0x66, 0x66, 0x12, 0x20, 0x2e, 0x74,
|
||||
0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
|
||||
0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x62, 0x65, 0x72, 0x62, 0x61, 0x6e, 0x6b, 0x42, 0x32, 0x42,
|
||||
0x12, 0x23, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x42, 0x32, 0x42, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
|
||||
0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x11, 0x47, 0x65,
|
||||
0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x42, 0x50, 0x12,
|
||||
0x20, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50,
|
||||
0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x21, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x12, 0x25,
|
||||
0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68,
|
||||
0x6f, 0x6e, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
|
||||
0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x12, 0x47, 0x65,
|
||||
0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x61, 0x73, 0x68,
|
||||
0x12, 0x25, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x50, 0x68, 0x6f, 0x6e, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75,
|
||||
0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69,
|
||||
0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x1a,
|
||||
0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x49, 0x6e,
|
||||
0x73, 0x74, 0x61, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x74, 0x72, 0x65,
|
||||
0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74,
|
||||
0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x42, 0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x72,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_treasurer_service_proto_rawDescOnce sync.Once
|
||||
file_treasurer_service_proto_rawDescData = file_treasurer_service_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_treasurer_service_proto_rawDescGZIP() []byte {
|
||||
file_treasurer_service_proto_rawDescOnce.Do(func() {
|
||||
file_treasurer_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_treasurer_service_proto_rawDescData)
|
||||
})
|
||||
return file_treasurer_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_treasurer_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_treasurer_service_proto_goTypes = []interface{}{
|
||||
(*GetBankCardPaymentLinkRequest)(nil), // 0: treasurer.GetBankCardPaymentLinkRequest
|
||||
(*GetPaymentLinkRequest)(nil), // 1: treasurer.GetPaymentLinkRequest
|
||||
(*GetPhonePaymentLinkRequest)(nil), // 2: treasurer.GetPhonePaymentLinkRequest
|
||||
(*GetLoginPaymentLinkRequest)(nil), // 3: treasurer.GetLoginPaymentLinkRequest
|
||||
(*GetB2BPaymentLinkRequest)(nil), // 4: treasurer.GetB2BPaymentLinkRequest
|
||||
(*GetPaymentLinkResponse)(nil), // 5: treasurer.GetPaymentLinkResponse
|
||||
(*MainPaymentSettings)(nil), // 6: treasurer.MainPaymentSettings
|
||||
(*BankCardInformation)(nil), // 7: treasurer.BankCardInformation
|
||||
(*emptypb.Empty)(nil), // 8: google.protobuf.Empty
|
||||
}
|
||||
var file_treasurer_service_proto_depIdxs = []int32{
|
||||
6, // 0: treasurer.GetBankCardPaymentLinkRequest.MainSettings:type_name -> treasurer.MainPaymentSettings
|
||||
7, // 1: treasurer.GetBankCardPaymentLinkRequest.BankCard:type_name -> treasurer.BankCardInformation
|
||||
6, // 2: treasurer.GetPaymentLinkRequest.MainSettings:type_name -> treasurer.MainPaymentSettings
|
||||
6, // 3: treasurer.GetPhonePaymentLinkRequest.MainSettings:type_name -> treasurer.MainPaymentSettings
|
||||
6, // 4: treasurer.GetLoginPaymentLinkRequest.MainSettings:type_name -> treasurer.MainPaymentSettings
|
||||
6, // 5: treasurer.GetB2BPaymentLinkRequest.MainSettings:type_name -> treasurer.MainPaymentSettings
|
||||
8, // 6: treasurer.GetB2BPaymentLinkRequest.VatData:type_name -> google.protobuf.Empty
|
||||
0, // 7: treasurer.TreasurerService.GetPaymentLinkBankCard:input_type -> treasurer.GetBankCardPaymentLinkRequest
|
||||
1, // 8: treasurer.TreasurerService.GetPaymentLinkYooMoney:input_type -> treasurer.GetPaymentLinkRequest
|
||||
2, // 9: treasurer.TreasurerService.GetPaymentLinkQIWI:input_type -> treasurer.GetPhonePaymentLinkRequest
|
||||
2, // 10: treasurer.TreasurerService.GetPaymentLinkSberPay:input_type -> treasurer.GetPhonePaymentLinkRequest
|
||||
3, // 11: treasurer.TreasurerService.GetPaymentLinkAlfaClick:input_type -> treasurer.GetLoginPaymentLinkRequest
|
||||
1, // 12: treasurer.TreasurerService.GetPaymentLinkTinkoff:input_type -> treasurer.GetPaymentLinkRequest
|
||||
4, // 13: treasurer.TreasurerService.GetPaymentLinkSberbankB2B:input_type -> treasurer.GetB2BPaymentLinkRequest
|
||||
1, // 14: treasurer.TreasurerService.GetPaymentLinkSBP:input_type -> treasurer.GetPaymentLinkRequest
|
||||
2, // 15: treasurer.TreasurerService.GetPaymentLinkMobile:input_type -> treasurer.GetPhonePaymentLinkRequest
|
||||
2, // 16: treasurer.TreasurerService.GetPaymentLinkCash:input_type -> treasurer.GetPhonePaymentLinkRequest
|
||||
1, // 17: treasurer.TreasurerService.GetPaymentLinkInstallments:input_type -> treasurer.GetPaymentLinkRequest
|
||||
5, // 18: treasurer.TreasurerService.GetPaymentLinkBankCard:output_type -> treasurer.GetPaymentLinkResponse
|
||||
5, // 19: treasurer.TreasurerService.GetPaymentLinkYooMoney:output_type -> treasurer.GetPaymentLinkResponse
|
||||
5, // 20: treasurer.TreasurerService.GetPaymentLinkQIWI:output_type -> treasurer.GetPaymentLinkResponse
|
||||
5, // 21: treasurer.TreasurerService.GetPaymentLinkSberPay:output_type -> treasurer.GetPaymentLinkResponse
|
||||
5, // 22: treasurer.TreasurerService.GetPaymentLinkAlfaClick:output_type -> treasurer.GetPaymentLinkResponse
|
||||
5, // 23: treasurer.TreasurerService.GetPaymentLinkTinkoff:output_type -> treasurer.GetPaymentLinkResponse
|
||||
5, // 24: treasurer.TreasurerService.GetPaymentLinkSberbankB2B:output_type -> treasurer.GetPaymentLinkResponse
|
||||
5, // 25: treasurer.TreasurerService.GetPaymentLinkSBP:output_type -> treasurer.GetPaymentLinkResponse
|
||||
5, // 26: treasurer.TreasurerService.GetPaymentLinkMobile:output_type -> treasurer.GetPaymentLinkResponse
|
||||
5, // 27: treasurer.TreasurerService.GetPaymentLinkCash:output_type -> treasurer.GetPaymentLinkResponse
|
||||
5, // 28: treasurer.TreasurerService.GetPaymentLinkInstallments:output_type -> treasurer.GetPaymentLinkResponse
|
||||
18, // [18:29] is the sub-list for method output_type
|
||||
7, // [7:18] is the sub-list for method input_type
|
||||
7, // [7:7] is the sub-list for extension type_name
|
||||
7, // [7:7] is the sub-list for extension extendee
|
||||
0, // [0:7] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_treasurer_service_proto_init() }
|
||||
func file_treasurer_service_proto_init() {
|
||||
if File_treasurer_service_proto != nil {
|
||||
return
|
||||
}
|
||||
file_treasurer_payment_model_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_treasurer_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetBankCardPaymentLinkRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_treasurer_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetPaymentLinkRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_treasurer_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetPhonePaymentLinkRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_treasurer_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetLoginPaymentLinkRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_treasurer_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetB2BPaymentLinkRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_treasurer_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetPaymentLinkResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_treasurer_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_treasurer_service_proto_goTypes,
|
||||
DependencyIndexes: file_treasurer_service_proto_depIdxs,
|
||||
MessageInfos: file_treasurer_service_proto_msgTypes,
|
||||
}.Build()
|
||||
File_treasurer_service_proto = out.File
|
||||
file_treasurer_service_proto_rawDesc = nil
|
||||
file_treasurer_service_proto_goTypes = nil
|
||||
file_treasurer_service_proto_depIdxs = nil
|
||||
}
|
459
internal/proto/treasurer/service_grpc.pb.go
Normal file
459
internal/proto/treasurer/service_grpc.pb.go
Normal file
@ -0,0 +1,459 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
|
||||
package treasurer
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
// TreasurerServiceClient is the client API for TreasurerService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type TreasurerServiceClient interface {
|
||||
GetPaymentLinkBankCard(ctx context.Context, in *GetBankCardPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkYooMoney(ctx context.Context, in *GetPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkQIWI(ctx context.Context, in *GetPhonePaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkSberPay(ctx context.Context, in *GetPhonePaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkAlfaClick(ctx context.Context, in *GetLoginPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkTinkoff(ctx context.Context, in *GetPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkSberbankB2B(ctx context.Context, in *GetB2BPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkSBP(ctx context.Context, in *GetPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkMobile(ctx context.Context, in *GetPhonePaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkCash(ctx context.Context, in *GetPhonePaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkInstallments(ctx context.Context, in *GetPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error)
|
||||
}
|
||||
|
||||
type treasurerServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewTreasurerServiceClient(cc grpc.ClientConnInterface) TreasurerServiceClient {
|
||||
return &treasurerServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkBankCard(ctx context.Context, in *GetBankCardPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkBankCard", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkYooMoney(ctx context.Context, in *GetPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkYooMoney", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkQIWI(ctx context.Context, in *GetPhonePaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkQIWI", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkSberPay(ctx context.Context, in *GetPhonePaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkSberPay", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkAlfaClick(ctx context.Context, in *GetLoginPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkAlfaClick", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkTinkoff(ctx context.Context, in *GetPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkTinkoff", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkSberbankB2B(ctx context.Context, in *GetB2BPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkSberbankB2B", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkSBP(ctx context.Context, in *GetPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkSBP", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkMobile(ctx context.Context, in *GetPhonePaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkMobile", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkCash(ctx context.Context, in *GetPhonePaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkCash", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *treasurerServiceClient) GetPaymentLinkInstallments(ctx context.Context, in *GetPaymentLinkRequest, opts ...grpc.CallOption) (*GetPaymentLinkResponse, error) {
|
||||
out := new(GetPaymentLinkResponse)
|
||||
err := c.cc.Invoke(ctx, "/treasurer.TreasurerService/GetPaymentLinkInstallments", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// TreasurerServiceServer is the server API for TreasurerService service.
|
||||
// All implementations should embed UnimplementedTreasurerServiceServer
|
||||
// for forward compatibility
|
||||
type TreasurerServiceServer interface {
|
||||
GetPaymentLinkBankCard(context.Context, *GetBankCardPaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkYooMoney(context.Context, *GetPaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkQIWI(context.Context, *GetPhonePaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkSberPay(context.Context, *GetPhonePaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkAlfaClick(context.Context, *GetLoginPaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkTinkoff(context.Context, *GetPaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkSberbankB2B(context.Context, *GetB2BPaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkSBP(context.Context, *GetPaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkMobile(context.Context, *GetPhonePaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkCash(context.Context, *GetPhonePaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
GetPaymentLinkInstallments(context.Context, *GetPaymentLinkRequest) (*GetPaymentLinkResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedTreasurerServiceServer should be embedded to have forward compatible implementations.
|
||||
type UnimplementedTreasurerServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkBankCard(context.Context, *GetBankCardPaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkBankCard not implemented")
|
||||
}
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkYooMoney(context.Context, *GetPaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkYooMoney not implemented")
|
||||
}
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkQIWI(context.Context, *GetPhonePaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkQIWI not implemented")
|
||||
}
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkSberPay(context.Context, *GetPhonePaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkSberPay not implemented")
|
||||
}
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkAlfaClick(context.Context, *GetLoginPaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkAlfaClick not implemented")
|
||||
}
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkTinkoff(context.Context, *GetPaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkTinkoff not implemented")
|
||||
}
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkSberbankB2B(context.Context, *GetB2BPaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkSberbankB2B not implemented")
|
||||
}
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkSBP(context.Context, *GetPaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkSBP not implemented")
|
||||
}
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkMobile(context.Context, *GetPhonePaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkMobile not implemented")
|
||||
}
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkCash(context.Context, *GetPhonePaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkCash not implemented")
|
||||
}
|
||||
func (UnimplementedTreasurerServiceServer) GetPaymentLinkInstallments(context.Context, *GetPaymentLinkRequest) (*GetPaymentLinkResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPaymentLinkInstallments not implemented")
|
||||
}
|
||||
|
||||
// UnsafeTreasurerServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to TreasurerServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeTreasurerServiceServer interface {
|
||||
mustEmbedUnimplementedTreasurerServiceServer()
|
||||
}
|
||||
|
||||
func RegisterTreasurerServiceServer(s grpc.ServiceRegistrar, srv TreasurerServiceServer) {
|
||||
s.RegisterService(&TreasurerService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkBankCard_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetBankCardPaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkBankCard(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkBankCard",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkBankCard(ctx, req.(*GetBankCardPaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkYooMoney_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkYooMoney(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkYooMoney",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkYooMoney(ctx, req.(*GetPaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkQIWI_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPhonePaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkQIWI(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkQIWI",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkQIWI(ctx, req.(*GetPhonePaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkSberPay_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPhonePaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkSberPay(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkSberPay",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkSberPay(ctx, req.(*GetPhonePaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkAlfaClick_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetLoginPaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkAlfaClick(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkAlfaClick",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkAlfaClick(ctx, req.(*GetLoginPaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkTinkoff_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkTinkoff(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkTinkoff",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkTinkoff(ctx, req.(*GetPaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkSberbankB2B_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetB2BPaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkSberbankB2B(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkSberbankB2B",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkSberbankB2B(ctx, req.(*GetB2BPaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkSBP_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkSBP(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkSBP",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkSBP(ctx, req.(*GetPaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkMobile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPhonePaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkMobile(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkMobile",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkMobile(ctx, req.(*GetPhonePaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkCash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPhonePaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkCash(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkCash",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkCash(ctx, req.(*GetPhonePaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TreasurerService_GetPaymentLinkInstallments_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPaymentLinkRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkInstallments(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/treasurer.TreasurerService/GetPaymentLinkInstallments",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TreasurerServiceServer).GetPaymentLinkInstallments(ctx, req.(*GetPaymentLinkRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// TreasurerService_ServiceDesc is the grpc.ServiceDesc for TreasurerService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var TreasurerService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "treasurer.TreasurerService",
|
||||
HandlerType: (*TreasurerServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetPaymentLinkBankCard",
|
||||
Handler: _TreasurerService_GetPaymentLinkBankCard_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPaymentLinkYooMoney",
|
||||
Handler: _TreasurerService_GetPaymentLinkYooMoney_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPaymentLinkQIWI",
|
||||
Handler: _TreasurerService_GetPaymentLinkQIWI_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPaymentLinkSberPay",
|
||||
Handler: _TreasurerService_GetPaymentLinkSberPay_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPaymentLinkAlfaClick",
|
||||
Handler: _TreasurerService_GetPaymentLinkAlfaClick_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPaymentLinkTinkoff",
|
||||
Handler: _TreasurerService_GetPaymentLinkTinkoff_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPaymentLinkSberbankB2B",
|
||||
Handler: _TreasurerService_GetPaymentLinkSberbankB2B_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPaymentLinkSBP",
|
||||
Handler: _TreasurerService_GetPaymentLinkSBP_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPaymentLinkMobile",
|
||||
Handler: _TreasurerService_GetPaymentLinkMobile_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPaymentLinkCash",
|
||||
Handler: _TreasurerService_GetPaymentLinkCash_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPaymentLinkInstallments",
|
||||
Handler: _TreasurerService_GetPaymentLinkInstallments_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "treasurer/service.proto",
|
||||
}
|
78
internal/server/grpc.go
Normal file
78
internal/server/grpc.go
Normal file
@ -0,0 +1,78 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
|
||||
grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/proto/treasurer"
|
||||
)
|
||||
|
||||
type DepsGRPC struct {
|
||||
Logger *zap.Logger
|
||||
}
|
||||
|
||||
type GRPC struct {
|
||||
logger *zap.Logger
|
||||
grpc *grpc.Server
|
||||
}
|
||||
|
||||
func NewGRPC(deps DepsGRPC) (*GRPC, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("Logger is nil on <NewGRPC>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
grpcStreamInterceptor := grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
|
||||
grpc_zap.StreamServerInterceptor(deps.Logger),
|
||||
grpc_recovery.StreamServerInterceptor(),
|
||||
))
|
||||
|
||||
grpcUnaryInterceptor := grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
|
||||
grpc_zap.UnaryServerInterceptor(deps.Logger),
|
||||
grpc_recovery.UnaryServerInterceptor(),
|
||||
))
|
||||
|
||||
return &GRPC{
|
||||
grpc: grpc.NewServer(grpcStreamInterceptor, grpcUnaryInterceptor),
|
||||
logger: deps.Logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *GRPC) Run(config *models.ConfigurationGRPC) {
|
||||
connectionString := fmt.Sprintf("%s:%s", config.Host, config.Port)
|
||||
|
||||
receiver.logger.Info("Starting GRPC Server", zap.String("host", connectionString))
|
||||
|
||||
if err := receiver.listen(connectionString); err != nil && err != grpc.ErrServerStopped {
|
||||
receiver.logger.Error("GRPC Listen error", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *GRPC) Stop(_ context.Context) error {
|
||||
receiver.grpc.GracefulStop()
|
||||
receiver.logger.Info("Shutting down GRPC server...")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *GRPC) Register(server treasurer.TreasurerServiceServer) *GRPC {
|
||||
treasurer.RegisterTreasurerServiceServer(receiver.grpc, server)
|
||||
|
||||
return receiver
|
||||
}
|
||||
|
||||
func (receiver *GRPC) listen(address string) error {
|
||||
listener, err := net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return receiver.grpc.Serve(listener)
|
||||
}
|
85
internal/server/http.go
Normal file
85
internal/server/http.go
Normal file
@ -0,0 +1,85 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/swagger"
|
||||
)
|
||||
|
||||
type DepsHTTP struct {
|
||||
Logger *zap.Logger
|
||||
Swagger *openapi3.T
|
||||
}
|
||||
|
||||
type HTTP struct {
|
||||
logger *zap.Logger
|
||||
server *http.Server
|
||||
echo *echo.Echo
|
||||
}
|
||||
|
||||
func NewHTTP(deps DepsHTTP) (*HTTP, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("Logger is nil on <NewHTTP>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.Swagger == nil {
|
||||
return nil, errors.NewWithMessage("Swagger is nil on <NewHTTP>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
echo := echo.New()
|
||||
|
||||
echo.Use(middleware.Recover())
|
||||
|
||||
return &HTTP{
|
||||
echo: echo,
|
||||
logger: deps.Logger,
|
||||
server: &http.Server{
|
||||
Handler: echo,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
ReadTimeout: 10 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *HTTP) Listen(address string) error {
|
||||
receiver.server.Addr = address
|
||||
|
||||
return receiver.server.ListenAndServe()
|
||||
}
|
||||
|
||||
func (receiver *HTTP) Run(config *models.ConfigurationHTTP) {
|
||||
connectionString := fmt.Sprintf("%s:%s", config.Host, config.Port)
|
||||
startServerMessage := fmt.Sprintf("starting http server on %s", connectionString)
|
||||
|
||||
receiver.logger.Info(startServerMessage)
|
||||
|
||||
if err := receiver.Listen(connectionString); err != nil && err != http.ErrServerClosed {
|
||||
receiver.logger.Error("http listen error: ", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *HTTP) Stop(ctx context.Context) error {
|
||||
receiver.logger.Info("shutting down server...")
|
||||
|
||||
if err := receiver.server.Shutdown(ctx); err != nil {
|
||||
return fmt.Errorf("failed to shutdown server: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *HTTP) Register(api *swagger.API) *HTTP {
|
||||
swagger.RegisterHandlers(receiver.echo, api)
|
||||
|
||||
return receiver
|
||||
}
|
127
internal/service/callback/callback.go
Normal file
127
internal/service/callback/callback.go
Normal file
@ -0,0 +1,127 @@
|
||||
package callback
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
)
|
||||
|
||||
type CallbackClient interface {
|
||||
SendOnSuccess(ctx context.Context, host string, event *models.Event) errors.Error
|
||||
SendOnFailure(ctx context.Context, host string, event *models.Event) errors.Error
|
||||
}
|
||||
|
||||
type PaymentRepository interface {
|
||||
SetPaymentComplete(ctx context.Context, paymentID string) (*models.Payment, errors.Error)
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
CallbackClient CallbackClient
|
||||
PaymentRepository PaymentRepository
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
callbackClient CallbackClient
|
||||
paymentRepository PaymentRepository
|
||||
}
|
||||
|
||||
func New(deps Deps) (*Service, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("logger is nil on <NewCallbackService>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.CallbackClient == nil {
|
||||
return nil, errors.NewWithMessage("CallbackClient is nil on <NewCallbackService>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.PaymentRepository == nil {
|
||||
return nil, errors.NewWithMessage("PaymentRepository is nil on <NewCallbackService>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &Service{
|
||||
logger: deps.Logger,
|
||||
callbackClient: deps.CallbackClient,
|
||||
paymentRepository: deps.PaymentRepository,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) OnSuccess(ctx context.Context, event *models.Event) errors.Error {
|
||||
waitGroup := sync.WaitGroup{}
|
||||
mutex := sync.Mutex{}
|
||||
executeErrors := make([]error, 0)
|
||||
|
||||
for _, callbackURL := range event.Payment.CallbackHostGRPC {
|
||||
waitGroup.Add(1)
|
||||
|
||||
go func(url string) {
|
||||
defer waitGroup.Done()
|
||||
|
||||
if err := receiver.callbackClient.SendOnSuccess(ctx, url, event); err != nil {
|
||||
receiver.logger.Error("failid to send callback on <OnSuccess> of <CallbackService>")
|
||||
|
||||
mutex.Lock()
|
||||
executeErrors = append(executeErrors, err)
|
||||
mutex.Unlock()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := receiver.paymentRepository.SetPaymentComplete(ctx, event.Payment.PaymentID); err != nil {
|
||||
receiver.logger.Error("failid to set payment complete on <OnSuccess> of <CallbackService>")
|
||||
|
||||
mutex.Lock()
|
||||
executeErrors = append(executeErrors, err)
|
||||
mutex.Unlock()
|
||||
|
||||
return
|
||||
}
|
||||
}(callbackURL)
|
||||
}
|
||||
|
||||
waitGroup.Wait()
|
||||
|
||||
if len(executeErrors) >= len(event.Payment.CallbackHostGRPC) {
|
||||
receiver.logger.Error("failid to success payment on <OnSuccess> of <CallbackService>", zap.Errors("errors", executeErrors))
|
||||
return errors.NewWithMessage("failed to success payment: all operations failed", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *Service) OnFailure(ctx context.Context, event *models.Event) errors.Error {
|
||||
waitGroup := sync.WaitGroup{}
|
||||
mutex := sync.Mutex{}
|
||||
executeErrors := make([]error, 0)
|
||||
|
||||
for _, callbackURL := range event.Payment.CallbackHostGRPC {
|
||||
waitGroup.Add(1)
|
||||
|
||||
go func(url string) {
|
||||
defer waitGroup.Done()
|
||||
|
||||
if err := receiver.callbackClient.SendOnFailure(ctx, url, event); err != nil {
|
||||
receiver.logger.Error("failid to send callback on <OnFailure> of <CallbackService>")
|
||||
|
||||
mutex.Lock()
|
||||
executeErrors = append(executeErrors, err)
|
||||
mutex.Unlock()
|
||||
|
||||
return
|
||||
}
|
||||
}(callbackURL)
|
||||
}
|
||||
|
||||
waitGroup.Wait()
|
||||
|
||||
if len(executeErrors) >= len(event.Payment.CallbackHostGRPC) {
|
||||
receiver.logger.Error("failid to success payment on <OnFailure> of <CallbackService>", zap.Errors("errors", executeErrors))
|
||||
return errors.NewWithMessage("failed to success payment: all operations failed", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
153
internal/service/payment/payment.go
Normal file
153
internal/service/payment/payment.go
Normal file
@ -0,0 +1,153 @@
|
||||
package payment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/utils"
|
||||
)
|
||||
|
||||
type PaymentStrategyService interface {
|
||||
CreatePaymentPhone(ctx context.Context, uuid string, payment *models.CreatePayment[string]) (*models.CreatePaymentResult, errors.Error)
|
||||
CreatePaymentBankCard(ctx context.Context, uuid string, payment *models.CreatePayment[*models.BankCard]) (*models.CreatePaymentResult, errors.Error)
|
||||
CreatePayment(ctx context.Context, uuid string, payment *models.CreatePayment[*any]) (*models.CreatePaymentResult, errors.Error)
|
||||
CreatePaymentLogin(ctx context.Context, uuid string, payment *models.CreatePayment[string]) (*models.CreatePaymentResult, errors.Error)
|
||||
}
|
||||
|
||||
type PaymentRepository interface {
|
||||
Insert(context.Context, *models.Payment) (*models.Payment, errors.Error)
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
PaymentStrategyService PaymentStrategyService
|
||||
PaymentRepository PaymentRepository
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
paymentStrategyService PaymentStrategyService
|
||||
paymentRepository PaymentRepository
|
||||
}
|
||||
|
||||
func New(deps Deps) (*Service, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("logger is nil on <NewCallbackClient>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.PaymentStrategyService == nil {
|
||||
return nil, errors.NewWithMessage("PaymentStrategyService is nil on <NewCallbackClient>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.PaymentRepository == nil {
|
||||
return nil, errors.NewWithMessage("PaymentRepository is nil on <NewCallbackClient>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &Service{
|
||||
logger: deps.Logger,
|
||||
paymentStrategyService: deps.PaymentStrategyService,
|
||||
paymentRepository: deps.PaymentRepository,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) CreatePaymentPhone(ctx context.Context, request *models.CreatePayment[string]) (string, errors.Error) {
|
||||
paymentUUID, generateErr := utils.GenerateUUID()
|
||||
if generateErr != nil {
|
||||
receiver.logger.Error("failed to generate uuid on <CreatePaymentPhone> of <PaymentService>", zap.Error(generateErr))
|
||||
return "", errors.NewWithError(fmt.Errorf("failed to generate uuid: %w", generateErr), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
response, err := receiver.paymentStrategyService.CreatePaymentPhone(ctx, paymentUUID, request)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentPhone> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
if _, err := receiver.paymentRepository.Insert(ctx, response.Payment); err != nil {
|
||||
receiver.logger.Error("failed to insert payment on <CreatePaymentPhone> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return response.RedirectURL, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) CreatePaymentBankCard(ctx context.Context, request *models.CreatePayment[*models.BankCard]) (string, errors.Error) {
|
||||
paymentUUID, generateErr := utils.GenerateUUID()
|
||||
if generateErr != nil {
|
||||
receiver.logger.Error("failed to generate uuid on <CreatePaymentBankCard> of <PaymentService>", zap.Error(generateErr))
|
||||
return "", errors.NewWithError(fmt.Errorf("failed to generate uuid: %w", generateErr), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
response, err := receiver.paymentStrategyService.CreatePaymentBankCard(ctx, paymentUUID, request)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentBankCard> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
if _, err := receiver.paymentRepository.Insert(ctx, response.Payment); err != nil {
|
||||
receiver.logger.Error("failed to insert payment on <CreatePaymentBankCard> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return response.RedirectURL, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) CreatePayment(ctx context.Context, request *models.CreatePayment[*any]) (string, errors.Error) {
|
||||
paymentUUID, generateErr := utils.GenerateUUID()
|
||||
if generateErr != nil {
|
||||
receiver.logger.Error("failed to generate uuid on <CreatePayment> of <PaymentService>", zap.Error(generateErr))
|
||||
return "", errors.NewWithError(fmt.Errorf("failed to generate uuid: %w", generateErr), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
response, err := receiver.paymentStrategyService.CreatePayment(ctx, paymentUUID, request)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePayment> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
if _, err := receiver.paymentRepository.Insert(ctx, response.Payment); err != nil {
|
||||
receiver.logger.Error("failed to insert payment on <CreatePayment> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return response.RedirectURL, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) CreatePaymentLogin(ctx context.Context, request *models.CreatePayment[string]) (string, errors.Error) {
|
||||
paymentUUID, generateErr := utils.GenerateUUID()
|
||||
if generateErr != nil {
|
||||
receiver.logger.Error("failed to generate uuid on <CreatePaymentLogin> of <PaymentService>", zap.Error(generateErr))
|
||||
return "", errors.NewWithError(fmt.Errorf("failed to generate uuid: %w", generateErr), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
response, err := receiver.paymentStrategyService.CreatePaymentLogin(ctx, paymentUUID, request)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentLogin> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
if _, err := receiver.paymentRepository.Insert(ctx, response.Payment); err != nil {
|
||||
receiver.logger.Error("failed to insert payment on <CreatePaymentLogin> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return response.RedirectURL, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) GetAvailablePaymentMethods(_ context.Context) ([]models.PaymentType, errors.Error) {
|
||||
return []models.PaymentType{
|
||||
models.PaymentTypeBankCard,
|
||||
models.PaymentTypeTinkoff,
|
||||
models.PaymentTypeQiwi,
|
||||
models.PaymentTypeSberPay,
|
||||
models.PaymentTypeYoomoney,
|
||||
models.PaymentTypeMobile,
|
||||
models.PaymentTypeInstallments,
|
||||
models.PaymentTypeCash,
|
||||
models.PaymentTypeSBP,
|
||||
models.PaymentTypeSberB2B,
|
||||
}, nil
|
||||
}
|
213
internal/service/payment/yandex.go
Normal file
213
internal/service/payment/yandex.go
Normal file
@ -0,0 +1,213 @@
|
||||
package payment
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models/yandex"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/utils"
|
||||
)
|
||||
|
||||
type YandexPaymentClient interface {
|
||||
CreatePaymentPhone(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodPhone]) (*yandex.Payment, errors.Error)
|
||||
CreatePayment(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodType]) (*yandex.Payment, errors.Error)
|
||||
CreatePaymentBankCard(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodBankCard]) (*yandex.Payment, errors.Error)
|
||||
CreatePaymentB2B(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodB2B]) (*yandex.Payment, errors.Error)
|
||||
CreatePaymentLogin(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodLogin]) (*yandex.Payment, errors.Error)
|
||||
}
|
||||
|
||||
type YandexPaymentServiceDeps struct {
|
||||
Logger *zap.Logger
|
||||
YandexPaymentClient YandexPaymentClient
|
||||
}
|
||||
|
||||
type Yandex struct {
|
||||
logger *zap.Logger
|
||||
yandexPaymentClient YandexPaymentClient
|
||||
}
|
||||
|
||||
func NewYandex(deps YandexPaymentServiceDeps) (*Yandex, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("logger is nil on <NewCallbackClient>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.YandexPaymentClient == nil {
|
||||
return nil, errors.NewWithMessage("YandexPaymentClient is nil on <NewCallbackClient>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &Yandex{
|
||||
logger: deps.Logger,
|
||||
yandexPaymentClient: deps.YandexPaymentClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) CreatePaymentPhone(ctx context.Context, uuid string, request *models.CreatePayment[string]) (*models.CreatePaymentResult, errors.Error) {
|
||||
yandexPayment, err := receiver.yandexPaymentClient.CreatePaymentPhone(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodPhone]{
|
||||
Amount: yandex.Amount{
|
||||
Value: utils.ConvertAmountToStringFloat(request.Amount),
|
||||
Currency: request.Currency,
|
||||
},
|
||||
PaymentMethodData: &yandex.PaymentMethodPhone{
|
||||
Type: models.YandexPaymentTypeMap[request.Type],
|
||||
Phone: request.Requisites,
|
||||
},
|
||||
Confirmation: &yandex.CreateConfirmationRedirect{
|
||||
Type: yandex.ConfirmationTypeRedirect,
|
||||
Locale: "ru_RU",
|
||||
ReturnURL: request.ReturnURL,
|
||||
Enforce: true,
|
||||
},
|
||||
Capture: true,
|
||||
ClientIP: request.ClientIP,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentPhone> of <YandexPaymentService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.CreatePaymentResult{
|
||||
Payment: &models.Payment{
|
||||
UserID: request.UserID,
|
||||
PaymentID: yandexPayment.ID,
|
||||
ClientIP: request.ClientIP,
|
||||
Currency: request.Currency,
|
||||
IdempotencePaymentID: uuid,
|
||||
Amount: request.Amount,
|
||||
Type: request.Type,
|
||||
Status: models.PaymentStatusMap[string(yandexPayment.Status)],
|
||||
Completed: false,
|
||||
RawPaymentBody: yandexPayment,
|
||||
CallbackHostGRPC: request.CallbackHostGRPC,
|
||||
},
|
||||
RedirectURL: yandexPayment.Confirmation.ConfirmationURL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) CreatePaymentBankCard(ctx context.Context, uuid string, request *models.CreatePayment[*models.BankCard]) (*models.CreatePaymentResult, errors.Error) {
|
||||
yandexPayment, err := receiver.yandexPaymentClient.CreatePaymentBankCard(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodBankCard]{
|
||||
Amount: yandex.Amount{
|
||||
Value: utils.ConvertAmountToStringFloat(request.Amount),
|
||||
Currency: request.Currency,
|
||||
},
|
||||
PaymentMethodData: &yandex.PaymentMethodBankCard{
|
||||
Type: models.YandexPaymentTypeMap[request.Type],
|
||||
Card: &yandex.BankCardInformation{
|
||||
Number: request.Requisites.Number,
|
||||
ExpiryYear: request.Requisites.ExpiryYear,
|
||||
ExpiryMonth: request.Requisites.ExpiryMonth,
|
||||
},
|
||||
},
|
||||
Confirmation: &yandex.CreateConfirmationRedirect{
|
||||
Type: yandex.ConfirmationTypeRedirect,
|
||||
Locale: "ru_RU",
|
||||
ReturnURL: request.ReturnURL,
|
||||
Enforce: true,
|
||||
},
|
||||
Capture: true,
|
||||
ClientIP: request.ClientIP,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentBankCard> of <YandexPaymentService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.CreatePaymentResult{
|
||||
Payment: &models.Payment{
|
||||
UserID: request.UserID,
|
||||
PaymentID: yandexPayment.ID,
|
||||
IdempotencePaymentID: uuid,
|
||||
ClientIP: request.ClientIP,
|
||||
Currency: request.Currency,
|
||||
Amount: request.Amount,
|
||||
Type: request.Type,
|
||||
Status: models.PaymentStatusMap[string(yandexPayment.Status)],
|
||||
Completed: false,
|
||||
RawPaymentBody: yandexPayment,
|
||||
CallbackHostGRPC: request.CallbackHostGRPC,
|
||||
},
|
||||
RedirectURL: yandexPayment.Confirmation.ConfirmationURL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) CreatePayment(ctx context.Context, uuid string, request *models.CreatePayment[*any]) (*models.CreatePaymentResult, errors.Error) {
|
||||
yandexPayment, err := receiver.yandexPaymentClient.CreatePayment(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodType]{
|
||||
Amount: yandex.Amount{
|
||||
Value: utils.ConvertAmountToStringFloat(request.Amount),
|
||||
Currency: request.Currency,
|
||||
},
|
||||
PaymentMethodData: &yandex.PaymentMethodType{Type: models.YandexPaymentTypeMap[request.Type]},
|
||||
Confirmation: &yandex.CreateConfirmationRedirect{
|
||||
Type: yandex.ConfirmationTypeRedirect,
|
||||
Locale: "ru_RU",
|
||||
ReturnURL: request.ReturnURL,
|
||||
Enforce: true,
|
||||
},
|
||||
Capture: true,
|
||||
ClientIP: request.ClientIP,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePayment> of <YandexPaymentService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.CreatePaymentResult{
|
||||
Payment: &models.Payment{
|
||||
UserID: request.UserID,
|
||||
PaymentID: yandexPayment.ID,
|
||||
IdempotencePaymentID: uuid,
|
||||
ClientIP: request.ClientIP,
|
||||
Currency: request.Currency,
|
||||
Amount: request.Amount,
|
||||
Type: request.Type,
|
||||
Status: models.PaymentStatusMap[string(yandexPayment.Status)],
|
||||
Completed: false,
|
||||
RawPaymentBody: yandexPayment,
|
||||
CallbackHostGRPC: request.CallbackHostGRPC,
|
||||
},
|
||||
RedirectURL: yandexPayment.Confirmation.ConfirmationURL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) CreatePaymentLogin(ctx context.Context, uuid string, request *models.CreatePayment[string]) (*models.CreatePaymentResult, errors.Error) {
|
||||
yandexPayment, err := receiver.yandexPaymentClient.CreatePaymentLogin(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodLogin]{
|
||||
Amount: yandex.Amount{
|
||||
Value: utils.ConvertAmountToStringFloat(request.Amount),
|
||||
Currency: request.Currency,
|
||||
},
|
||||
PaymentMethodData: &yandex.PaymentMethodLogin{
|
||||
Type: models.YandexPaymentTypeMap[request.Type],
|
||||
Login: request.Requisites,
|
||||
},
|
||||
Confirmation: &yandex.CreateConfirmationRedirect{
|
||||
Type: yandex.ConfirmationTypeRedirect,
|
||||
Locale: "ru_RU",
|
||||
ReturnURL: request.ReturnURL,
|
||||
Enforce: true,
|
||||
},
|
||||
Capture: true,
|
||||
ClientIP: request.ClientIP,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentLogin> of <YandexPaymentService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.CreatePaymentResult{
|
||||
Payment: &models.Payment{
|
||||
UserID: request.UserID,
|
||||
PaymentID: yandexPayment.ID,
|
||||
IdempotencePaymentID: uuid,
|
||||
ClientIP: request.ClientIP,
|
||||
Currency: request.Currency,
|
||||
Amount: request.Amount,
|
||||
Type: request.Type,
|
||||
Status: models.PaymentStatusMap[string(yandexPayment.Status)],
|
||||
Completed: false,
|
||||
RawPaymentBody: yandexPayment,
|
||||
CallbackHostGRPC: request.CallbackHostGRPC,
|
||||
},
|
||||
RedirectURL: yandexPayment.Confirmation.ConfirmationURL,
|
||||
}, nil
|
||||
}
|
78
internal/service/status/status.go
Normal file
78
internal/service/status/status.go
Normal file
@ -0,0 +1,78 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
)
|
||||
|
||||
type PaymentRepository interface {
|
||||
SetPaymentStatus(ctx context.Context, paymentID string, status models.PaymentStatus) (*models.Payment, errors.Error)
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
PaymentRepository PaymentRepository
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
paymentRepository PaymentRepository
|
||||
}
|
||||
|
||||
func New(deps Deps) (*Service, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("logger is nil on <NewStatusService>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.PaymentRepository == nil {
|
||||
return nil, errors.NewWithMessage("PaymentRepository is nil on <NewStatusService>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &Service{
|
||||
logger: deps.Logger,
|
||||
paymentRepository: deps.PaymentRepository,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) SetStatusCanceled(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
payment, err := receiver.paymentRepository.SetPaymentStatus(ctx, paymentID, models.PaymentStatusCanceled)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to set payment status on <SetStatusCanceled> of <StatusService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return payment, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) SetStatusSuccess(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
payment, err := receiver.paymentRepository.SetPaymentStatus(ctx, paymentID, models.PaymentStatusSuccessfully)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to set payment status on <SetStatusSuccess> of <StatusService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return payment, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) SetStatusWaiting(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
payment, err := receiver.paymentRepository.SetPaymentStatus(ctx, paymentID, models.PaymentStatusWaiting)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to set payment status on <SetStatusWaiting> of <StatusService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return payment, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) SetStatusRefund(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
payment, err := receiver.paymentRepository.SetPaymentStatus(ctx, paymentID, models.PaymentStatusRefund)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to set payment status on <SetStatusRefund> of <StatusService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return payment, nil
|
||||
}
|
191
internal/service/webhook/yandex.go
Normal file
191
internal/service/webhook/yandex.go
Normal file
@ -0,0 +1,191 @@
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models/yandex"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/pkg/array"
|
||||
)
|
||||
|
||||
const (
|
||||
onYandexSuccessWebhookEventKey = "e242352d-5921-44b1-99f9-d022734fe514-success"
|
||||
onYandexCanceledWebhookEventKey = "e242352d-5921-44b1-99f9-d022734fe514-canceled"
|
||||
onYandexWaitingWebhookEventKey = "e242352d-5921-44b1-99f9-d022734fe514-waiting"
|
||||
onYandexRefundWebhookEventKey = "e242352d-5921-44b1-99f9-d022734fe514-refund"
|
||||
)
|
||||
|
||||
type YandexWebhookClient interface {
|
||||
SetWebhookEvent(ctx context.Context, idempotenceKey string, request *yandex.CreateWebhookRequest) (id string, err errors.Error)
|
||||
GetWebhookEvents(ctx context.Context) ([]yandex.Webhook, errors.Error)
|
||||
DeleteWebhook(ctx context.Context, webhookID string) errors.Error
|
||||
}
|
||||
|
||||
type YandexDeps struct {
|
||||
Logger *zap.Logger
|
||||
Configuration *models.ConfigurationHTTP
|
||||
YandexWebhookClient YandexWebhookClient
|
||||
}
|
||||
|
||||
type Yandex struct {
|
||||
logger *zap.Logger
|
||||
configuration *models.ConfigurationHTTP
|
||||
yandexWebhookClient YandexWebhookClient
|
||||
}
|
||||
|
||||
func NewYandex(deps YandexDeps) (*Yandex, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("logger is nil on <NewYandexWebhookService>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.Configuration == nil {
|
||||
return nil, errors.NewWithMessage("Configuration is nil on <NewYandexWebhookService>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.YandexWebhookClient == nil {
|
||||
return nil, errors.NewWithMessage("PaymentRepository is nil on <NewYandexWebhookService>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &Yandex{
|
||||
logger: deps.Logger,
|
||||
configuration: deps.Configuration,
|
||||
yandexWebhookClient: deps.YandexWebhookClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) SetOnPaymentSuccess(ctx context.Context) errors.Error {
|
||||
url, urlErr := url.JoinPath(receiver.configuration.Domen, "yandex", "payment", "status", "succeeded")
|
||||
if urlErr != nil {
|
||||
receiver.logger.Error("failed to join url path on <SetOnPaymentSuccess> of <WebhookService>", zap.Error(urlErr))
|
||||
return errors.NewWithError(fmt.Errorf("failed to join url path: %w", urlErr), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
if err := receiver.SetWebhook(ctx, onYandexSuccessWebhookEventKey, &yandex.CreateWebhookRequest{
|
||||
Event: yandex.WebhookEventPaymentSucceeded,
|
||||
URL: url,
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to set webhook on <SetOnPaymentSuccess> of <WebhookService>", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) SetOnPaymentCanceled(ctx context.Context) errors.Error {
|
||||
url, urlErr := url.JoinPath(receiver.configuration.Domen, "yandex", "payment", "status", "canceled")
|
||||
if urlErr != nil {
|
||||
receiver.logger.Error("failed to join url path on <SetOnPaymentCanceled> of <WebhookService>", zap.Error(urlErr))
|
||||
return errors.NewWithError(fmt.Errorf("failed to join url path: %w", urlErr), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
if err := receiver.SetWebhook(ctx, onYandexCanceledWebhookEventKey, &yandex.CreateWebhookRequest{
|
||||
Event: yandex.WebhookEventPaymentCanceled,
|
||||
URL: url,
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to set webhook on <SetOnPaymentCanceled> of <WebhookService>", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) SetOnPaymentWaiting(ctx context.Context) errors.Error {
|
||||
url, urlErr := url.JoinPath(receiver.configuration.Domen, "yandex", "payment", "status", "waiting")
|
||||
if urlErr != nil {
|
||||
receiver.logger.Error("failed to join url path on <SetOnPaymentWaiting> of <WebhookService>", zap.Error(urlErr))
|
||||
return errors.NewWithError(fmt.Errorf("failed to join url path: %w", urlErr), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
if err := receiver.SetWebhook(ctx, onYandexWaitingWebhookEventKey, &yandex.CreateWebhookRequest{
|
||||
Event: yandex.WebhookEventPaymentWaiting,
|
||||
URL: url,
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to set webhook on <SetOnPaymentWaiting> of <WebhookService>", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) SetOnPaymentRefund(ctx context.Context) errors.Error {
|
||||
url, urlErr := url.JoinPath(receiver.configuration.Domen, "yandex", "refund", "status", "canceled")
|
||||
if urlErr != nil {
|
||||
receiver.logger.Error("failed to join url path on <SetOnPaymentRefund> of <WebhookService>", zap.Error(urlErr))
|
||||
return errors.NewWithError(fmt.Errorf("failed to join url path: %w", urlErr), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
if err := receiver.SetWebhook(ctx, onYandexRefundWebhookEventKey, &yandex.CreateWebhookRequest{
|
||||
Event: yandex.WebhookEventRefundSucceeded,
|
||||
URL: url,
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to set webhook on <SetOnPaymentRefund> of <WebhookService>", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) SetWebhook(ctx context.Context, idempotenceKey string, request *yandex.CreateWebhookRequest) errors.Error {
|
||||
webhook, err := receiver.GetWebhookByType(ctx, request.Event)
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
receiver.logger.Error("failed to get webhook on <SetWebhook> of <WebhookService>", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
if webhook != nil {
|
||||
receiver.logger.Error("webhook already exist on <SetWebhook> of <WebhookService>")
|
||||
return errors.NewWithError(
|
||||
fmt.Errorf("yandex webhook with type <%s> already exist", request.Event),
|
||||
errors.ErrConflict,
|
||||
)
|
||||
}
|
||||
|
||||
if _, err := receiver.yandexWebhookClient.SetWebhookEvent(ctx, idempotenceKey, request); err != nil {
|
||||
receiver.logger.Error("failed to set webhook on <SetWebhook> of <WebhookService>", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) GetWebhookByType(ctx context.Context, event yandex.WebhookEventType) (*yandex.Webhook, errors.Error) {
|
||||
webhooks, err := receiver.yandexWebhookClient.GetWebhookEvents(ctx)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get webhooks list on <GetWebhookByKey> of <WebhookService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(webhooks) < 1 {
|
||||
receiver.logger.Error("empty webhooks on <GetWebhookByKey> of <WebhookService>")
|
||||
return nil, errors.NewWithMessage("webhooks empty in yandex server", errors.ErrNotFound)
|
||||
}
|
||||
|
||||
webhook := array.Find(webhooks, func(webhook yandex.Webhook, _ int, _ []yandex.Webhook) bool {
|
||||
return webhook.Event == event
|
||||
})
|
||||
if webhook == nil {
|
||||
receiver.logger.Error("webhook not found on <GetWebhookByKey> of <WebhookService>", zap.Error(err), zap.String("event", string(event)))
|
||||
return nil, errors.NewWithError(fmt.Errorf("yandex webhook not found with <%s> event", event), errors.ErrNotFound)
|
||||
}
|
||||
|
||||
return webhook, nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) UnsetWebhook(ctx context.Context, event yandex.WebhookEventType) errors.Error {
|
||||
webhook, err := receiver.GetWebhookByType(ctx, event)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get webhook on <UnsetWebhook> of <WebhookService>", zap.Error(err), zap.String("event", string(event)))
|
||||
return err
|
||||
}
|
||||
|
||||
if err := receiver.yandexWebhookClient.DeleteWebhook(ctx, webhook.ID); err != nil {
|
||||
receiver.logger.Error("failed to delete webhook on <UnsetWebhook> of <WebhookService>", zap.Error(err), zap.String("id", webhook.ID))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
224
internal/swagger/api.gen.go
Normal file
224
internal/swagger/api.gen.go
Normal file
@ -0,0 +1,224 @@
|
||||
// Package swagger provides primitives to interact with the openapi HTTP API.
|
||||
//
|
||||
// Code generated by github.com/deepmap/oapi-codegen version v1.12.4 DO NOT EDIT.
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
// ServerInterface represents all server handlers.
|
||||
type ServerInterface interface {
|
||||
// (GET /available)
|
||||
GetAvailablePayments(ctx echo.Context) error
|
||||
|
||||
// (POST /yandex/payment/status/canceled)
|
||||
SetYandexPaymentStatusCanceled(ctx echo.Context) error
|
||||
|
||||
// (POST /yandex/payment/status/succeeded)
|
||||
SetYandexPaymentStatusSucceeded(ctx echo.Context) error
|
||||
|
||||
// (POST /yandex/payment/status/waiting)
|
||||
SetYandexPaymentStatusWaiting(ctx echo.Context) error
|
||||
|
||||
// (POST /yandex/refund/status/succeeded)
|
||||
SetYandexRefundStatusSucceeded(ctx echo.Context) error
|
||||
}
|
||||
|
||||
// ServerInterfaceWrapper converts echo contexts to parameters.
|
||||
type ServerInterfaceWrapper struct {
|
||||
Handler ServerInterface
|
||||
}
|
||||
|
||||
// GetAvailablePayments converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetAvailablePayments(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.GetAvailablePayments(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetYandexPaymentStatusCanceled converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) SetYandexPaymentStatusCanceled(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.SetYandexPaymentStatusCanceled(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetYandexPaymentStatusSucceeded converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) SetYandexPaymentStatusSucceeded(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.SetYandexPaymentStatusSucceeded(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetYandexPaymentStatusWaiting converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) SetYandexPaymentStatusWaiting(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.SetYandexPaymentStatusWaiting(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetYandexRefundStatusSucceeded converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) SetYandexRefundStatusSucceeded(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.SetYandexRefundStatusSucceeded(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// This is a simple interface which specifies echo.Route addition functions which
|
||||
// are present on both echo.Echo and echo.Group, since we want to allow using
|
||||
// either of them for path registration
|
||||
type EchoRouter interface {
|
||||
CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
}
|
||||
|
||||
// RegisterHandlers adds each server route to the EchoRouter.
|
||||
func RegisterHandlers(router EchoRouter, si ServerInterface) {
|
||||
RegisterHandlersWithBaseURL(router, si, "")
|
||||
}
|
||||
|
||||
// Registers handlers, and prepends BaseURL to the paths, so that the paths
|
||||
// can be served under a prefix.
|
||||
func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) {
|
||||
|
||||
wrapper := ServerInterfaceWrapper{
|
||||
Handler: si,
|
||||
}
|
||||
|
||||
router.GET(baseURL+"/available", wrapper.GetAvailablePayments)
|
||||
router.POST(baseURL+"/yandex/payment/status/canceled", wrapper.SetYandexPaymentStatusCanceled)
|
||||
router.POST(baseURL+"/yandex/payment/status/succeeded", wrapper.SetYandexPaymentStatusSucceeded)
|
||||
router.POST(baseURL+"/yandex/payment/status/waiting", wrapper.SetYandexPaymentStatusWaiting)
|
||||
router.POST(baseURL+"/yandex/refund/status/succeeded", wrapper.SetYandexRefundStatusSucceeded)
|
||||
|
||||
}
|
||||
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"H4sIAAAAAAAC/+xYzW7bRhB+FWLbQwIwlpw2DaBb0kMR9NDARlEUSWBsyJXD1CIZknIiGAL0kzRBHTRI",
|
||||
"0EMPRYq0PReybNm0fuhXmH2FPkkxs0tJlLaOVSC3XBKJImdnvm++b4beY05QCwNf+EnMKnssdh6IGqeP",
|
||||
"N2pB3U/wUxgFoYgST9B1px5Fwnca+NkVsRN5YeIFPqsw+EO2YCCfwYHswhD6MIAJTOQ+nFowhAyOLOhD",
|
||||
"D0byZ9mR+xb0LfkUMtmCMfRkBwbWrc1vrnx+df06s5l4wmvhjmAVtvHtTWazpBHilziJPH+bNW22y3fq",
|
||||
"wpDDO9mFMUbE+NCX+3AgW9DDTCDDTKYpwKBwznp5rVxePqlps0g8qnuRcFnljj7WnqFwb/pEcP+hcBLM",
|
||||
"7TZv1ISfbCY8qRNmwq/X8OnH3Es8f3urGkRbDg+TeoSxQuG7eJbN4rrjCOEKF0/gviN2hDt3wqz6DeF4",
|
||||
"oSdM/HDHQeK2PNeAzq9whKzIDqTyKaQwJOQz2bIQMjiEHpxAChMN399f8zjmJvi3eSIe88aqp8i27MIB",
|
||||
"9GBIF7t0U++9qM/VVDjaBP6mSAr4b4hHdREbgBK7Gr/FDoIMDuQ+Zg8D24KMulcVABmMLdml3j7CLzCS",
|
||||
"r2AgO3NYzVrKDxKv6jmcIhtA1ElX9tinkaiyCvukNJNjSWux9D33XfFE14SPqTjL6oMUzixK/icYwBCR",
|
||||
"XbPgLyRAtiGl7PtTKQwsOEGi5XPSaQoD65/WL9Z8ztalYqn5jZdXqHKBSfrV1thPETDxWCx7uc2n9nQe",
|
||||
"dtrEmignkpu7xU2cv0HngrF8ZcEZOpXsYN2yBceqlSFVP42UU8GxqWlt5gR+1YtqCgrTKXNuRL4o23ie",
|
||||
"bCNr/+foGVxOJHjy/vLoqBM4ohwo8gmpEXVvLKkQaSnwWziDVLZVtAVDNfy4FF08Cb1IxO/J2rawA4sy",
|
||||
"PMQLfRwjY8jgGDWILX0AA8JUoTXBm/CZsUayI19akMII0kW0j/Jf55A2ZbyqrRaIK5rqDCoeu9XrPP4C",
|
||||
"/71WvYZfjWf7TlATW6u2fsiNSf8uW5AqD4Ah+oZOFTE1NsX9INgR3FchSZZbNZE8CFzjGO7IFq4BsiO7",
|
||||
"2PLIE3KUYe8twnJpRqLiawSpfE7JvJRt7NJMdgpiWYpx2SSKaH5MngfWbJ7SU9W67/L7OyaXfUP6UelO",
|
||||
"MBvdNdpdB3gBu6tP9/WxdCzqDDLrxu1bRjDVeajdFYmNpwvGefcXtxGcH3ocntsPiCvVklEpp6pBBlTP",
|
||||
"j5BCaihlwetpWusc7dyw50kpuJbOS7drgYXl8dAkNVQDoyUdUF9oYjKt8Lb6Xw0/TZJsU0F95VLWFeUJ",
|
||||
"I9mVz3M3UJuQfEbrK20vYxjLrj1nRrjR0I3KpFA61A00czvypW2po5QZZqg1dItTnVIKp4VotC5Po+EC",
|
||||
"S0nl9mWTh+AhKu0UezFvOq2S6f5CypnpGjH2EmXO72alX6HN75Dc9nDJueRr7HS5L59ZtN6/0FvAKbPZ",
|
||||
"rohiBfv6WnmtTDtNKHweeqzCPlsrr60Tn8kDatIS3+XeTq6rbWFqwqlJIEijfB4rSvJhOMVyiOQcaRF2",
|
||||
"4UyniUsO9XKPLDlDwHSwIhi4T9CsvuWyCvtKJDfyBLVmYurDOAz8WG0dV8tlegcK/ES7Cg/DHb38lB7G",
|
||||
"akgq5dGOmVv8HfbIe+whZJ5aqD3/h6Baxdb2ElGj4Et+ry/wKOIN1fNFtBab6iJAzCOAERO+HWN6IW+w",
|
||||
"e3ih1KDFq6QtvqQEXJq+juAmFhgN5LdF7mSXGrNH+2YfhqQDvEBDob08B+4yeJtPa/kaJnfZEkubIils",
|
||||
"hsrWvsyzUw4k4uRm4DZWouo8C/2vd4pmU3necocsQPMnUYXiwY3bgExvARmk/5ox1BuYyC5OV/16/UqN",
|
||||
"xxeQwgEGWonV2QvnB6Z1HoDswrRuzr0Pf+R1BV71Hxo+uFjhGNL8ZQIGF+b1O53eR1bPZ1XtQB9arIVV",
|
||||
"dUW5blCGH9V6EV5nV/aYz2s42vGX5r3mvwEAAP//ghXolIcVAAA=",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
// or error if failed to decode
|
||||
func decodeSpec() ([]byte, error) {
|
||||
zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, ""))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error base64 decoding spec: %s", err)
|
||||
}
|
||||
zr, err := gzip.NewReader(bytes.NewReader(zipped))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decompressing spec: %s", err)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
_, err = buf.ReadFrom(zr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decompressing spec: %s", err)
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
var rawSpec = decodeSpecCached()
|
||||
|
||||
// a naive cached of a decoded swagger spec
|
||||
func decodeSpecCached() func() ([]byte, error) {
|
||||
data, err := decodeSpec()
|
||||
return func() ([]byte, error) {
|
||||
return data, err
|
||||
}
|
||||
}
|
||||
|
||||
// Constructs a synthetic filesystem for resolving external references when loading openapi specifications.
|
||||
func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) {
|
||||
var res = make(map[string]func() ([]byte, error))
|
||||
if len(pathToFile) > 0 {
|
||||
res[pathToFile] = rawSpec
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// GetSwagger returns the Swagger specification corresponding to the generated code
|
||||
// in this file. The external references of Swagger specification are resolved.
|
||||
// The logic of resolving external references is tightly connected to "import-mapping" feature.
|
||||
// Externally referenced files must be embedded in the corresponding golang packages.
|
||||
// Urls can be supported but this task was out of the scope.
|
||||
func GetSwagger() (swagger *openapi3.T, err error) {
|
||||
var resolvePath = PathToRawSpec("")
|
||||
|
||||
loader := openapi3.NewLoader()
|
||||
loader.IsExternalRefsAllowed = true
|
||||
loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) {
|
||||
var pathToFile = url.String()
|
||||
pathToFile = path.Clean(pathToFile)
|
||||
getSpec, ok := resolvePath[pathToFile]
|
||||
if !ok {
|
||||
err1 := fmt.Errorf("path not found: %s", pathToFile)
|
||||
return nil, err1
|
||||
}
|
||||
return getSpec()
|
||||
}
|
||||
var specData []byte
|
||||
specData, err = rawSpec()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
swagger, err = loader.LoadFromData(specData)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
77
internal/swagger/api.go
Normal file
77
internal/swagger/api.go
Normal file
@ -0,0 +1,77 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||
)
|
||||
|
||||
//go:generate oapi-codegen --config api.yaml ../../openapi.yaml
|
||||
//go:generate oapi-codegen --config models.yaml ../../openapi.yaml
|
||||
|
||||
type commonController interface {
|
||||
// (GET /available)
|
||||
GetAvailablePayments(ctx echo.Context) error
|
||||
}
|
||||
|
||||
type yandexStatusController interface {
|
||||
// (POST /yandex/payment/status/canceled)
|
||||
SetPaymentStatusCanceled(ctx echo.Context) error
|
||||
|
||||
// (POST /yandex/payment/status/succeeded)
|
||||
SetPaymentStatusSucceeded(ctx echo.Context) error
|
||||
|
||||
// (POST /yandex/payment/status/waiting)
|
||||
SetPaymentStatusWaiting(ctx echo.Context) error
|
||||
|
||||
// (POST /yandex/refund/status/succeeded)
|
||||
SetRefundStatusSucceeded(ctx echo.Context) error
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
CommonController commonController
|
||||
YandexStatusController yandexStatusController
|
||||
}
|
||||
|
||||
type API struct {
|
||||
commonController commonController
|
||||
yandexStatusController yandexStatusController
|
||||
}
|
||||
|
||||
func New(deps Deps) (*API, errors.Error) {
|
||||
if deps.CommonController == nil {
|
||||
return nil, errors.NewWithMessage("CommonController in nil on <NewSwaggerAPI>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.YandexStatusController == nil {
|
||||
return nil, errors.NewWithMessage("YandexStatusController in nil on <NewSwaggerAPI>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &API{
|
||||
commonController: deps.CommonController,
|
||||
yandexStatusController: deps.YandexStatusController,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Common
|
||||
|
||||
func (receiver *API) GetAvailablePayments(ctx echo.Context) error {
|
||||
return receiver.commonController.GetAvailablePayments(ctx)
|
||||
}
|
||||
|
||||
// Status (Yandex)
|
||||
|
||||
func (receiver *API) SetYandexPaymentStatusCanceled(ctx echo.Context) error {
|
||||
return receiver.yandexStatusController.SetPaymentStatusCanceled(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) SetYandexPaymentStatusSucceeded(ctx echo.Context) error {
|
||||
return receiver.yandexStatusController.SetPaymentStatusSucceeded(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) SetYandexPaymentStatusWaiting(ctx echo.Context) error {
|
||||
return receiver.yandexStatusController.SetPaymentStatusWaiting(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) SetYandexRefundStatusSucceeded(ctx echo.Context) error {
|
||||
return receiver.yandexStatusController.SetRefundStatusSucceeded(ctx)
|
||||
}
|
6
internal/swagger/api.yaml
Normal file
6
internal/swagger/api.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
output: api.gen.go
|
||||
package: swagger
|
||||
generate:
|
||||
echo-server: true
|
||||
models: false
|
||||
embedded-spec: true
|
94
internal/swagger/models.gen.go
Normal file
94
internal/swagger/models.gen.go
Normal file
@ -0,0 +1,94 @@
|
||||
// Package swagger provides primitives to interact with the openapi HTTP API.
|
||||
//
|
||||
// Code generated by github.com/deepmap/oapi-codegen version v1.12.4 DO NOT EDIT.
|
||||
package swagger
|
||||
|
||||
// Defines values for PaymentStatus.
|
||||
const (
|
||||
Canceled PaymentStatus = "canceled"
|
||||
Pending PaymentStatus = "pending"
|
||||
Succeeded PaymentStatus = "succeeded"
|
||||
WaitingForCapture PaymentStatus = "waiting_for_capture"
|
||||
)
|
||||
|
||||
// Amount defines model for Amount.
|
||||
type Amount struct {
|
||||
// Currency Трехбуквенный код валюты в формате ISO-4217
|
||||
Currency string `json:"currency"`
|
||||
|
||||
// Value Сумма в выбранной валюте
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// PaymentStatus defines model for PaymentStatus.
|
||||
type PaymentStatus string
|
||||
|
||||
// Recipient defines model for Recipient.
|
||||
type Recipient struct {
|
||||
// AccountId Идентификатор магазина в ЮKassa
|
||||
AccountId string `json:"account_id"`
|
||||
|
||||
// GatewayId Идентификатор субаккаунта
|
||||
GatewayId string `json:"gateway_id"`
|
||||
}
|
||||
|
||||
// SetPaymentStatusRequest defines model for SetPaymentStatusRequest.
|
||||
type SetPaymentStatusRequest struct {
|
||||
// Event Событие, о котором уведомляет ЮKassa
|
||||
Event string `json:"event"`
|
||||
Object YandexPayment `json:"object"`
|
||||
|
||||
// Type Тип объекта. Фиксированное значение — notification (уведомление)
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// YandexPayment defines model for YandexPayment.
|
||||
type YandexPayment struct {
|
||||
Amount Amount `json:"amount"`
|
||||
|
||||
// CapturedAt Время подтверждения платежа
|
||||
CapturedAt *string `json:"captured_at,omitempty"`
|
||||
|
||||
// Confirmation Выбранный способ подтверждения платежа
|
||||
Confirmation *map[string]interface{} `json:"confirmation,omitempty"`
|
||||
|
||||
// CreatedAt Время создания заказа
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// Description Описание
|
||||
Description *string `json:"description,omitempty"`
|
||||
|
||||
// ExpiresAt Время, до которого вы можете бесплатно отменить или подтвердить платеж
|
||||
ExpiresAt *string `json:"expires_at,omitempty"`
|
||||
|
||||
// Id Идентификатор платежа в ЮKassa
|
||||
Id string `json:"id"`
|
||||
IncomeAmount *Amount `json:"income_amount,omitempty"`
|
||||
|
||||
// Paid Признак оплаты заказа
|
||||
Paid bool `json:"paid"`
|
||||
|
||||
// PaymentMethod Структура метода платежа (может отличаться от способа платежа)
|
||||
PaymentMethod *map[string]interface{} `json:"payment_method,omitempty"`
|
||||
Recipient Recipient `json:"recipient"`
|
||||
|
||||
// Refundable Возможность провести возврат по API
|
||||
Refundable bool `json:"refundable"`
|
||||
RefundedAmount *Amount `json:"refunded_amount,omitempty"`
|
||||
Status PaymentStatus `json:"status"`
|
||||
|
||||
// Test Признак тестовой операции
|
||||
Test bool `json:"test"`
|
||||
}
|
||||
|
||||
// SetYandexPaymentStatusCanceledJSONRequestBody defines body for SetYandexPaymentStatusCanceled for application/json ContentType.
|
||||
type SetYandexPaymentStatusCanceledJSONRequestBody = SetPaymentStatusRequest
|
||||
|
||||
// SetYandexPaymentStatusSucceededJSONRequestBody defines body for SetYandexPaymentStatusSucceeded for application/json ContentType.
|
||||
type SetYandexPaymentStatusSucceededJSONRequestBody = SetPaymentStatusRequest
|
||||
|
||||
// SetYandexPaymentStatusWaitingJSONRequestBody defines body for SetYandexPaymentStatusWaiting for application/json ContentType.
|
||||
type SetYandexPaymentStatusWaitingJSONRequestBody = SetPaymentStatusRequest
|
||||
|
||||
// SetYandexRefundStatusSucceededJSONRequestBody defines body for SetYandexRefundStatusSucceeded for application/json ContentType.
|
||||
type SetYandexRefundStatusSucceededJSONRequestBody = SetPaymentStatusRequest
|
4
internal/swagger/models.yaml
Normal file
4
internal/swagger/models.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
output: models.gen.go
|
||||
package: swagger
|
||||
generate:
|
||||
models: true
|
7
internal/utils/amount.go
Normal file
7
internal/utils/amount.go
Normal file
@ -0,0 +1,7 @@
|
||||
package utils
|
||||
|
||||
import "strconv"
|
||||
|
||||
func ConvertAmountToStringFloat(amount int64) string {
|
||||
return strconv.FormatFloat(float64(amount)/100, 'f', 2, 64)
|
||||
}
|
43
internal/utils/amount_test.go
Normal file
43
internal/utils/amount_test.go
Normal file
@ -0,0 +1,43 @@
|
||||
package utils_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/utils"
|
||||
)
|
||||
|
||||
func TestConvertAmountToStringFloat(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
amount int64
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "Успешная конвертация числа 10020 в 100.20",
|
||||
amount: 10020,
|
||||
expected: "100.20",
|
||||
},
|
||||
{
|
||||
name: "Успешная конвертация числа 10002 в 100.02",
|
||||
amount: 10002,
|
||||
expected: "100.02",
|
||||
},
|
||||
{
|
||||
name: "Успешная конвертация числа 12054 в 120.54",
|
||||
amount: 12054,
|
||||
expected: "120.54",
|
||||
},
|
||||
{
|
||||
name: "Успешная конвертация числа 198531 в 1985.31",
|
||||
amount: 198531,
|
||||
expected: "1985.31",
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
assert.Equal(t, testCase.expected, utils.ConvertAmountToStringFloat(testCase.amount))
|
||||
})
|
||||
}
|
||||
}
|
13
internal/utils/echotools/bind.go
Normal file
13
internal/utils/echotools/bind.go
Normal file
@ -0,0 +1,13 @@
|
||||
package echotools
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
func Bind[T any](ctx echo.Context) (*T, error) {
|
||||
item := new(T)
|
||||
|
||||
if err := ctx.Bind(item); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return item, nil
|
||||
}
|
19
internal/utils/uuid.go
Normal file
19
internal/utils/uuid.go
Normal file
@ -0,0 +1,19 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func GenerateUUID() (result string, err error) {
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
err = fmt.Errorf("recovered generateUUID error: %v", recovered)
|
||||
}
|
||||
}()
|
||||
|
||||
generatedUUID := uuid.New()
|
||||
|
||||
return generatedUUID.String(), nil
|
||||
}
|
15
internal/utils/yoomoney.go
Normal file
15
internal/utils/yoomoney.go
Normal file
@ -0,0 +1,15 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ConvertYoomoneySercetsToAuth(authType, storeID, secretKey string) string {
|
||||
credentials := fmt.Sprintf("%s:%s", storeID, secretKey)
|
||||
encoded := base64.StdEncoding.EncodeToString([]byte(credentials))
|
||||
trimedAuthType := strings.TrimSpace(authType)
|
||||
|
||||
return fmt.Sprintf("%s %s", trimedAuthType, encoded)
|
||||
}
|
22
internal/utils/yoomoney_test.go
Normal file
22
internal/utils/yoomoney_test.go
Normal file
@ -0,0 +1,22 @@
|
||||
package utils_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/utils"
|
||||
)
|
||||
|
||||
func TestConvertYoomoneySercetsToAuth(t *testing.T) {
|
||||
t.Run("Успешная конвертация секретов в base64 используя метод Basic", func(t *testing.T) {
|
||||
assert.Equal(t, "Basic aWQ6c2VjcmV0", utils.ConvertYoomoneySercetsToAuth("Basic", "id", "secret"))
|
||||
})
|
||||
|
||||
t.Run("Успешная конвертация секретов в base64 используя метод Bearer", func(t *testing.T) {
|
||||
assert.Equal(t, "Bearer aWQ6c2VjcmV0", utils.ConvertYoomoneySercetsToAuth("Bearer", "id", "secret"))
|
||||
})
|
||||
|
||||
t.Run("Успешная конвертация секретов в base64 используя метод Basic, в котором лишние пробелы", func(t *testing.T) {
|
||||
assert.Equal(t, "Basic aWQ6c2VjcmV0", utils.ConvertYoomoneySercetsToAuth("Basic ", "id", "secret"))
|
||||
})
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: treasurer
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: treasurer
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: treasurer
|
||||
tier: backend
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: regcred
|
||||
containers:
|
||||
- name: treasurer
|
||||
image: 192.168.193.230:31320/treasurer
|
||||
imagePullPolicy: Always
|
||||
resources:
|
||||
requests:
|
||||
memory: 50Mi
|
||||
limits:
|
||||
memory: 1Gi
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
name: http
|
||||
restartPolicy: Always
|
@ -1,11 +0,0 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: treasurer
|
||||
spec:
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: treasurer
|
10
main.go
10
main.go
@ -1,10 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bitbucket.org/skeris/treasurer/app"
|
||||
"github.com/skeris/appInit"
|
||||
)
|
||||
|
||||
func main() {
|
||||
appInit.Initialize(app.New, app.Options{})
|
||||
}
|
1
migrations/test/001_amocrm_insert.down.json
Normal file
1
migrations/test/001_amocrm_insert.down.json
Normal file
@ -0,0 +1 @@
|
||||
[{ "delete": "amocrm", "deletes": [{ "q": {} }] }]
|
85
migrations/test/001_amocrm_insert.up.json
Normal file
85
migrations/test/001_amocrm_insert.up.json
Normal file
@ -0,0 +1,85 @@
|
||||
[
|
||||
{
|
||||
"insert": "amocrm",
|
||||
"ordered": true,
|
||||
"documents": [
|
||||
{
|
||||
"amocrmId": "1",
|
||||
"userId": "1",
|
||||
"information": {
|
||||
"id": 30228997,
|
||||
"name": "ООО ПЕНА",
|
||||
"subdomain": "penadigital",
|
||||
"created_at": 1683680509,
|
||||
"created_by": 0,
|
||||
"updated_at": 1683680509,
|
||||
"updated_by": 0,
|
||||
"current_user_id": 8110726,
|
||||
"country": "RU",
|
||||
"customers_mode": "disabled",
|
||||
"is_unsorted_on": true,
|
||||
"is_loss_reason_enabled": true,
|
||||
"is_helpbot_enabled": false,
|
||||
"is_technical_account": true,
|
||||
"contact_name_display_order": 1,
|
||||
"amojo_id": "",
|
||||
"uuid": "",
|
||||
"version": 0,
|
||||
"_links": { "self": { "href": "https://penadigital.amocrm.ru/api/v4/account" } },
|
||||
"_embedded": {
|
||||
"amojo_rights": { "can_direct": false, "can_create_groups": false },
|
||||
"users_groups": null,
|
||||
"task_types": null,
|
||||
"entity_names": {
|
||||
"leads": {
|
||||
"ru": {
|
||||
"gender": "",
|
||||
"plural_form": {
|
||||
"dative": "",
|
||||
"default": "",
|
||||
"genitive": "",
|
||||
"accusative": "",
|
||||
"instrumental": "",
|
||||
"prepositional": ""
|
||||
},
|
||||
"singular_form": {
|
||||
"dative": "",
|
||||
"default": "",
|
||||
"genitive": "",
|
||||
"accusative": "",
|
||||
"instrumental": "",
|
||||
"prepositional": ""
|
||||
}
|
||||
},
|
||||
"en": {
|
||||
"singular_form": { "default": "" },
|
||||
"plural_form": { "default": "" },
|
||||
"gender": ""
|
||||
},
|
||||
"es": {
|
||||
"singular_form": { "default": "" },
|
||||
"plural_form": { "default": "" },
|
||||
"gender": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"datetime_settings": {
|
||||
"date_pattern": "",
|
||||
"short_date_pattern": "",
|
||||
"short_time_pattern": "",
|
||||
"date_formant": "",
|
||||
"time_format": "",
|
||||
"timezone": "",
|
||||
"timezone_offset": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"audit": {
|
||||
"createdAt": "2022-12-31T00:00:00.000Z",
|
||||
"updatedAt": "2022-12-31T00:00:00.000Z",
|
||||
"deleted": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
206
openapi.yaml
206
openapi.yaml
@ -4,11 +4,15 @@ info:
|
||||
description: |-
|
||||
Область отвественности сервиса - получить на вход сумму, которуб надо запросить, и список действий, который надо выполнить, в зависимости от события оплаты
|
||||
version: 1.0.0
|
||||
|
||||
tags:
|
||||
- name: pay
|
||||
|
||||
paths:
|
||||
/available
|
||||
|
||||
/available:
|
||||
get:
|
||||
operationId: getAvailablePayments
|
||||
description: метод для получения списка доступных вариантов для оплаты
|
||||
tags:
|
||||
- pay
|
||||
@ -22,82 +26,166 @@ paths:
|
||||
example: ["qiwi", "visa", "tinkoff"]
|
||||
items:
|
||||
type: string
|
||||
/invoice:
|
||||
|
||||
/yandex/payment/status/waiting:
|
||||
post:
|
||||
description: метод для создания запроса на оплату
|
||||
operationId: setYandexPaymentStatusWaiting
|
||||
description: Метод для установки статуса платежа "Ожидание"
|
||||
tags:
|
||||
- pay
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Request'
|
||||
$ref: '#/components/schemas/SetPaymentStatusRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: успешное создание платёжной ссылки
|
||||
description: Успешная установка статуса
|
||||
'500':
|
||||
description: Внутренняя ошибка
|
||||
|
||||
/yandex/payment/status/succeeded:
|
||||
post:
|
||||
operationId: setYandexPaymentStatusSucceeded
|
||||
description: Метод для установки статуса платежа "Успешно"
|
||||
tags:
|
||||
- pay
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
link:
|
||||
type: string
|
||||
example: "google.ru"
|
||||
'400':
|
||||
description: недостаточно данных
|
||||
$ref: '#/components/schemas/SetPaymentStatusRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Успешная установка статуса
|
||||
'500':
|
||||
description: порой бывает что платёжные решения глючат все сразу, поэтому приходится оповещать о том, что получится запрос только потом
|
||||
description: Внутренняя ошибка
|
||||
|
||||
/yandex/payment/status/canceled:
|
||||
post:
|
||||
operationId: setYandexPaymentStatusCanceled
|
||||
description: Метод для установки статуса платежа "Отменён"
|
||||
tags:
|
||||
- pay
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SetPaymentStatusRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Успешная установка статуса
|
||||
'500':
|
||||
description: Внутренняя ошибка
|
||||
|
||||
/yandex/refund/status/succeeded:
|
||||
post:
|
||||
operationId: setYandexRefundStatusSucceeded
|
||||
description: Метод для установки статуса возврата "Успешно"
|
||||
tags:
|
||||
- pay
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SetPaymentStatusRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Успешная установка статуса
|
||||
'500':
|
||||
description: Внутренняя ошибка
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Request:
|
||||
type: object
|
||||
properties:
|
||||
requester:
|
||||
type: string
|
||||
example: "asdf7as6df7a5f5asdf"
|
||||
description: айдишник юзера, создавшего запрос
|
||||
amount:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 10000
|
||||
description: количество денег в сотых долях валюты
|
||||
currency:
|
||||
type: string
|
||||
example: "rub"
|
||||
description: валюта, в которой юзер хочет запросить деньги. Если для такой валюты нет платёжного решения, через переменные окружения должна передаваться дефолтная валюта, которая будет использоваться в таком случае
|
||||
payway:
|
||||
type: string
|
||||
example: "qiwi"
|
||||
description: платёжный метод, который хочет использовать пользователь для пополнения баланса
|
||||
additional:
|
||||
type: string
|
||||
example: "+79885895677"
|
||||
description: некоторым платёжным решениям необходимы дополнительные данные, типа номера телефона или почты. Я пока не знаю, как сделать это красиво, пусть будет так
|
||||
on_accept:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Action'
|
||||
on_decline:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Action'
|
||||
on_timeout:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Action'
|
||||
Action:
|
||||
|
||||
SetPaymentStatusRequest:
|
||||
type: object
|
||||
required: [type, event, object]
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum: ["post", "get", "put", "delete", "patch"]
|
||||
description: это варианты запросов по сети. В последствии тут ещё появятся всякие варианты с отправкой смс, почты, оповещений в телегу и прочих методов доставки результата оплаты
|
||||
example: post
|
||||
target:
|
||||
description: Тип объекта. Фиксированное значение — notification (уведомление)
|
||||
example: "notification"
|
||||
event:
|
||||
$ref: '#/components/schemas/Event'
|
||||
object:
|
||||
$ref: '#/components/schemas/YandexPayment'
|
||||
|
||||
YandexPayment:
|
||||
type: object
|
||||
required: [id, status, amount, recipient, created_at, test, paid, refundable]
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: в случае с http запросами, это url на который надо сделать запрос
|
||||
example: "google.ru"
|
||||
data:
|
||||
description: Идентификатор платежа в ЮKassa
|
||||
example: "asdf7as6df7a5f5asdf"
|
||||
status:
|
||||
$ref: '#/components/schemas/PaymentStatus'
|
||||
amount:
|
||||
$ref: '#/components/schemas/Amount'
|
||||
income_amount:
|
||||
$ref: '#/components/schemas/Amount'
|
||||
recipient:
|
||||
$ref: '#/components/schemas/Recipient'
|
||||
description:
|
||||
type: string
|
||||
description: данные, которые надо передать. в условиях https запросов это json или query string
|
||||
example: "{\"some\":\"shit\"}"
|
||||
description: Описание
|
||||
example: "Описание"
|
||||
payment_method:
|
||||
type: object
|
||||
description: Структура метода платежа (может отличаться от способа платежа)
|
||||
captured_at:
|
||||
type: string
|
||||
description: Время подтверждения платежа
|
||||
expires_at:
|
||||
type: string
|
||||
description: Время, до которого вы можете бесплатно отменить или подтвердить платеж
|
||||
created_at:
|
||||
type: string
|
||||
description: Время создания заказа
|
||||
confirmation:
|
||||
type: object
|
||||
description: Выбранный способ подтверждения платежа
|
||||
test:
|
||||
type: boolean
|
||||
description: Признак тестовой операции
|
||||
refunded_amount:
|
||||
$ref: '#/components/schemas/Amount'
|
||||
paid:
|
||||
type: boolean
|
||||
description: Признак оплаты заказа
|
||||
refundable:
|
||||
type: boolean
|
||||
description: Возможность провести возврат по API
|
||||
|
||||
Amount:
|
||||
type: object
|
||||
required: [value, currency]
|
||||
properties:
|
||||
value:
|
||||
type: string
|
||||
description: Сумма в выбранной валюте
|
||||
example: "10.00"
|
||||
currency:
|
||||
type: string
|
||||
description: Трехбуквенный код валюты в формате ISO-4217
|
||||
example: "RUB"
|
||||
|
||||
Recipient:
|
||||
type: object
|
||||
required: [account_id, gateway_id]
|
||||
properties:
|
||||
account_id:
|
||||
type: string
|
||||
description: Идентификатор магазина в ЮKassa
|
||||
gateway_id:
|
||||
type: string
|
||||
description: Идентификатор субаккаунта
|
||||
|
||||
PaymentStatus:
|
||||
type: string
|
||||
enum: ["waiting_for_capture", "pending", "succeeded", "canceled"]
|
||||
|
||||
Event:
|
||||
type: string
|
||||
enum: ["payment.waiting_for_capture", "payment.succeeded", "payment.canceled", "refund.succeeded"]
|
46
ops/deploy
46
ops/deploy
@ -1,46 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
cd ..
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "################################################################"
|
||||
echo "#### BUILDING APP"
|
||||
echo "################################################################"
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
make build
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "################################################################"
|
||||
echo "#### BUILDING DOCKER IMAGE"
|
||||
echo "################################################################"
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
sudo docker build -t 192.168.193.230:31320/treasurer:latest .
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "################################################################"
|
||||
echo "#### BUILDING PUSH IMAGE"
|
||||
echo "################################################################"
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
sudo docker push 192.168.193.230:31320/treasurer
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "################################################################"
|
||||
echo "#### RELOAD PODS"
|
||||
echo "################################################################"
|
||||
echo ""
|
||||
echo ""
|
||||
# TODO: rolling-update
|
||||
cd ./k8s; kubectl apply -f ./deployment.yml; kubectl apply -f service.yml
|
||||
|
||||
|
||||
kubectl rollout restart deployment treasurer
|
@ -1,33 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
cd ..
|
||||
git checkout dev
|
||||
echo ""
|
||||
echo ""
|
||||
echo "################################################################"
|
||||
echo "#### BUILDING APP"
|
||||
echo "################################################################"
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
make build
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "################################################################"
|
||||
echo "#### BUILDING DOCKER IMAGE"
|
||||
echo "################################################################"
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
sudo docker build -t 192.168.193.154:31320/treasurer:latest . -f ./DockerfileStaging
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "################################################################"
|
||||
echo "#### BUILDING PUSH IMAGE"
|
||||
echo "################################################################"
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
sudo docker push 192.168.193.154:31320/treasurer
|
@ -1,3 +0,0 @@
|
||||
FROM scratch
|
||||
ADD test /
|
||||
CMD ["/test"]
|
168
payway/bt.go
168
payway/bt.go
@ -1,168 +0,0 @@
|
||||
package payway
|
||||
|
||||
import (
|
||||
"bitbucket.org/skeris/treasurer/dal"
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/fatih/structs"
|
||||
"sort"
|
||||
)
|
||||
|
||||
const UrlBt = "https://merchant.betatransfer.io/api"
|
||||
|
||||
type BetaTransfer struct {
|
||||
MongoID string
|
||||
Name string
|
||||
MerchantID string
|
||||
WalletID string
|
||||
Secret1 string // Request key
|
||||
Secret2 string // Response key
|
||||
Secret3 string // Wallet API Key
|
||||
PayoutTypeList []dal.PayoutType
|
||||
PaymentTypeList []dal.PayWayPayment
|
||||
}
|
||||
|
||||
func NewBt(ctx context.Context, conn *dal.MongoConnection) (*BetaTransfer, error) {
|
||||
bt, err := conn.GetPayWayByName(ctx, "BetaTransfer")
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
paymentList, err := conn.GetPayWayPaymentByPayWay(ctx, bt.ShortName)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BetaTransfer{
|
||||
MongoID: bt.ID,
|
||||
Name: bt.Name,
|
||||
MerchantID: bt.MerchantID,
|
||||
WalletID: bt.WalletID,
|
||||
Secret1: bt.Secret1,
|
||||
Secret2: bt.Secret2,
|
||||
PayoutTypeList: bt.PayoutTypeList,
|
||||
PaymentTypeList: paymentList,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (bt *BetaTransfer) GetMongoID() string {
|
||||
return bt.MongoID
|
||||
}
|
||||
|
||||
func (bt *BetaTransfer) GetName() string {
|
||||
return bt.Name
|
||||
}
|
||||
|
||||
func (bt *BetaTransfer) UpdateData(data *dal.PayWay) {
|
||||
bt.MongoID = data.ID
|
||||
bt.Name = data.MerchantID
|
||||
bt.MerchantID = data.MerchantID
|
||||
bt.Secret1 = data.Secret1
|
||||
bt.Secret2 = data.Secret2
|
||||
bt.Secret3 = data.Secret3
|
||||
}
|
||||
|
||||
func (bt *BetaTransfer) UpdatePayment(data []dal.PayWayPayment) {
|
||||
bt.PaymentTypeList = data
|
||||
}
|
||||
|
||||
func (bt *BetaTransfer) UpdatePayout(data []dal.PayoutType) {
|
||||
bt.PayoutTypeList = data
|
||||
}
|
||||
|
||||
type ReqPaymentListenerBt struct {
|
||||
Sign string
|
||||
Amount float64
|
||||
OrderId string
|
||||
UserComment string
|
||||
}
|
||||
|
||||
// GetPayoutTypeList - возвращает локальные способы вывода средств из кошелька
|
||||
func (bt *BetaTransfer) GetPayoutTypeList() []dal.PayoutType {
|
||||
return bt.PayoutTypeList
|
||||
}
|
||||
|
||||
// GetPayoutType - возвращает локальный указанный способ вывода средств, либо nil если не найдено
|
||||
func (bt *BetaTransfer) GetPayoutType(payoutType string) *dal.PayoutType {
|
||||
for _, v := range bt.PayoutTypeList {
|
||||
if v.ApiId == payoutType {
|
||||
return &v
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPaymentTypeList - возвращает локальные способы пополнения
|
||||
func (bt *BetaTransfer) GetPaymentTypeList() []dal.PayWayPayment {
|
||||
return bt.PaymentTypeList
|
||||
}
|
||||
|
||||
// GetPaymentType - возвращает локальный указанный способ пополнения, либо nil если не найдено
|
||||
func (bt *BetaTransfer) GetPaymentType(paymentType string) *dal.PayWayPayment {
|
||||
for _, v := range bt.PaymentTypeList {
|
||||
if v.ApiId == paymentType {
|
||||
return &v
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindPayoutType - возвращает локальный указанный способ вывода средств учитывая amount.
|
||||
// Возвращает nil если ничего не найдено
|
||||
func (bt *BetaTransfer) FindPayoutType(payoutType string, amount float64) *dal.PayoutType {
|
||||
for _, v := range bt.PayoutTypeList {
|
||||
if v.ApiId == payoutType && amount > v.Minimum && amount < v.Maximum {
|
||||
return &v
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// prepareData - сортирует структуру по имени поля, добавляет подпись и переводит в байты
|
||||
func (bt *BetaTransfer) prepareData(data interface{}) ([]byte, error) {
|
||||
s := structs.New(data)
|
||||
structMap := s.Map() // Преобразуем структуру в map
|
||||
|
||||
// Сортируем по ключу
|
||||
keys := make([]string, 0, len(structMap))
|
||||
for k := range structMap {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
sorted := map[string]interface{}{}
|
||||
var str string
|
||||
|
||||
for _, k := range keys {
|
||||
if structMap[k] != "" {
|
||||
sorted[s.Field(k).Tag("json")] = structMap[k]
|
||||
str += fmt.Sprintf("%v", structMap[k])
|
||||
}
|
||||
}
|
||||
|
||||
// Добавляем подпись
|
||||
sorted["sign"] = bt.createSign([]string{str})
|
||||
|
||||
// Переводим в байты
|
||||
return json.Marshal(sorted)
|
||||
}
|
||||
|
||||
// createSign - создает md5-подпись из указанного массива строк. В конец строки добавляет Secret2
|
||||
func (bt *BetaTransfer) createSign(s []string) string {
|
||||
var str string
|
||||
for _, v := range s {
|
||||
str += v
|
||||
}
|
||||
|
||||
str += bt.Secret2
|
||||
|
||||
h := md5.Sum([]byte(str))
|
||||
return fmt.Sprintf("%x", h)
|
||||
}
|
322
payway/bt_api.go
322
payway/bt_api.go
@ -1,322 +0,0 @@
|
||||
package payway
|
||||
|
||||
import (
|
||||
"bitbucket.org/skeris/treasurer/dal"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/rs/xid"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
//#region ========= Payment =========
|
||||
|
||||
type ReqCreatePaymentUrlBt struct {
|
||||
Amount string `json:"amount"` // Required
|
||||
Currency string `json:"currency"` // Required
|
||||
OrderId string `json:"orderId"` // Required
|
||||
PaymentSystem string `json:"paymentSystem,omitempty"`
|
||||
UrlResult string `json:"urlResult,omitempty"`
|
||||
UrlSuccess string `json:"urlSuccess,omitempty"`
|
||||
UrlFail string `json:"urlFail,omitempty"`
|
||||
Locale string `json:"locale,omitempty"`
|
||||
PayerPhone string `json:"payerPhone,omitempty"`
|
||||
PayerName string `json:"payerName,omitempty"`
|
||||
PayerEmail string `json:"payerEmail,omitempty"`
|
||||
PayerFirstName string `json:"payer_firstname,omitempty"`
|
||||
PayerLastName string `json:"payer_lastname,omitempty"`
|
||||
PayerPostCode string `json:"payer_postcode,omitempty"`
|
||||
PayerAddress string `json:"payer_address,omitempty"`
|
||||
Ip string `json:"ip,omitempty"`
|
||||
UserComment string `json:"user_comment"` // Returned in Callback
|
||||
Sign string `json:"sign"` // Required
|
||||
}
|
||||
|
||||
type RespCreatePaymentUrlBt struct {
|
||||
Status interface{} `json:"status"`
|
||||
Id int64 `json:"id"`
|
||||
Url string `json:"url"`
|
||||
UrlPayment string `json:"urlPayment"`
|
||||
}
|
||||
|
||||
// CreatePaymentUrl - создает ссылку для перевода средств на кошелек (пополнение счета клиента)
|
||||
func (bt *BetaTransfer) CreatePaymentUrl(amount, orderID, paymentType, currency, lang, email, phone, requesterID,
|
||||
userIP string) (string, error) {
|
||||
action := UrlBt + "/payment?token=" + bt.Secret1
|
||||
|
||||
data := ReqCreatePaymentUrlBt{
|
||||
Amount: amount,
|
||||
Currency: currency,
|
||||
OrderId: orderID,
|
||||
PaymentSystem: paymentType,
|
||||
UrlResult: "",
|
||||
UrlSuccess: "",
|
||||
UrlFail: "",
|
||||
Locale: lang,
|
||||
PayerPhone: phone,
|
||||
PayerName: "",
|
||||
PayerEmail: email,
|
||||
PayerFirstName: "",
|
||||
PayerLastName: "",
|
||||
PayerPostCode: "",
|
||||
PayerAddress: "",
|
||||
Ip: "",
|
||||
UserComment: requesterID,
|
||||
Sign: "",
|
||||
}
|
||||
|
||||
body, err := bt.prepareData(data)
|
||||
|
||||
fmt.Println("Request:", string(body))
|
||||
if err != nil {
|
||||
fmt.Println("MarshalErr:", err)
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
params.Add("amount", data.Amount)
|
||||
params.Add("currency", data.Currency)
|
||||
params.Add("orderId", xid.New().String())
|
||||
params.Add("paymentSystem", data.PaymentSystem)
|
||||
params.Add("locale", lang)
|
||||
params.Add("user_comment", orderID)
|
||||
json.Unmarshal(body, &data)
|
||||
params.Add("sign", data.Sign)
|
||||
|
||||
resp, err := http.PostForm(action, params)
|
||||
|
||||
fmt.Println("Status:", resp.Status)
|
||||
|
||||
var result RespCreatePaymentUrlBt
|
||||
bodyr, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Println(" ioutil: ", err)
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
|
||||
return "", errors.New("bad response: " + string(bodyr))
|
||||
}
|
||||
|
||||
err = json.Unmarshal(bodyr,&result)
|
||||
|
||||
if err != nil {
|
||||
log.Println(" json: ", err)
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
return result.Url, nil
|
||||
}
|
||||
|
||||
// PaymentListener - Обрабатывает результат перевода
|
||||
func (bt *BetaTransfer) PaymentListener(ctx context.Context,ip string, request interface{}, mc *dal.MongoConnection) error {
|
||||
data := request.(*ReqPaymentListenerBt)
|
||||
if data.Sign != fmt.Sprintf("%x",
|
||||
md5.Sum([]byte(fmt.Sprint(data.Amount)+data.OrderId+bt.Secret2))) {
|
||||
return errors.New(fmt.Sprintf("wrong sign: %v, %s, %s", data.Sign, data.OrderId, bt.Secret2))
|
||||
}
|
||||
|
||||
// Проверка существования платежа в БД
|
||||
payment, err := mc.GetPayment(ctx, data.UserComment)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if payment == nil {
|
||||
return errors.New("payment not found")
|
||||
}
|
||||
|
||||
// Проверка статуса платежа (должен быть open)
|
||||
//if payment.Status != "open" || {
|
||||
// return errors.New(fmt.Sprintf("payment have status: %v", payment.Status))
|
||||
//}
|
||||
|
||||
// Проверка суммы платежа
|
||||
//if data.Amount != payment.Amount {
|
||||
// return errors.New(fmt.Sprintf("wrong amount: %v", data.Amount))
|
||||
//}
|
||||
//
|
||||
//// Проверка RequesterID
|
||||
//if data.RequesterID != payment.RequesterID {
|
||||
// return errors.New(fmt.Sprintf("wrong us_requesterID: %v", data.RequesterID))
|
||||
//}
|
||||
|
||||
// Обновление статуса платежа в БД
|
||||
if payment.Status != "accepted" {
|
||||
err = mc.UpdatePaymentStatus(ctx, data.UserComment, "accepted")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bt *BetaTransfer) GetPaymentList() ([]dal.PayWayPayment, error) {
|
||||
//TODO: implement me
|
||||
return bt.GetPaymentTypeList(), nil
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ========= Payout =========
|
||||
|
||||
type ReqCreatePayoutBt struct {
|
||||
Amount string `json:"amount,omitempty"` // Required
|
||||
Currency string `json:"currency"` // Required
|
||||
OrderId string `json:"orderId"` // Required
|
||||
PaymentSystem string `json:"paymentSystem"` // Required
|
||||
UrlResult string `json:"urlResult,omitempty"`
|
||||
Address string `json:"address"` // Required. Purse
|
||||
Sign string `json:"sign"` // Required
|
||||
}
|
||||
|
||||
type RespCreatePayoutBt struct {
|
||||
Status string `json:"status"`
|
||||
Id int `json:"id"`
|
||||
PaymentSystem string `json:"paymentSystem"`
|
||||
OrderId string `json:"orderId"`
|
||||
OrderAmount string `json:"orderAmount"`
|
||||
OrderCurrency string `json:"orderCurrency"`
|
||||
PaymentAmount string `json:"paymentAmount"`
|
||||
PaymentCurrency string `json:"paymentCurrency"`
|
||||
Commission string `json:"commission"`
|
||||
CommissionCurrency string `json:"commissionCurrency"`
|
||||
}
|
||||
|
||||
// CreatePayout - выполняет запрос для вывода средств из кошелька (вывод средств со счета клиента).
|
||||
// В ответ получает RespCreatePayoutBt
|
||||
// purse - кошелек для вывода
|
||||
// amount - сумма для вывода
|
||||
// desc - описание/комментарий (OrderId)
|
||||
// exchange = 1 - отключить автообмен
|
||||
// currency - валюта для вывода
|
||||
func (bt *BetaTransfer) CreatePayout(amount, orderID, payoutType, currency, address string) (string, error) {
|
||||
action := UrlBt + "//withdrawal-payment?token=" + bt.Secret1
|
||||
payout := bt.GetPayoutType(payoutType)
|
||||
if currency == "" {
|
||||
currency = payout.Currency
|
||||
}
|
||||
|
||||
data := ReqCreatePayoutBt{
|
||||
Amount: amount,
|
||||
Currency: currency,
|
||||
OrderId: orderID,
|
||||
PaymentSystem: payoutType,
|
||||
UrlResult: "",
|
||||
Address: address,
|
||||
Sign: "",
|
||||
}
|
||||
|
||||
body, err := bt.prepareData(data)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("MarshalErr:", err)
|
||||
}
|
||||
|
||||
resp, err := http.Post(action, "application/json", bytes.NewReader(body))
|
||||
|
||||
defer func() {
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
fmt.Println("Status:", resp.Status)
|
||||
|
||||
var result RespCreatePayoutBt
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&result)
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
log.Println(" ioutil: ", err)
|
||||
}
|
||||
return "", errors.New("bad response: " + string(body))
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
return strconv.Itoa(result.Id), nil
|
||||
}
|
||||
|
||||
// PayoutListener - обрабатывает результат вывода
|
||||
func (bt *BetaTransfer) PayoutListener(ctx context.Context, ip string, request interface{}, mc *dal.MongoConnection) error {
|
||||
fmt.Println("bt.PayoutListener:", request)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bt *BetaTransfer) GetPayoutList() ([]dal.PayoutType, error) {
|
||||
//TODO: implement me
|
||||
return bt.GetPayoutTypeList(), nil
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ========= Wallet =========
|
||||
|
||||
type RespGetWalletBalanceBt struct {
|
||||
Account struct {
|
||||
LockWithdrawal bool `json:"lockWithdrawal"`
|
||||
LockAccount bool `json:"lockAccount"`
|
||||
AuthAt int `json:"authAt"`
|
||||
} `json:"account"`
|
||||
Balance map[string]string `json:"balance"`
|
||||
BalanceOnHold map[string]string `json:"balance_on_hold"`
|
||||
}
|
||||
|
||||
// GetWalletBalance - выполняет запрос чтобы узнать баланс кошелька
|
||||
func (bt *BetaTransfer) GetWalletBalance() (map[string]float64, error) {
|
||||
action := UrlBt + "/account-info"
|
||||
|
||||
params := url.Values{
|
||||
"token": {bt.Secret1},
|
||||
"sign": {bt.createSign([]string{bt.Secret1})},
|
||||
}
|
||||
|
||||
action += fmt.Sprintf("?%v", params.Encode())
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Get(action)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, errors.New(fmt.Sprintf("got bad status: %v", resp.Status))
|
||||
}
|
||||
|
||||
var response RespGetWalletBalanceBt
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result map[string]float64
|
||||
|
||||
for key, val := range response.Balance {
|
||||
if val == "" {
|
||||
val = "0.0"
|
||||
}
|
||||
|
||||
toFloat, err := strconv.ParseFloat(val, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[key] = toFloat
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
//#endregion
|
191
payway/fk.go
191
payway/fk.go
@ -1,191 +0,0 @@
|
||||
package payway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/skeris/treasurer/dal"
|
||||
"github.com/fatih/structs"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
//const AllowedIPs = "136.243.38.147 136.243.38.149 136.243.38.150 136.243.38.151 136.243.38.189"
|
||||
|
||||
type FreeKassa struct {
|
||||
MongoID string
|
||||
Name string
|
||||
ShortName string
|
||||
MerchantID string
|
||||
WalletID string
|
||||
Secret1 string // Request key
|
||||
Secret2 string // Response key
|
||||
Secret3 string // Wallet API Key
|
||||
PayoutTypeList []dal.PayoutType
|
||||
PaymentTypeList []dal.PayWayPayment
|
||||
}
|
||||
|
||||
func NewFk(ctx context.Context, conn *dal.MongoConnection) (*FreeKassa, error) {
|
||||
fmt.Println("NewFK0")
|
||||
fk, err := conn.GetPayWayByName(ctx, "FreeKassa")
|
||||
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
fk = &dal.PayWay{
|
||||
ID: "fk1",
|
||||
Name: "FreeKassa",
|
||||
ShortName: "fk",
|
||||
MerchantID: "20397",
|
||||
WalletID: "20397",
|
||||
Secret1: "+%H$+Jb$gNw<PbE",
|
||||
Secret2: "*}/^bkOCGq[C*Ss",
|
||||
Secret3: "db9f770bf1b400445fb9c7d82e59ba81",
|
||||
PayoutTypeList: []dal.PayoutType{},
|
||||
CreatedAt: time.Time{},
|
||||
UpdatedAt: time.Time{},
|
||||
}
|
||||
fk.ID, err = conn.InsertPayWay(ctx, *fk)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
paymentList, err := conn.GetPayWayPaymentByPayWay(ctx, fk.ShortName)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &FreeKassa{
|
||||
MongoID: fk.ID,
|
||||
Name: fk.Name,
|
||||
ShortName: fk.ShortName,
|
||||
MerchantID: fk.MerchantID,
|
||||
WalletID: fk.WalletID,
|
||||
Secret1: fk.Secret1,
|
||||
Secret2: fk.Secret2,
|
||||
Secret3: fk.Secret3,
|
||||
PayoutTypeList: fk.PayoutTypeList,
|
||||
PaymentTypeList: paymentList,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (fk *FreeKassa) GetMongoID() string {
|
||||
return fk.MongoID
|
||||
}
|
||||
|
||||
func (fk *FreeKassa) GetName() string {
|
||||
return fk.Name
|
||||
}
|
||||
|
||||
func (fk *FreeKassa) UpdateData(data *dal.PayWay) {
|
||||
fk.MongoID = data.ID
|
||||
fk.Name = data.MerchantID
|
||||
fk.MerchantID = data.MerchantID
|
||||
fk.Secret1 = data.Secret1
|
||||
fk.Secret2 = data.Secret2
|
||||
fk.Secret3 = data.Secret3
|
||||
}
|
||||
|
||||
func (fk *FreeKassa) UpdatePayment(data []dal.PayWayPayment) {
|
||||
fk.PaymentTypeList = data
|
||||
}
|
||||
|
||||
func (fk *FreeKassa) UpdatePayout(data []dal.PayoutType) {
|
||||
fk.PayoutTypeList = data
|
||||
}
|
||||
|
||||
// GetPayoutTypeList - возвращает локальные способы вывода средств из кошелька
|
||||
func (fk *FreeKassa) GetPayoutTypeList() []dal.PayoutType {
|
||||
return fk.PayoutTypeList
|
||||
}
|
||||
|
||||
// GetPayoutType - возвращает локальный указанный способ вывода средств, либо nil если не найдено
|
||||
func (fk *FreeKassa) GetPayoutType(payoutType string) *dal.PayoutType {
|
||||
for _, v := range fk.PayoutTypeList {
|
||||
if v.ApiId == payoutType {
|
||||
return &v
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPaymentTypeList - возвращает локальные способы пополнения
|
||||
func (fk *FreeKassa) GetPaymentTypeList() []dal.PayWayPayment {
|
||||
return fk.PaymentTypeList
|
||||
}
|
||||
|
||||
// GetPaymentType - возвращает локальный указанный способ пополнения, либо nil если не найдено
|
||||
func (fk *FreeKassa) GetPaymentType(paymentType string) *dal.PayWayPayment {
|
||||
for _, v := range fk.PaymentTypeList {
|
||||
if v.ApiId == paymentType {
|
||||
return &v
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindPayoutType - возвращает локальный указанный способ вывода средств учитывая amount.
|
||||
// Возвращает nil если ничего не найдено
|
||||
func (fk *FreeKassa) FindPayoutType(payoutType string, amount float64) *dal.PayoutType {
|
||||
for _, v := range fk.PayoutTypeList {
|
||||
if v.ApiId == payoutType && amount > v.Minimum && amount < v.Maximum {
|
||||
return &v
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// prepareData - сортирует структуру по имени поля, добавляет подпись и переводит в байты
|
||||
func (fk *FreeKassa) prepareData(data interface{}) ([]byte, error) {
|
||||
s := structs.New(data)
|
||||
structMap := s.Map() // Преобразуем структуру в map
|
||||
|
||||
// Сортируем по ключу
|
||||
keys := make([]string, 0, len(structMap))
|
||||
for k := range structMap {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
sorted := map[string]interface{}{}
|
||||
var arr []string
|
||||
|
||||
for _, k := range keys {
|
||||
if structMap[k] != "" {
|
||||
sorted[s.Field(k).Tag("json")] = structMap[k]
|
||||
arr = append(arr, fmt.Sprintf("%v", structMap[k]))
|
||||
}
|
||||
}
|
||||
|
||||
// Добавляем подпись
|
||||
sorted["signature"] = fk.createSign(arr)
|
||||
|
||||
// Переводим в байты
|
||||
return json.Marshal(sorted)
|
||||
}
|
||||
|
||||
// createSign - создает hmac_sha256 подпись по Secret1
|
||||
func (fk *FreeKassa) createSign(data []string) string {
|
||||
str := strings.Join(data, "|")
|
||||
|
||||
sign := hmac.New(sha256.New, []byte("45fb9c7d82e59ba81"))
|
||||
sign.Write([]byte(str))
|
||||
h := sign.Sum(nil)
|
||||
|
||||
return fmt.Sprintf("%x", h)
|
||||
}
|
620
payway/fk_api.go
620
payway/fk_api.go
@ -1,620 +0,0 @@
|
||||
package payway
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/skeris/treasurer/dal"
|
||||
)
|
||||
|
||||
const UrlFk = "https://api.freekassa.ru/v1"
|
||||
const PrivateKey = "SomePrivateKey1!" //16 byte
|
||||
|
||||
//#region ========= Payment =========
|
||||
|
||||
type ReqCreatePaymentUrlFk struct {
|
||||
ShopId int64 `json:"shopId"` // Required
|
||||
Nonce int64 `json:"nonce"` // Required Уникальный ID запроса, должен всегда быть больше предыдущего значения
|
||||
Signature string `json:"signature"` // Required
|
||||
PaymentId string `json:"paymentId"`
|
||||
I int64 `json:"i"` // Required. ID платежной системы. dal.PaymentType.ApiId
|
||||
Email string `json:"email"` // Required
|
||||
IP string `json:"ip"` // Required
|
||||
Amount float64 `json:"amount"` // Required
|
||||
Currency string `json:"currency"` // Required
|
||||
Tel string `json:"tel"`
|
||||
SuccessUrl string `json:"successUrl,omitempty"`
|
||||
FailureUrl string `json:"failureUrl,omitempty"`
|
||||
NotificationUrl string `json:"notificationUrl,omitempty"`
|
||||
}
|
||||
|
||||
type RespCreatePaymentUrlFk struct {
|
||||
Type string `json:"type"`
|
||||
OrderId int `json:"order_id"`
|
||||
OrderHash string `json:"order_hash"`
|
||||
Location string `json:"location"`
|
||||
}
|
||||
|
||||
// CreatePaymentUrl - создает ссылку для перевода средств на кошелек (пополнение счета клиента)
|
||||
func (fk *FreeKassa) CreatePaymentUrl(amount, orderID, paymentType, currency, lang, email, phone, requesterID,
|
||||
userIP string) (string,
|
||||
error) {
|
||||
action := UrlFk + "/orders/create"
|
||||
|
||||
shopID, err := strconv.ParseInt(fk.MerchantID, 10, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
apiId, err := strconv.ParseInt(paymentType, 10, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
amountFloat, err := strconv.ParseFloat(amount, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
data := ReqCreatePaymentUrlFk{
|
||||
ShopId: shopID,
|
||||
Nonce: time.Now().Unix(),
|
||||
Signature: "",
|
||||
PaymentId: orderID,
|
||||
I: apiId,
|
||||
Email: email,
|
||||
IP: userIP,
|
||||
Amount: amountFloat,
|
||||
Currency: currency,
|
||||
Tel: phone,
|
||||
SuccessUrl: "",
|
||||
FailureUrl: "",
|
||||
NotificationUrl: "",
|
||||
}
|
||||
|
||||
body, err := fk.prepareData(data)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := http.Post(action, "application/json", bytes.NewReader(body))
|
||||
|
||||
defer func() {
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
fmt.Println("Status:", resp.Status)
|
||||
|
||||
var result RespCreatePaymentUrlFk
|
||||
bodyR, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
log.Println(" ioutil: ", err)
|
||||
}
|
||||
fmt.Println("ERSPONSE", string(bodyR))
|
||||
|
||||
err = json.Unmarshal(bodyR, &result)
|
||||
if err != nil {
|
||||
log.Println(" JSONNNNNioutil: ", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 || err != nil {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
log.Println(" ioutil: ", err)
|
||||
}
|
||||
return "", errors.New("bad response: " + string(body))
|
||||
}
|
||||
|
||||
if result.Type != "success" {
|
||||
return "", errors.New(fmt.Sprintf("bad response: %v", result))
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
return result.Location, nil
|
||||
}
|
||||
|
||||
type ReqPaymentListenerFk struct {
|
||||
MerchantID string `schema:"MERCHANT_ID"`
|
||||
Amount float64 `schema:"AMOUNT"`
|
||||
IntId string `schema:"intid"`
|
||||
PaymentID string `schema:"MERCHANT_ORDER_ID"`
|
||||
PEmail string `schema:"P_EMAIL"`
|
||||
PPhone string `schema:"P_PHONE"`
|
||||
CurID string `schema:"CUR_ID"`
|
||||
Sign string `schema:"SIGN"`
|
||||
Comission string `schema:"commission"`
|
||||
PayerAccount string `schema:"payer_account"`
|
||||
RequesterID string `schema:"us_requesterID"`
|
||||
}
|
||||
|
||||
// PaymentListener - Обрабатывает результат перевода
|
||||
func (fk *FreeKassa) PaymentListener(ctx context.Context, ip string, request interface{}, mc *dal.MongoConnection) error {
|
||||
data := request.(*ReqPaymentListenerFk)
|
||||
|
||||
// Проверка IP - временно отключен, т.к. получает айпи из зиротира
|
||||
//if !strings.Contains(ip, AllowedIPs) {
|
||||
//return errors.New(fmt.Sprintf("this ip not allowed: %v", ip))
|
||||
//}
|
||||
|
||||
// Проверка подписи
|
||||
//fmt.Println("ORAAAA", fk.MerchantID+":"+fmt.Sprint(int64(data.Amount))+":"+fk.Secret2+":"+data.PaymentID)
|
||||
//fmt.Println("ORAAAA", md5.Sum([]byte(fk.MerchantID+":"+fmt.Sprint(int64(data.Amount))+":"+fk.Secret2+":"+data.PaymentID)))
|
||||
//fmt.Println("ORAAAA", fmt.Sprintf("%x",
|
||||
// md5.Sum([]byte(fk.MerchantID+":"+fmt.Sprint(int64(data.Amount))+":"+fk.Secret2+":"+data.PaymentID))))
|
||||
if data.Sign != fmt.Sprintf("%x",
|
||||
md5.Sum([]byte(fk.MerchantID+":"+fmt.Sprint(int64(data.Amount))+":*}/^bkOCGq[C*Ss:"+data.PaymentID))) {
|
||||
return errors.New(fmt.Sprintf("wrong sign: %v", data))
|
||||
}
|
||||
|
||||
// Проверка существования платежа в БД
|
||||
payment, err := mc.GetPayment(ctx, data.PaymentID)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if payment == nil {
|
||||
return errors.New("payment not found")
|
||||
}
|
||||
|
||||
// Проверка статуса платежа (должен быть open)
|
||||
if payment.Status != "open" {
|
||||
return errors.New(fmt.Sprintf("payment have status: %v", payment.Status))
|
||||
}
|
||||
|
||||
// Проверка суммы платежа
|
||||
//if data.Amount != payment.Amount {
|
||||
// return errors.New(fmt.Sprintf("wrong amount: %v", data.Amount))
|
||||
//}
|
||||
//
|
||||
//// Проверка RequesterID
|
||||
//if data.RequesterID != payment.RequesterID {
|
||||
// return errors.New(fmt.Sprintf("wrong us_requesterID: %v", data.RequesterID))
|
||||
//}
|
||||
|
||||
// Обновление статуса платежа в БД
|
||||
err = mc.UpdatePaymentStatus(ctx, data.PaymentID, "accepted")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ReqGetPaymentListFk struct {
|
||||
ShopId int64 `json:"shopId"` // Required
|
||||
Nonce int64 `json:"nonce"` // Required
|
||||
Signature string `json:"signature"` // Required
|
||||
}
|
||||
|
||||
type RespGetPaymentListFk struct {
|
||||
Type string `json:"type"`
|
||||
Currencies []struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Currency string `json:"currency"`
|
||||
IsEnabled int `json:"is_enabled"`
|
||||
IsFavorite int `json:"is_favorite"`
|
||||
} `json:"currencies"`
|
||||
}
|
||||
|
||||
// GetPaymentList - возвращает из API актуальный список доступных платежных систем
|
||||
func (fk *FreeKassa) GetPaymentList() ([]dal.PayWayPayment, error) {
|
||||
action := UrlFk + "/currencies"
|
||||
|
||||
shopID, err := strconv.ParseInt(fk.MerchantID, 10, 64)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nonce := time.Now().Unix()
|
||||
|
||||
data := ReqGetPaymentListFk{
|
||||
ShopId: shopID,
|
||||
Nonce: nonce,
|
||||
}
|
||||
|
||||
body, err := fk.prepareData(data)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := http.Post(action, "application/json", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
fmt.Println("FKAPIERR", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
fmt.Println("Status:", resp.Status, data)
|
||||
|
||||
var result RespGetPaymentListFk
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&result)
|
||||
|
||||
if resp.StatusCode != 200 || err != nil {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
log.Println(" ioutil: ", err)
|
||||
}
|
||||
return nil, errors.New("bad response: " + string(body))
|
||||
}
|
||||
|
||||
if result.Type != "success" {
|
||||
return nil, errors.New(fmt.Sprintf("bad response: %v", result))
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
var formatted []dal.PayWayPayment
|
||||
|
||||
for _, item := range result.Currencies {
|
||||
status := "active"
|
||||
|
||||
if item.IsEnabled == 0 {
|
||||
status = "inactive"
|
||||
}
|
||||
formatted = append(formatted, dal.PayWayPayment{
|
||||
ID: fmt.Sprintf("%v-%v", fk.ShortName, item.Id),
|
||||
Name: item.Name,
|
||||
Status: status,
|
||||
Currency: item.Currency,
|
||||
ApiId: strconv.Itoa(item.Id),
|
||||
Commission: 0,
|
||||
Minimum: 0,
|
||||
Maximum: 0,
|
||||
})
|
||||
}
|
||||
|
||||
return formatted, nil
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ========= Payout =========
|
||||
|
||||
type ReqCreatePayoutFk struct {
|
||||
ShopId int64 `json:"shopId"` // Required
|
||||
Nonce int64 `json:"nonce"` // Required Уникальный ID запроса, должен всегда быть больше предыдущего значения
|
||||
Signature string `json:"signature"` // Required
|
||||
PaymentId string `json:"paymentId"`
|
||||
I int64 `json:"i"` // Required. ID платежной системы. dal.PayoutType.ApiId
|
||||
Account string `json:"account"` // Required. Кошелек для зачисления средств
|
||||
Amount float64 `json:"amount"` // Required
|
||||
Currency string `json:"currency"` // Required
|
||||
}
|
||||
|
||||
type RespCreatePayoutFk struct {
|
||||
Type string `json:"type"`
|
||||
Data struct {
|
||||
Id int `json:"id"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
// CreatePayout - выполняет запрос для вывода средств из кошелька (вывод средств со счета клиента).
|
||||
// В ответ получает RespCreatePayoutFk
|
||||
|
||||
func (fk *FreeKassa) CreatePayout(amount, orderID, payoutType, currency, address string) (string, error) {
|
||||
action := UrlFk + "/withdrawals/create"
|
||||
|
||||
payout := fk.GetPayoutType(payoutType)
|
||||
if currency == "" {
|
||||
currency = payout.Currency
|
||||
}
|
||||
|
||||
shopID, err := strconv.ParseInt(fk.MerchantID, 10, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
apiId, err := strconv.ParseInt(payoutType, 10, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
amountFloat, err := strconv.ParseFloat(amount, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
data := ReqCreatePayoutFk{
|
||||
ShopId: shopID,
|
||||
Nonce: time.Now().Unix(),
|
||||
Signature: "",
|
||||
PaymentId: orderID,
|
||||
I: apiId,
|
||||
Account: address,
|
||||
Amount: amountFloat,
|
||||
Currency: currency,
|
||||
}
|
||||
|
||||
body, err := fk.prepareData(data)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := http.Post(action, "application/json", bytes.NewReader(body))
|
||||
|
||||
defer func() {
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
fmt.Println("Status:", resp.Status)
|
||||
|
||||
var result RespCreatePayoutFk
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&result)
|
||||
|
||||
if resp.StatusCode != 200 || err != nil {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
log.Println(" ioutil: ", err)
|
||||
}
|
||||
return "", errors.New("bad response: " + string(body))
|
||||
}
|
||||
|
||||
if result.Type != "success" {
|
||||
return "", errors.New(fmt.Sprintf("bad response: %v", result))
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
return strconv.Itoa(result.Data.Id), nil
|
||||
}
|
||||
|
||||
type ReqPayoutListenerFk struct {
|
||||
WalletID string `json:"wallet_id" schema:"wallet_id"`
|
||||
OrderID string `json:"order_id" schema:"order_id"`
|
||||
Status string `json:"status" schema:"status"`
|
||||
Amount float64 `json:"amount" schema:"amount"`
|
||||
UserOrderID string `json:"user_order_id" schema:"user_order_id"`
|
||||
Sign string `json:"sign" schema:"sign"`
|
||||
}
|
||||
|
||||
// PayoutListener - обрабатывает результат вывода
|
||||
func (fk *FreeKassa) PayoutListener(ctx context.Context, ip string, request interface{}, mc *dal.MongoConnection) error {
|
||||
data := request.(*ReqPayoutListenerFk)
|
||||
|
||||
// Проверка IP - временно отключен, т.к. получает айпи из зиротира
|
||||
//if !strings.Contains(ip, AllowedIPs) {
|
||||
//return errors.New(fmt.Sprintf("this ip not allowed: %v", ip))
|
||||
//}
|
||||
|
||||
// Проверка подписи
|
||||
if data.Sign != fk.createSign([]string{
|
||||
fk.WalletID,
|
||||
data.OrderID,
|
||||
data.UserOrderID,
|
||||
data.Status,
|
||||
fmt.Sprint(data.Amount),
|
||||
}) {
|
||||
return errors.New(fmt.Sprintf("wrong sign: %v", data.Sign))
|
||||
}
|
||||
|
||||
// Проверка существования платежа в БД
|
||||
payout, err := mc.GetPaymentByServiceID(ctx, data.OrderID, "false")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if payout == nil {
|
||||
return errors.New("payment not found")
|
||||
}
|
||||
|
||||
// Проверка статуса платежа (должен быть open)
|
||||
if payout.Status != "open" {
|
||||
return errors.New(fmt.Sprintf("payment have status: %v", payout.Status))
|
||||
}
|
||||
|
||||
// Проверка суммы платежа
|
||||
if data.Amount != payout.Amount {
|
||||
return errors.New(fmt.Sprintf("wrong amount: %v", data.Amount))
|
||||
}
|
||||
|
||||
// Обновление статуса платежа в БД
|
||||
|
||||
var newStatus string
|
||||
switch data.Status {
|
||||
case "1":
|
||||
newStatus = "accepted"
|
||||
case "9":
|
||||
newStatus = "declined"
|
||||
default:
|
||||
newStatus = ""
|
||||
}
|
||||
|
||||
err = mc.UpdatePaymentStatus(ctx, payout.ID, newStatus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ReqGetPayoutListFk struct {
|
||||
ShopId int64 `json:"shopId"` // Required
|
||||
Nonce int64 `json:"nonce"` // Required
|
||||
Signature string `json:"signature"` // Required
|
||||
}
|
||||
|
||||
type RespGetPayoutListFk struct {
|
||||
Type string `json:"type"`
|
||||
Currencies []struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Min float64 `json:"min"`
|
||||
Max float64 `json:"max"`
|
||||
Currency string `json:"currency"`
|
||||
CanExchange int `json:"can_exchange"`
|
||||
} `json:"currencies"`
|
||||
}
|
||||
|
||||
// GetPayoutList - возвращает из API актуальный список доступных платежных систем
|
||||
func (fk *FreeKassa) GetPayoutList() ([]dal.PayoutType, error) {
|
||||
action := UrlFk + "/withdrawals/currencies"
|
||||
|
||||
shopID, err := strconv.ParseInt(fk.MerchantID, 10, 64)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data := ReqGetPaymentListFk{
|
||||
ShopId: shopID,
|
||||
Nonce: time.Now().Unix(),
|
||||
Signature: "",
|
||||
}
|
||||
|
||||
body, err := fk.prepareData(data)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := http.Post(action, "application/json", bytes.NewReader(body))
|
||||
|
||||
defer func() {
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
fmt.Println("Status:", resp.Status)
|
||||
|
||||
var result RespGetPayoutListFk
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&result)
|
||||
|
||||
fmt.Println("StatuRR:", result, resp.StatusCode, err)
|
||||
|
||||
if resp.StatusCode != 200 || err != nil {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
fmt.Println(body)
|
||||
if err != nil {
|
||||
log.Println(" ioutil: ", err)
|
||||
}
|
||||
return nil, errors.New("bad response: " + string(body))
|
||||
}
|
||||
fmt.Println(result)
|
||||
|
||||
if result.Type != "success" {
|
||||
return nil, errors.New(fmt.Sprintf("bad response: %v", result))
|
||||
}
|
||||
|
||||
var formatted []dal.PayoutType
|
||||
|
||||
for _, item := range result.Currencies {
|
||||
formatted = append(formatted, dal.PayoutType{
|
||||
|
||||
Name: item.Name,
|
||||
IsEnabled: true,
|
||||
Currency: item.Currency,
|
||||
ApiId: strconv.Itoa(item.Id),
|
||||
Commission: 0,
|
||||
Minimum: item.Min,
|
||||
Maximum: item.Max,
|
||||
})
|
||||
}
|
||||
|
||||
return formatted, nil
|
||||
}
|
||||
|
||||
//#endregionn
|
||||
|
||||
//#region ========= Wallet =========
|
||||
|
||||
type ReqGetWalletBalanceFk struct {
|
||||
ShopId int64 `json:"shopId"` // Required
|
||||
Nonce int64 `json:"nonce"` // Required
|
||||
Signature string `json:"signature"` // Required
|
||||
}
|
||||
|
||||
type RespGetWalletBalanceFk struct {
|
||||
Type string `json:"type"`
|
||||
Balance []struct {
|
||||
Currency string `json:"currency"`
|
||||
Value float64 `json:"value"`
|
||||
} `json:"balance"`
|
||||
}
|
||||
|
||||
// GetWalletBalance - выполняет запрос чтобы узнать баланс кошелька
|
||||
// В ответ получает RespGetWalletBalanceFk
|
||||
func (fk *FreeKassa) GetWalletBalance() (map[string]float64, error) {
|
||||
action := UrlFk + "/balance"
|
||||
|
||||
shopID, err := strconv.ParseInt(fk.MerchantID, 10, 64)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data := ReqGetWalletBalanceFk{
|
||||
ShopId: shopID,
|
||||
Nonce: time.Now().Unix(),
|
||||
Signature: "",
|
||||
}
|
||||
|
||||
body, err := fk.prepareData(data)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := http.Post(action, "application/json", bytes.NewReader(body))
|
||||
|
||||
defer func() {
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
fmt.Println("Status:", resp.Status)
|
||||
|
||||
var result RespGetWalletBalanceFk
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&result)
|
||||
|
||||
if resp.StatusCode != 200 || err != nil {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
log.Println(" ioutil: ", err)
|
||||
}
|
||||
return nil, errors.New("bad response: " + string(body))
|
||||
}
|
||||
|
||||
if result.Type != "success" {
|
||||
return nil, errors.New(fmt.Sprintf("bad response: %v", result))
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
var formatted map[string]float64
|
||||
|
||||
for _, item := range result.Balance {
|
||||
formatted[item.Currency] = item.Value
|
||||
}
|
||||
|
||||
return formatted, nil
|
||||
|
||||
}
|
||||
|
||||
//#endregion
|
@ -1,18 +0,0 @@
|
||||
package payway
|
||||
|
||||
type ErrorType struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
type InfoType struct {
|
||||
Info interface{}
|
||||
}
|
||||
|
||||
type ErrorQueueWorker ErrorType
|
||||
|
||||
type ErrorCreatePayout struct {
|
||||
ErrorType
|
||||
Url string
|
||||
}
|
||||
|
||||
type InfoQueueWorkerDone InfoType
|
393
payway/payway.go
393
payway/payway.go
@ -1,393 +0,0 @@
|
||||
package payway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/skeris/treasurer/dal"
|
||||
pw "bitbucket.org/skeris/treasurer/payway/payways"
|
||||
"bitbucket.org/skeris/treasurer/payway/payways/fk"
|
||||
"github.com/MarsherSusanin/pena_hub_packages_common/fastconfig"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/themakers/hlog"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type Payways struct {
|
||||
pws []*pw.Payway
|
||||
conn *mongo.Client
|
||||
db *mongo.Database
|
||||
collSvcs *mongo.Collection
|
||||
available map[string]createPW
|
||||
templates map[string]string
|
||||
errChan chan error
|
||||
}
|
||||
|
||||
const collServices = "services"
|
||||
|
||||
type createPW func() *pw.Payway
|
||||
|
||||
func New(
|
||||
ctx context.Context,
|
||||
conn *mongo.Client,
|
||||
db string,
|
||||
errChan chan error,
|
||||
available ...pw.PayWayI,
|
||||
) (*Payways, error) {
|
||||
a := map[string]createPW{}
|
||||
t := map[string]string{}
|
||||
|
||||
for _, p := range available {
|
||||
name := p.Type()
|
||||
a[name] = p.Copy
|
||||
|
||||
bts, err := json.Marshal(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t[name] = string(bts)
|
||||
}
|
||||
|
||||
d := conn.Database(db)
|
||||
|
||||
return &Payways{
|
||||
available: a,
|
||||
templates: t,
|
||||
conn: conn,
|
||||
db: d,
|
||||
errChan: errChan,
|
||||
collSvcs: d.Collection(collServices),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Payways) Init(ctx context.Context) error {
|
||||
if err := p.YieldPayways(ctx, p.ProcessPayways); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := p.WatchPayways(ctx, p.ProcessPayways); err != nil {
|
||||
p.errChan <- err
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Payways) Register(api *fiber.App) *fiber.App {
|
||||
api.Get("/services", p.getServices)
|
||||
return api
|
||||
}
|
||||
|
||||
func (p *Payways) getServices(c *fiber.Ctx) error {
|
||||
fmt.Println("getServices")
|
||||
return c.JSON(p.templates)
|
||||
}
|
||||
|
||||
func (p *Payways) ProcessPayways(d *pw.Payway) error {
|
||||
switch d.Svc {
|
||||
case "fk":
|
||||
way := fk.FreeKassa{}
|
||||
|
||||
if err := bson.Unmarshal(d.RawCredentials, &way); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.Credentials = way
|
||||
p.pws = append(p.pws, d)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Payways) WatchPayways(ctx context.Context, yield func(d *pw.Payway) error) error {
|
||||
cs, err := p.collSvcs.Watch(ctx, mongo.Pipeline{}, options.ChangeStream().SetFullDocument(options.UpdateLookup))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for cs.Next(ctx) {
|
||||
var change fastconfig.Change
|
||||
|
||||
if err := cs.Decode(&change); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var piece pw.Payway
|
||||
|
||||
if err := bson.Unmarshal(change.FullDocument, &piece); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := yield(&piece); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Payways) YieldPayways(ctx context.Context, yield func(d *pw.Payway) error) error {
|
||||
cur, err := p.collSvcs.Find(ctx, bson.M{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for cur.Next(ctx) {
|
||||
var piece pw.Payway
|
||||
|
||||
if err := cur.Decode(&piece); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := yield(&piece); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type PaywayAPI interface {
|
||||
GetWallet() error
|
||||
CreateInvoice() error
|
||||
CreatePayout() error
|
||||
InvoiceListener() error
|
||||
PayoutListener() error
|
||||
GetInvoiceCurrencies() error
|
||||
GetPayoutCurrencies() error
|
||||
}
|
||||
|
||||
type LayerPayWay interface {
|
||||
GetMongoID() string
|
||||
|
||||
GetName() string
|
||||
|
||||
UpdateData(data *dal.PayWay)
|
||||
|
||||
UpdatePayment(data []dal.PayWayPayment)
|
||||
|
||||
UpdatePayout(data []dal.PayoutType)
|
||||
|
||||
// Payment
|
||||
|
||||
CreatePaymentUrl(amount, orderID, paymentType, currency, lang, email, phone, requesterID, userIP string) (string, error)
|
||||
|
||||
PaymentListener(ctx context.Context, ip string, request interface{}, mc *dal.MongoConnection) error
|
||||
|
||||
GetPaymentList() ([]dal.PayWayPayment, error)
|
||||
|
||||
GetPaymentTypeList() []dal.PayWayPayment
|
||||
|
||||
GetPaymentType(paymentType string) *dal.PayWayPayment
|
||||
|
||||
// Payout
|
||||
|
||||
CreatePayout(amount, orderID, payoutType, currency, address string) (string, error)
|
||||
|
||||
PayoutListener(ctx context.Context, ip string, request interface{}, mc *dal.MongoConnection) error
|
||||
|
||||
GetPayoutList() ([]dal.PayoutType, error)
|
||||
|
||||
GetPayoutType(payoutType string) *dal.PayoutType
|
||||
|
||||
FindPayoutType(payType string, amount float64) *dal.PayoutType
|
||||
|
||||
GetWalletBalance() (map[string]float64, error)
|
||||
}
|
||||
|
||||
type PayWay struct {
|
||||
mongo *dal.MongoConnection
|
||||
Cache
|
||||
*QueuePayout
|
||||
}
|
||||
|
||||
func NewPayWay(
|
||||
ctx context.Context,
|
||||
logger hlog.Logger,
|
||||
mongoPayWay, mongoTreasurer *dal.MongoConnection) (*PayWay, error) {
|
||||
|
||||
fk, err := NewFk(ctx, mongoPayWay)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bt, err := NewBt(ctx, mongoPayWay)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: пока заполняем всё это вручную, стоит ли автоматизировать?
|
||||
cache := Cache{
|
||||
"fk": fk,
|
||||
"bt": bt,
|
||||
}
|
||||
|
||||
queue := NewQueuePayout()
|
||||
|
||||
// Заполняем очередь значениями из бд
|
||||
ptList, err := mongoTreasurer.GetPaymentListByStatus(ctx, "open", "false")
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, payout := range ptList {
|
||||
queue.Enqueue(payout.ID)
|
||||
}
|
||||
|
||||
payWay := &PayWay{
|
||||
Cache: cache,
|
||||
QueuePayout: queue,
|
||||
mongo: mongoPayWay,
|
||||
}
|
||||
|
||||
worker := newQueueWorker(ctx, payWay, logger, mongoTreasurer)
|
||||
|
||||
// update workers
|
||||
|
||||
go payWay.WorkerUpdatePayment(ctx)
|
||||
|
||||
go payWay.WorkerUpdatePayout(ctx)
|
||||
|
||||
go worker.routine()
|
||||
|
||||
return payWay, nil
|
||||
}
|
||||
|
||||
type Cache map[string]LayerPayWay
|
||||
|
||||
func (c Cache) GetPayWayById(id string) LayerPayWay {
|
||||
for _, way := range c {
|
||||
fmt.Println("way:", way.GetMongoID())
|
||||
if id == way.GetMongoID() {
|
||||
return way
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Cache) GetPayWayListByPayoutType(payoutType string, amount float64) map[string]LayerPayWay {
|
||||
result := map[string]LayerPayWay{}
|
||||
|
||||
for name, pw := range c {
|
||||
pt := pw.FindPayoutType(payoutType, amount)
|
||||
if pt != nil {
|
||||
result[name] = pw
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (c Cache) GetPaymentList() (map[string][]dal.PayWayPayment, error) {
|
||||
result := map[string][]dal.PayWayPayment{}
|
||||
|
||||
for k, v := range c {
|
||||
arr, err := v.GetPaymentList()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("%v.GetPaymentListErr: %v \r\n", k, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result[k] = arr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (p PayWay) WorkerUpdatePayment(ctx context.Context) {
|
||||
for {
|
||||
for name, pw := range p.Cache {
|
||||
data, err := pw.GetPaymentList()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("worker.%v.GetPaymentListErr: %v \r\n", name, err)
|
||||
}
|
||||
|
||||
for k, item := range data {
|
||||
id := fmt.Sprintf("%v-%v", name, item.ApiId)
|
||||
data[k].ID = id
|
||||
|
||||
payment, err := p.mongo.GetPayWayPayment(ctx, id)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("worker.%v.GetPayWayPaymentByApiIdAndPayWay: %v \r\n", name, err)
|
||||
//payment.ID = xid.New().String()
|
||||
}
|
||||
|
||||
if payment == nil {
|
||||
payment = &dal.PayWayPayment{ID: id}
|
||||
}
|
||||
//if payment != nil {
|
||||
err = p.mongo.UpdatePayWayPayment(ctx, dal.PayWayPayment{
|
||||
ID: payment.ID,
|
||||
ApiId: item.ApiId,
|
||||
Name: item.Name,
|
||||
PayWay: name,
|
||||
Currency: item.Currency,
|
||||
Commission: item.Commission,
|
||||
Minimum: item.Minimum,
|
||||
Maximum: item.Maximum,
|
||||
Status: item.Status,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("worker.%v.GetPayWayPaymentByApiIdAndPayWay: %v \r\n", name, err)
|
||||
}
|
||||
//} else {
|
||||
// if err != nil {
|
||||
// fmt.Printf("worker.%v.GetPayWayPaymentByApiIdAndPayWay: %v \r\n", name, err)
|
||||
// }
|
||||
//}
|
||||
}
|
||||
pw.UpdatePayment(data)
|
||||
}
|
||||
|
||||
// Прерывание
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(10 * time.Minute): // Сладкий сон
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p PayWay) WorkerUpdatePayout(ctx context.Context) {
|
||||
for {
|
||||
for name, pw := range p.Cache {
|
||||
data, err := pw.GetPayoutList()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("worker.%v.GetPaymentListErr: %v \r\n", name, pw)
|
||||
}
|
||||
|
||||
fmt.Println("OTTO", name, err, data)
|
||||
pw.UpdatePayout(data)
|
||||
|
||||
if err := p.mongo.UpdatePayWay(ctx, dal.PayWay{
|
||||
ID: pw.GetMongoID(),
|
||||
PayoutTypeList: data,
|
||||
}); err != nil {
|
||||
fmt.Println("UpdatePayoutErr", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Прерывание
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(10 * time.Minute): // Сладкий сон
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
@ -1,329 +0,0 @@
|
||||
package fk
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const UrlFk = "https://api.freekassa.ru/v1"
|
||||
|
||||
type ReqCreateInvoice struct {
|
||||
ShopId int64 `json:"shopId"`
|
||||
Nonce int64 `json:"none"`
|
||||
Signature string `json:"signature"`
|
||||
PaymentId string `json:"paymentId"`
|
||||
I int64 `json:"i"`
|
||||
Email string `json:"email"`
|
||||
IP string `json:"ip"`
|
||||
Amount float64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
Tel string `json:"tel"`
|
||||
SuccessUrl string `json:"successUrl,omitempty"`
|
||||
FailureUrl string `json:"failureUrl,omitempty"`
|
||||
NotificationUrl string `json:"motificationUrl,omitempty"`
|
||||
}
|
||||
|
||||
type RespCreateInvoice struct {
|
||||
Type string `json:"type"`
|
||||
OrderId int `json:"order_id"`
|
||||
OrderHash string `json:"order_hash"`
|
||||
Location string `json:"location"`
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) CreatePaymentUrl(paymentType int64, amount float64, orderId, email, ip, currency, phone string) (string, error) {
|
||||
body, err := pw.create(&ReqCreateInvoice{
|
||||
ShopId: pw.ShopId,
|
||||
Nonce: time.Now().Unix(),
|
||||
PaymentId: orderId,
|
||||
I: paymentType,
|
||||
Email: email,
|
||||
IP: ip,
|
||||
Amount: amount,
|
||||
Currency: currency,
|
||||
Tel: phone,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := http.Post(UrlFk+"/orders/create", "application/json", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var result RespCreateInvoice
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if result.Type != "success" {
|
||||
return "", fmt.Errorf("create link bad response: %v", result)
|
||||
}
|
||||
|
||||
return result.Location, nil
|
||||
}
|
||||
|
||||
type ReqOrdersHistory struct {
|
||||
ShopId int64 `json:"id"`
|
||||
Nonce int64 `json:"nonce"`
|
||||
Signature string `json:"signature"`
|
||||
DateFrom string `json:"dateFrom"`
|
||||
DateTo string `json:"dateTo"`
|
||||
}
|
||||
|
||||
type RespOrdersHistory struct {
|
||||
Type string `json:"type"`
|
||||
Pages int64 `json:"pages"`
|
||||
Orders []Order `json:"orders"`
|
||||
}
|
||||
|
||||
type Order struct {
|
||||
MerchantOrderId string `json:"merchant_order_id"`
|
||||
FkOrderId int64 `json:"fk_order_id"`
|
||||
Amount float64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
Email string `json:"email"`
|
||||
Account string `json:"account"`
|
||||
Date string `json:"date"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) GetOrdersHistory() ([]Order, error) {
|
||||
var resp RespOrdersHistory
|
||||
|
||||
if err := pw.apiRequest("https://api.freekassa.ru/v1/orders", &pw.getOrders, &ReqOrdersHistory{
|
||||
ShopId: pw.ShopId,
|
||||
Nonce: time.Now().Unix(),
|
||||
}, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.Orders, nil
|
||||
}
|
||||
|
||||
type ReqGetWallet struct {
|
||||
ShopId int64 `json:"shopId"`
|
||||
Nonce int64 `json:"nonce"`
|
||||
Signature string `json:"signature"`
|
||||
}
|
||||
|
||||
type WalletResp struct {
|
||||
Type string `json:"type"`
|
||||
Balance []Wallet `json:"balance"`
|
||||
}
|
||||
|
||||
type Wallet struct {
|
||||
Currency string `json:"currency" bson:"cur"`
|
||||
Value string `json:"value" bson:"val"`
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) GetWallet() ([]Wallet, error) {
|
||||
var resp WalletResp
|
||||
if err := pw.apiRequest("https://api.freekassa.ru/v1/balance", &pw.wallet, &ReqGetWallet{
|
||||
ShopId: pw.ShopId,
|
||||
Nonce: time.Now().Unix(),
|
||||
}, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println("wallet", resp)
|
||||
|
||||
return resp.Balance, nil
|
||||
}
|
||||
|
||||
type CurreciesResp struct {
|
||||
Type string `json:"type"`
|
||||
Currencies []Currency `json:"currencies"`
|
||||
}
|
||||
|
||||
type Currency struct {
|
||||
Id int `json:"id" bson:"id"`
|
||||
Name string `json:"name" bson:"name"`
|
||||
Currency string `json:"currency" bson:"cur"`
|
||||
IsEnabled uint8 `json:"is_enabled" bson:"is_enabled"`
|
||||
IsFavourite uint8 `json:"is_favourite" bson:"is_fav"`
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) GetCurrencies() ([]Currency, error) {
|
||||
var resp CurreciesResp
|
||||
|
||||
if err := pw.apiRequest("https://api.freekassa.ru/v1/currencies", &pw.wallet, &ReqGetWallet{
|
||||
ShopId: pw.ShopId,
|
||||
Nonce: time.Now().Unix(),
|
||||
}, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println("currencies", resp)
|
||||
|
||||
return resp.Currencies, nil
|
||||
}
|
||||
|
||||
type ShopResp struct {
|
||||
Type string `json:"type"`
|
||||
Shops []Shop `json:"shops"`
|
||||
}
|
||||
|
||||
type Shop struct {
|
||||
Id int `json:"id" bson:"id"`
|
||||
Name string `json:"name" bson:"name"`
|
||||
Url string `json:"url" bson:"url"`
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) GetShops() ([]Shop, error) {
|
||||
var resp ShopResp
|
||||
|
||||
if err := pw.apiRequest("https://api.freekassa.ru/v1/shops", &pw.wallet, &ReqGetWallet{
|
||||
ShopId: pw.ShopId,
|
||||
Nonce: time.Now().Unix(),
|
||||
}, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println("shops", resp)
|
||||
|
||||
return resp.Shops, nil
|
||||
}
|
||||
|
||||
type WithdrawalCurrenciesResp struct {
|
||||
Type string `json:"type"`
|
||||
Currencies []WithdrawalCurrencie `json:"currencies"`
|
||||
}
|
||||
|
||||
type WithdrawalCurrencie struct {
|
||||
Id int `json:"id" bson:"id"`
|
||||
Name string `json:"name" bson:"name"`
|
||||
Min float64 `json:"min" bson:"min"`
|
||||
Max float64 `json:"max" bson:"max"`
|
||||
Currency string `json:"currency" bson:"cur"`
|
||||
CanExcahnge uint8 `json:"can_exchange" bson:"can_exch"`
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) GetWithdrawalCurrencies() ([]WithdrawalCurrencie, error) {
|
||||
var resp WithdrawalCurrenciesResp
|
||||
|
||||
if err := pw.apiRequest("https://api.freekassa.ru/v1/withdrawals/currencies", &pw.wallet, &ReqGetWallet{
|
||||
ShopId: pw.ShopId,
|
||||
Nonce: time.Now().Unix(),
|
||||
}, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println("withdrawals cur", resp)
|
||||
|
||||
return resp.Currencies, nil
|
||||
}
|
||||
|
||||
type Access struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) Accesable(id int) (bool, error) {
|
||||
var resp Access
|
||||
if err := pw.apiRequest(fmt.Sprintf("https://api.freekassa.ru/currencies/%d/status", id), &pw.wallet, &ReqGetWallet{
|
||||
ShopId: pw.ShopId,
|
||||
Nonce: time.Now().Unix(),
|
||||
}, &resp); err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if resp.Type != "success" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) apiRequest(url string, p *preparer, r, dest any) error {
|
||||
body, err := (*p)(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := http.Post(url, "application/json", bytes.NewBuffer(body))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return fmt.Errorf("status code: %d\nbad response: %s", resp.StatusCode, string(b))
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(dest); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) prepareData(shape any) func(data any) ([]byte, error) {
|
||||
var (
|
||||
sind []int
|
||||
indexes [][]int
|
||||
)
|
||||
|
||||
func() {
|
||||
var (
|
||||
fieldNames []string
|
||||
ind = map[string][]int{}
|
||||
)
|
||||
|
||||
for _, f := range reflect.VisibleFields(reflect.Indirect(reflect.ValueOf(shape)).Type()) {
|
||||
name := strings.Split(f.Tag.Get("json"), ",")[0]
|
||||
if name != "signature" {
|
||||
fieldNames = append(fieldNames, name)
|
||||
ind[name] = f.Index
|
||||
} else {
|
||||
sind = f.Index
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(fieldNames)
|
||||
|
||||
for _, i := range fieldNames {
|
||||
indexes = append(indexes, ind[i])
|
||||
}
|
||||
}()
|
||||
|
||||
return func(data any) ([]byte, error) {
|
||||
val := reflect.Indirect(reflect.ValueOf(data))
|
||||
|
||||
var forsign []string
|
||||
|
||||
for _, fn := range indexes {
|
||||
forsign = append(forsign, fmt.Sprint(val.FieldByIndex(fn)))
|
||||
}
|
||||
|
||||
val.FieldByIndex(sind).Set(reflect.ValueOf(pw.createSign([]byte(strings.Join(forsign, "|")))))
|
||||
|
||||
return json.Marshal(data)
|
||||
}
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) createSign(data []byte) string {
|
||||
sign := hmac.New(sha256.New, pw.byteKey)
|
||||
sign.Write(data)
|
||||
return fmt.Sprintf("%x", sign.Sum(nil))
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package fk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/themakers/bdd"
|
||||
)
|
||||
|
||||
func TestFk(t *testing.T) {
|
||||
fk := New("db9f770bf1b400445fb9c7d82e59ba81", 20397)
|
||||
bdd.Scenario(t, "sign creating and data preparing", func(t *testing.T, runid string) {
|
||||
bdd.Test(t, "prepare data", func() {
|
||||
fk.create(&ReqCreateInvoice{
|
||||
ShopId: 1,
|
||||
Nonce: 2,
|
||||
Signature: "q",
|
||||
PaymentId: "w",
|
||||
I: 3,
|
||||
Email: "e",
|
||||
IP: "r",
|
||||
Amount: 4.5,
|
||||
Currency: "t",
|
||||
Tel: "y",
|
||||
SuccessUrl: "u",
|
||||
FailureUrl: "i",
|
||||
NotificationUrl: "o",
|
||||
})
|
||||
fmt.Println(fk.GetWallet())
|
||||
fmt.Println(fk.GetCurrencies())
|
||||
fmt.Println(fk.GetShops())
|
||||
fmt.Println(fk.GetWithdrawalCurrencies())
|
||||
})
|
||||
})
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package fk
|
||||
|
||||
import (
|
||||
p "bitbucket.org/skeris/treasurer/payway/payways"
|
||||
)
|
||||
|
||||
type FreeKassa struct {
|
||||
Key string `json:"key"`
|
||||
ShopId int64 `json:"shopId"`
|
||||
|
||||
byteKey []byte
|
||||
create, wallet, getOrders preparer
|
||||
}
|
||||
|
||||
type preparer func(any) ([]byte, error)
|
||||
|
||||
func New(sk string, shid int64) *FreeKassa {
|
||||
fk := &FreeKassa{
|
||||
Key: sk,
|
||||
ShopId: shid,
|
||||
byteKey: []byte(sk),
|
||||
}
|
||||
|
||||
fk.create = fk.prepareData(&ReqCreateInvoice{})
|
||||
fk.wallet = fk.prepareData(&ReqGetWallet{})
|
||||
fk.getOrders = fk.prepareData(&ReqOrdersHistory{})
|
||||
|
||||
return fk
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) Type() string {
|
||||
return "fk"
|
||||
}
|
||||
|
||||
func (pw *FreeKassa) Copy() *p.Payway {
|
||||
return &p.Payway{
|
||||
Credentials: &FreeKassa{},
|
||||
}
|
||||
}
|
||||
|
||||
//func (pw *FreeKassa) MarshalJSON() ([]byte, error) {
|
||||
// return json.Marshal(&FreeKassa{})
|
||||
//}
|
@ -1,26 +0,0 @@
|
||||
package pw
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
type PayWayI interface {
|
||||
Type() string
|
||||
Copy() *Payway
|
||||
//MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
type Payway struct {
|
||||
PayWayI
|
||||
ID string `json:"id" bson:"_id"`
|
||||
Name string `json:"name" bson:"name"`
|
||||
Description string `json:"desc" bson:"desc"`
|
||||
Svc string `json:"svc" bson:"svc"`
|
||||
|
||||
RawCredentials bson.Raw `json:"-" bson:"credentials"`
|
||||
Credentials any `json:"cred" bson:"-"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at" bson:"created_at"`
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package payway
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/themakers/bdd"
|
||||
)
|
||||
|
||||
func TestPWs(t *testing.T) {
|
||||
//ctx := context.Background()
|
||||
bdd.Scenario(t, "add payways", func(t *testing.T, runid string) {
|
||||
bdd.Test(t, "create pwmanager", func() {
|
||||
//pm, err := New(ctx, &fk.FreeKassa{})
|
||||
//assert.NoError(t, err)
|
||||
fmt.Println("pws0")
|
||||
})
|
||||
})
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user