refactor: package paths
This commit is contained in:
parent
10f635cb67
commit
e3aad0718f
14
README.md
14
README.md
@ -1,12 +1,12 @@
|
|||||||
# customer
|
# treasurer
|
||||||
|
|
||||||
Сервис customer
|
Сервис платёжки
|
||||||
|
|
||||||
| Branch | Pipeline | Code coverage |
|
| Branch | Pipeline | Code coverage |
|
||||||
| ------------- |:-----------------:| --------------:|
|
| ------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
||||||
| master | [](https://penahub.gitlab.yandexcloud.net/external/treasurer/-/pipelines) | [](https://penahub.gitlab.yandexcloud.net/external/treasurer/-/pipelines) |
|
| 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) |
|
| 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) |
|
| dev | [](https://penahub.gitlab.yandexcloud.net/external/treasurer/-/pipelines) | [](https://penahub.gitlab.yandexcloud.net/external/treasurer/-/pipelines) |
|
||||||
|
|
||||||
## Переменные окружения приложения
|
## Переменные окружения приложения
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/walkerus/go-wiremock"
|
"github.com/walkerus/go-wiremock"
|
||||||
@ -8,33 +9,37 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
mocklient := wiremock.NewClient("http://localhost:8000")
|
mockClient := wiremock.NewClient("http://localhost:8080")
|
||||||
|
|
||||||
if err := mocklient.StubFor(wiremock.
|
if err := mockClient.StubFor(wiremock.
|
||||||
Post(wiremock.URLPathEqualTo("/payments")).
|
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(
|
WillReturnJSON(
|
||||||
&yandex.Payment{},
|
&yandex.Payment{
|
||||||
|
ID: "f32d71f4-214b-464b-94bb-f7b4d5299af0",
|
||||||
|
Status: yandex.PaymentStatusPending,
|
||||||
|
Amount: yandex.Amount{
|
||||||
|
Value: "150.00",
|
||||||
|
Currency: "RUB",
|
||||||
|
},
|
||||||
|
Confirmation: &yandex.ConfirmationRedirect{
|
||||||
|
Type: yandex.ConfirmationTypeRedirect,
|
||||||
|
ConfirmationURL: "https://yandex-redirect-url.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
map[string]string{"Content-Type": "application/json"},
|
map[string]string{"Content-Type": "application/json"},
|
||||||
200,
|
200,
|
||||||
).
|
).
|
||||||
AtPriority(1),
|
AtPriority(1),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
log.Fatal("failed to stub <create phone payments>: %w", err)
|
log.Fatal("failed to stub bankcard payment: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request := wiremock.NewRequest("post", wiremock.URLPathEqualTo("/payments"))
|
||||||
|
|
||||||
|
isVerified, err := mockClient.Verify(request, 0)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("failed to verify /payments request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(isVerified)
|
||||||
}
|
}
|
||||||
|
@ -2,69 +2,44 @@ version: "3.3"
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
treasurer-app:
|
treasurer-app:
|
||||||
|
container_name: treasurer-service
|
||||||
|
tty: true
|
||||||
build:
|
build:
|
||||||
context: ../../.
|
context: ../../.
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
target: test
|
target: test
|
||||||
environment:
|
environment:
|
||||||
- HTTP_HOST=0.0.0.0
|
- HTTP_HOST=0.0.0.0
|
||||||
- HTTP_PORT=8080
|
- HTTP_PORT=8085
|
||||||
- HTTP_DOMEN=http://localhost:8080
|
- HTTP_DOMEN=http://localhost:8080
|
||||||
|
|
||||||
- GRPC_HOST=0.0.0.0
|
- GRPC_HOST=0.0.0.0
|
||||||
- GRPC_PORT=8081
|
- GRPC_PORT=9085
|
||||||
|
|
||||||
- YOOMONEY_STORE_ID = id
|
- YOOMONEY_STORE_ID=id
|
||||||
- YOOMONEY_SECRET_KEY = secret
|
- YOOMONEY_SECRET_KEY=secret
|
||||||
|
|
||||||
- MONGO_HOST=mongo
|
- MONGO_HOST=mongo
|
||||||
- MONGO_PORT=27017
|
- MONGO_PORT=27017
|
||||||
- MONGO_USER=admin
|
- MONGO_USER=test
|
||||||
- MONGO_PASSWORD=admin
|
- MONGO_PASSWORD=test
|
||||||
- MONGO_DB_NAME=admin
|
- MONGO_DB_NAME=admin
|
||||||
- MONGO_AUTH=admin
|
- MONGO_AUTH=admin
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8085:8085
|
||||||
- 8081:8081
|
- 9085:9085
|
||||||
|
networks:
|
||||||
|
- dev
|
||||||
depends_on:
|
depends_on:
|
||||||
- migration
|
- treasurer-mock
|
||||||
networks:
|
|
||||||
- dev
|
|
||||||
|
|
||||||
migration:
|
treasurer-mock:
|
||||||
build:
|
container_name: treasurermock-container
|
||||||
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'
|
image: 'wiremock/wiremock:2.35.0'
|
||||||
ports:
|
ports:
|
||||||
- 8000:8080
|
- 8080:8080
|
||||||
networks:
|
networks:
|
||||||
- dev
|
- dev
|
||||||
depends_on:
|
|
||||||
- app
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
dev:
|
dev:
|
||||||
|
@ -7,9 +7,9 @@ import (
|
|||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/initialize"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/initialize"
|
||||||
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/interface/swagger"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/server"
|
"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/closer"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/pkg/mongo"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/pkg/mongo"
|
||||||
)
|
)
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const defaultHTTPCode = http.StatusInternalServerError
|
||||||
|
|
||||||
var httpStatuses = map[ErrorType]int{
|
var httpStatuses = map[ErrorType]int{
|
||||||
ErrInternalError: http.StatusInternalServerError,
|
ErrInternalError: http.StatusInternalServerError,
|
||||||
ErrInvalidArgs: http.StatusBadRequest,
|
ErrInvalidArgs: http.StatusBadRequest,
|
||||||
@ -21,7 +23,7 @@ func HTTP(ctx echo.Context, err Error) error {
|
|||||||
status, ok := httpStatuses[err.Type()]
|
status, ok := httpStatuses[err.Type()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ctx.JSON(http.StatusInternalServerError, models.ResponseErrorHTTP{
|
return ctx.JSON(http.StatusInternalServerError, models.ResponseErrorHTTP{
|
||||||
StatusCode: http.StatusInternalServerError,
|
StatusCode: defaultHTTPCode,
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package initialize
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/swagger"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/interface/swagger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewAPI(controllers *Controllers) (*swagger.API, errors.Error) {
|
func NewAPI(controllers *Controllers) (*swagger.API, errors.Error) {
|
||||||
|
@ -14,10 +14,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
yandexPaymentsMockURL = "http://mock:8080/payments"
|
yandexPaymentsMockURL = "http://treasurer-mock:8080/payments"
|
||||||
yandexPaymentsProdURL = "https://api.yookassa.ru/v3/payments"
|
yandexPaymentsProdURL = "https://api.yookassa.ru/v3/payments"
|
||||||
|
|
||||||
yandexWebhooksMockURL = "http://mock:8080/webhooks"
|
yandexWebhooksMockURL = "http://treasurer-mock:8080/webhooks"
|
||||||
yandexWebhooksProdURL = "https://api.yookassa.ru/v3/webhooks"
|
yandexWebhooksProdURL = "https://api.yookassa.ru/v3/webhooks"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models/yandex"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models/yandex"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/utils/echotools"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/pkg/echotools"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StatusService interface {
|
type StatusService interface {
|
||||||
@ -51,8 +51,9 @@ func NewYandexStatusController(deps YandexStatusControllerDeps) (*YandexStatusCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &YandexStatusController{
|
return &YandexStatusController{
|
||||||
logger: deps.Logger,
|
logger: deps.Logger,
|
||||||
statusService: deps.StatusService,
|
statusService: deps.StatusService,
|
||||||
|
callbackService: deps.CallbackService,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
224
internal/interface/swagger/api.gen.go
Normal file
224
internal/interface/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/interface/swagger/api.go
Normal file
77
internal/interface/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/interface/swagger/api.yaml
Normal file
6
internal/interface/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/interface/swagger/models.gen.go
Normal file
94
internal/interface/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/interface/swagger/models.yaml
Normal file
4
internal/interface/swagger/models.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
output: models.gen.go
|
||||||
|
package: swagger
|
||||||
|
generate:
|
||||||
|
models: true
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||||
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
|
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
|
||||||
@ -40,7 +41,7 @@ func NewGRPC(deps DepsGRPC) (*GRPC, errors.Error) {
|
|||||||
))
|
))
|
||||||
|
|
||||||
return &GRPC{
|
return &GRPC{
|
||||||
grpc: grpc.NewServer(grpcStreamInterceptor, grpcUnaryInterceptor),
|
grpc: grpc.NewServer(grpcStreamInterceptor, grpcUnaryInterceptor, grpc.ConnectionTimeout(5*time.Second)),
|
||||||
logger: deps.Logger,
|
logger: deps.Logger,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||||||
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/interface/swagger"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||||||
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/swagger"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DepsHTTP struct {
|
type DepsHTTP struct {
|
||||||
@ -45,8 +45,9 @@ func NewHTTP(deps DepsHTTP) (*HTTP, errors.Error) {
|
|||||||
server: &http.Server{
|
server: &http.Server{
|
||||||
Handler: echo,
|
Handler: echo,
|
||||||
MaxHeaderBytes: 1 << 20,
|
MaxHeaderBytes: 1 << 20,
|
||||||
ReadTimeout: 10 * time.Second,
|
ReadTimeout: 20 * time.Second,
|
||||||
WriteTimeout: 10 * time.Second,
|
WriteTimeout: 20 * time.Second,
|
||||||
|
IdleTimeout: 20 * time.Second,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
13
pkg/echotools/bind.go
Normal file
13
pkg/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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user