Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
87affc4241 | |||
8122d31c72 | |||
819d6233ac | |||
d8e5dd8822 | |||
16694d31be | |||
7dab765ac3 | |||
d78b475d2b | |||
6981eca42e | |||
3aac0570ec | |||
778f51189b | |||
654abc04c6 | |||
fb51df3e98 | |||
dfbff4d86b | |||
edf077736b | |||
1d51dfe8c2 | |||
f416b25a65 | |||
56cb72ed21 | |||
d0f441b4f9 | |||
09638a8ca7 | |||
fd59a0be68 | |||
c812e328b6 | |||
758f3a905a | |||
90fd259051 | |||
b605b6674f | |||
ee8b80c170 |
@ -7,7 +7,7 @@ GRPC_PORT=8081
|
||||
|
||||
YOOMONEY_STORE_ID=storeid
|
||||
YOOMONEY_SECRET_KEY=secret
|
||||
IS_MOCK=true
|
||||
IS_MOCK=false
|
||||
MOCK_SERVICE_HOST=http://treasurer-mock:8080
|
||||
YOOMONEY_WEBHOOKS_URL=http://treasurer-mock:8080/webhooks
|
||||
YOOMONEY_PAYMENTS_URL=http://treasurer-mock:8080/payments
|
||||
@ -17,4 +17,6 @@ MONGO_PORT=27017
|
||||
MONGO_USER=admin
|
||||
MONGO_PASSWORD=admin
|
||||
MONGO_DB_NAME=admin
|
||||
MONGO_AUTH=admin
|
||||
MONGO_AUTH=admin
|
||||
|
||||
MONGO_URL = mongodb://admin:admin@localhost:27017/?authSource=admin
|
@ -1,25 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"context"
|
||||
"fmt"
|
||||
"gitea.pena/PenaSide/treasurer/internal/app"
|
||||
"gitea.pena/PenaSide/treasurer/internal/initialize"
|
||||
"go.uber.org/zap"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logger, err := zap.NewProduction(zap.AddStacktrace(zap.DPanicLevel))
|
||||
logger, err := zap.NewProduction()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to init zap logger: %v", err)
|
||||
fmt.Printf("Failed to initialize logger: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
config, err := initialize.Configuration(".env.test")
|
||||
config, err := initialize.LoadConfig()
|
||||
if err != nil {
|
||||
logger.Fatal("failed to init config: %v", zap.Error(err))
|
||||
logger.Fatal("Failed to load config", zap.Error(err))
|
||||
}
|
||||
|
||||
if err := app.Run(config, logger); err != nil {
|
||||
logger.Fatal("failed to run app: %v", zap.Error(err))
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
if err = app.Run(ctx, *config, logger); err != nil {
|
||||
logger.Fatal("App exited with error", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
43
go.mod
43
go.mod
@ -1,56 +1,53 @@
|
||||
module gitea.pena/PenaSide/treasurer
|
||||
|
||||
go 1.20
|
||||
go 1.23.2
|
||||
|
||||
toolchain go1.23.9
|
||||
|
||||
require (
|
||||
github.com/getkin/kin-openapi v0.118.0
|
||||
gitea.pena/PenaSide/common v0.0.0-20250421103113-7e4b3ae9e1e0
|
||||
github.com/caarlos0/env/v8 v8.0.0
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/gofiber/fiber/v2 v2.52.8
|
||||
github.com/google/uuid v1.6.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.9.0
|
||||
github.com/walkerus/go-wiremock v0.0.0-20230813141957-44e2a700708c
|
||||
go.mongodb.org/mongo-driver v1.11.7
|
||||
go.mongodb.org/mongo-driver v1.13.1
|
||||
go.uber.org/zap v1.27.0
|
||||
google.golang.org/grpc v1.62.1
|
||||
google.golang.org/protobuf v1.33.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // 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.4 // 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.17.7 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/kr/pretty v0.3.1 // 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/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // 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/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // 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/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.21.0 // indirect
|
||||
golang.org/x/net v0.22.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
111
go.sum
111
go.sum
@ -1,6 +1,12 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
gitea.pena/PenaSide/common v0.0.0-20250421103113-7e4b3ae9e1e0 h1:+gvpAPo1+1WtCpA+QaCWNy4R9/cIERBBzrVSYrx7hNo=
|
||||
gitea.pena/PenaSide/common v0.0.0-20250421103113-7e4b3ae9e1e0/go.mod h1:91EuBCgcqgJ6mG36n2pds8sPwwfaJytLWOzY3h2YFKU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/caarlos0/env/v8 v8.0.0 h1:POhxHhSpuxrLMIdvTGARuZqR4Jjm8AYmoi/JKlcScs0=
|
||||
github.com/caarlos0/env/v8 v8.0.0/go.mod h1:7K4wMY9bH0esiXSSHlfHLX5xKGQMnkH5Fk4TDSSSzfo=
|
||||
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=
|
||||
@ -12,26 +18,15 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||
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-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/gofiber/fiber/v2 v2.52.8 h1:xl4jJQ0BV5EJTA2aWiKw/VddRpHrKeZLF0QPUxqn0x4=
|
||||
github.com/gofiber/fiber/v2 v2.52.8/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||
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=
|
||||
@ -45,23 +40,18 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
|
||||
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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
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.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
|
||||
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
@ -71,36 +61,24 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
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/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/sethvargo/go-envconfig v0.9.0 h1:Q6FQ6hVEeTECULvkJZakq3dZMeBQ3JUpcKMfPQbKMDE=
|
||||
@ -108,37 +86,24 @@ github.com/sethvargo/go-envconfig v0.9.0/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YI
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
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=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
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.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/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
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/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/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
|
||||
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/walkerus/go-wiremock v0.0.0-20230813141957-44e2a700708c h1:+grD3yL1MBZzsYLHx8drdzLjzLe0WLskqA3V9HW/qNI=
|
||||
github.com/walkerus/go-wiremock v0.0.0-20230813141957-44e2a700708c/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.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
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/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=
|
||||
@ -147,11 +112,12 @@ github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
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.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk=
|
||||
go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
@ -164,8 +130,8 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
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/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
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=
|
||||
@ -186,18 +152,17 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
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-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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -206,16 +171,13 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/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-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.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
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=
|
||||
@ -223,10 +185,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
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.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
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/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
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=
|
||||
@ -263,10 +224,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
|
||||
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.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
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.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
@ -4,25 +4,18 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"gitea.pena/PenaSide/common/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/internal/server/grpc"
|
||||
"gitea.pena/PenaSide/treasurer/internal/server/http"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/initialize"
|
||||
"gitea.pena/PenaSide/treasurer/internal/interface/swagger"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/server"
|
||||
"gitea.pena/PenaSide/treasurer/internal/worker"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/closer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
shutdownTimeout = 5 * time.Second
|
||||
)
|
||||
|
||||
func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
func Run(ctx context.Context, config initialize.Config, logger *zap.Logger) (appErr error) {
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
appErr = errors.New("recovered panic on application run")
|
||||
@ -30,22 +23,17 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
}
|
||||
}()
|
||||
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
mongoDB, connectionErr := mongo.Connect(ctx, &mongo.ConnectDeps{
|
||||
shutdownGroup := closer.NewCloserGroup()
|
||||
|
||||
mongoDB, err := 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)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed connection to db: %w", err)
|
||||
}
|
||||
|
||||
repositories, err := initialize.NewRepositories(initialize.RepositoriesDeps{
|
||||
@ -53,35 +41,34 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
Database: mongoDB,
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize repositories")
|
||||
return err
|
||||
}
|
||||
|
||||
clients, err := initialize.NewClients(initialize.ClientsDeps{
|
||||
Logger: logger,
|
||||
YoomoneyConfiguration: &config.Service.YoomomeyConfiguration,
|
||||
Logger: logger,
|
||||
Config: config,
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize clients")
|
||||
return err
|
||||
}
|
||||
|
||||
services, err := initialize.NewServices(initialize.ServicesDeps{
|
||||
Logger: logger,
|
||||
Repositories: *repositories,
|
||||
Clients: *clients,
|
||||
ConfigurationHTTP: &config.HTTP,
|
||||
Configuration: &config.Service,
|
||||
Logger: logger,
|
||||
Repositories: *repositories,
|
||||
Clients: *clients,
|
||||
Config: config,
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize services")
|
||||
return err
|
||||
}
|
||||
|
||||
workers, err := initialize.NewWorkers(initialize.WorkersDeps{
|
||||
Logger: logger,
|
||||
Services: *services,
|
||||
Logger: logger,
|
||||
Service: services.Mock,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize workers")
|
||||
return err
|
||||
}
|
||||
|
||||
controllers, err := initialize.NewControllers(initialize.ControllersDeps{
|
||||
@ -89,50 +76,50 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
Services: *services,
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize controllers")
|
||||
return err
|
||||
}
|
||||
|
||||
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,
|
||||
httpServer := http.NewServer(http.ServerConfig{
|
||||
Logger: logger,
|
||||
Controllers: []http.Controller{controllers.YandexStatusREST, controllers.PaymentRest},
|
||||
})
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize http server")
|
||||
}
|
||||
|
||||
httpServer.Register(api)
|
||||
|
||||
grpcServer, err := server.NewGRPC(server.DepsGRPC{Logger: logger})
|
||||
grpcServer, err := grpc.NewGRPC(logger)
|
||||
if err != nil {
|
||||
return err.Wrap("failed to initialize grpc server")
|
||||
return err
|
||||
}
|
||||
|
||||
grpcServer.Register(controllers.PaymentGRPC)
|
||||
|
||||
go httpServer.Run(&config.HTTP)
|
||||
go grpcServer.Run(&config.GRPC)
|
||||
go func() {
|
||||
if err := httpServer.Start(config.HttpURL); err != nil {
|
||||
logger.Error("Client server startup error", zap.Error(err))
|
||||
cancel()
|
||||
}
|
||||
}()
|
||||
|
||||
go grpcServer.Run(config.GrpcURL)
|
||||
go worker.Run(ctx, workers)
|
||||
|
||||
closer.Add(mongoDB.Client().Disconnect)
|
||||
closer.Add(httpServer.Stop)
|
||||
closer.Add(grpcServer.Stop)
|
||||
httpServer.ListRoutes()
|
||||
|
||||
shutdownGroup.Add(closer.CloserFunc(mongoDB.Client().Disconnect))
|
||||
shutdownGroup.Add(closer.CloserFunc(httpServer.Shutdown))
|
||||
shutdownGroup.Add(closer.CloserFunc(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)
|
||||
timeoutCtx, timeoutCancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer timeoutCancel()
|
||||
if err := shutdownGroup.Call(timeoutCtx); err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
logger.Error("Shutdown timed out", zap.Error(err))
|
||||
} else {
|
||||
logger.Error("Failed to shutdown services gracefully", zap.Error(err))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Info("Application has stopped")
|
||||
return nil
|
||||
}
|
||||
|
@ -4,12 +4,12 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/payment_callback"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
type CallbackClientDeps struct {
|
||||
@ -28,15 +28,15 @@ func NewCallbackClient(deps CallbackClientDeps) (*CallbackClient, errors.Error)
|
||||
return &CallbackClient{logger: deps.Logger}, nil
|
||||
}
|
||||
|
||||
func (receiver *CallbackClient) SendOnSuccess(ctx context.Context, host string, event *models.Event) errors.Error {
|
||||
func (c *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))
|
||||
c.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))
|
||||
c.logger.Error("failed to close connection on <SendOnSuccess> of <CallbackClient>", zap.Error(closeErr))
|
||||
}
|
||||
}()
|
||||
|
||||
@ -57,7 +57,7 @@ func (receiver *CallbackClient) SendOnSuccess(ctx context.Context, host string,
|
||||
Completed: event.Payment.Completed,
|
||||
},
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to send success callback on <SendOnSuccess> of <CallbackClient>",
|
||||
c.logger.Error("failed to send success callback on <SendOnSuccess> of <CallbackClient>",
|
||||
zap.Error(err),
|
||||
zap.String("host", host),
|
||||
zap.Any("event", event),
|
||||
@ -68,15 +68,15 @@ func (receiver *CallbackClient) SendOnSuccess(ctx context.Context, host string,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *CallbackClient) SendOnFailure(ctx context.Context, host string, event *models.Event) errors.Error {
|
||||
func (c *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))
|
||||
c.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))
|
||||
c.logger.Error("failed to close connection on <SendOnFailure> of <CallbackClient>", zap.Error(closeErr))
|
||||
}
|
||||
}()
|
||||
|
||||
@ -97,7 +97,7 @@ func (receiver *CallbackClient) SendOnFailure(ctx context.Context, host string,
|
||||
Completed: event.Payment.Completed,
|
||||
},
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to send failure callback on <SendOnFailure> of <CallbackClient>",
|
||||
c.logger.Error("failed to send failure callback on <SendOnFailure> of <CallbackClient>",
|
||||
zap.Error(err),
|
||||
zap.String("host", host),
|
||||
zap.Any("event", event),
|
81
internal/client/yandex.go
Normal file
81
internal/client/yandex.go
Normal file
@ -0,0 +1,81 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/utils"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/client"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type YandexClientDeps struct {
|
||||
Logger *zap.Logger
|
||||
YooMoneyStoreID string
|
||||
YooMoneySecretKey string
|
||||
YooMoneyWebhooksURL string
|
||||
YooMoneyPaymentsURL string
|
||||
}
|
||||
|
||||
type YandexClient struct {
|
||||
logger *zap.Logger
|
||||
yooMoneyStoreID string
|
||||
yooMoneySecretKey string
|
||||
yooMoneyWebhooksURL string
|
||||
yooMoneyPaymentsURL string
|
||||
}
|
||||
|
||||
func NewYandexClient(deps YandexClientDeps) (*YandexClient, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("Logger is nil on <NewYandexClient>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &YandexClient{
|
||||
logger: deps.Logger,
|
||||
yooMoneyStoreID: deps.YooMoneyStoreID,
|
||||
yooMoneySecretKey: deps.YooMoneySecretKey,
|
||||
yooMoneyWebhooksURL: deps.YooMoneyWebhooksURL,
|
||||
yooMoneyPaymentsURL: deps.YooMoneyPaymentsURL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *YandexClient) CreatePayment(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodType]) (*yandex.Payment, errors.Error) {
|
||||
return CreateYandexPayment(ctx, c.logger, request, c.yooMoneyPaymentsURL, idempotenceKey,
|
||||
utils.ConvertYoomoneySercetsToAuth("Basic", c.yooMoneyStoreID, c.yooMoneySecretKey))
|
||||
}
|
||||
|
||||
func (c *YandexClient) CreatePaymentB2B(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodB2B]) (*yandex.Payment, errors.Error) {
|
||||
return CreateYandexPayment(ctx, c.logger, request, c.yooMoneyPaymentsURL, idempotenceKey,
|
||||
utils.ConvertYoomoneySercetsToAuth("Basic", c.yooMoneyStoreID, c.yooMoneySecretKey))
|
||||
}
|
||||
|
||||
func (c *YandexClient) CreatePaymentBankCard(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodBankCard]) (*yandex.Payment, errors.Error) {
|
||||
return CreateYandexPayment(ctx, c.logger, request, c.yooMoneyPaymentsURL, idempotenceKey,
|
||||
utils.ConvertYoomoneySercetsToAuth("Basic", c.yooMoneyStoreID, c.yooMoneySecretKey))
|
||||
}
|
||||
|
||||
func CreateYandexPayment[T any](ctx context.Context, logger *zap.Logger, request *yandex.CreatePaymentRequest[T],
|
||||
url string, idempotenceKey string, auth string) (*yandex.Payment, errors.Error) {
|
||||
|
||||
response, err := client.Post[yandex.Payment, any](ctx, &client.RequestSettings{
|
||||
URL: url,
|
||||
Body: request,
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
"Idempotence-Key": idempotenceKey,
|
||||
"Authorization": auth,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error("failed to make request", zap.Error(err))
|
||||
return nil, errors.NewWithError(fmt.Errorf("failed to make request: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
if response.Error != nil {
|
||||
logger.Error("failed to create payment", zap.Any("response", response.Error))
|
||||
return nil, errors.NewWithMessage("failed to create payment", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return response.Body, nil
|
||||
}
|
126
internal/controller/grpc/payment.go
Normal file
126
internal/controller/grpc/payment.go
Normal file
@ -0,0 +1,126 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/payment_provider"
|
||||
"gitea.pena/PenaSide/treasurer/internal/utils"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type PaymentControllerDeps struct {
|
||||
Logger *zap.Logger
|
||||
PaymentProviders []payment_provider.PaymentProvider
|
||||
}
|
||||
|
||||
type PaymentController struct {
|
||||
logger *zap.Logger
|
||||
paymentProviders []payment_provider.PaymentProvider
|
||||
providerMap map[models.PaymentType][]payment_provider.PaymentProvider
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func NewPaymentController(deps PaymentControllerDeps) (*PaymentController, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("Logger in nil on <NewPaymentController>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if len(deps.PaymentProviders) == 0 {
|
||||
return nil, errors.NewWithMessage("No payment providers provided on <NewPaymentController>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
controller := &PaymentController{
|
||||
logger: deps.Logger,
|
||||
paymentProviders: deps.PaymentProviders,
|
||||
providerMap: make(map[models.PaymentType][]payment_provider.PaymentProvider),
|
||||
}
|
||||
|
||||
for _, provider := range deps.PaymentProviders {
|
||||
for _, method := range provider.GetSupportedPaymentMethods() {
|
||||
controller.providerMap[method] = append(controller.providerMap[method], provider)
|
||||
}
|
||||
}
|
||||
|
||||
return controller, nil
|
||||
}
|
||||
|
||||
func (r *PaymentController) getProviderForPaymentMethod(method models.PaymentType) (payment_provider.PaymentProvider, errors.Error) {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
|
||||
providers, exists := r.providerMap[method]
|
||||
if !exists || len(providers) == 0 {
|
||||
return nil, errors.NewWithMessage("no provider found for payment method", errors.ErrNotFound)
|
||||
}
|
||||
return providers[0], nil
|
||||
}
|
||||
|
||||
func (r *PaymentController) createPayment(ctx context.Context, paymentType models.PaymentType, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
provider, err := r.getProviderForPaymentMethod(paymentType)
|
||||
if err != nil {
|
||||
r.logger.Error("failed to get payment provider",
|
||||
zap.String("paymentMethod", string(paymentType)),
|
||||
zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment provider", err)
|
||||
}
|
||||
|
||||
request := map[string]string{
|
||||
"type": string(paymentType),
|
||||
"currency": in.MainSettings.Currency,
|
||||
"amount": fmt.Sprintf("%d", in.MainSettings.Amount),
|
||||
"callback_host_grpc": strings.Join(in.MainSettings.CallbackHostGRPC, ","),
|
||||
"return_url": in.MainSettings.ReturnURL,
|
||||
"user_id": in.MainSettings.UserID,
|
||||
"client_ip": in.MainSettings.ClientIP,
|
||||
"requisites": utils.ToJSON(yandex.Receipt{
|
||||
TaxSystemCode: 2,
|
||||
Customer: yandex.Customer{
|
||||
FullName: in.MainSettings.Customer.FullName,
|
||||
INN: in.MainSettings.Customer.INN,
|
||||
Email: in.MainSettings.Customer.Email,
|
||||
Phone: in.MainSettings.Customer.Phone,
|
||||
},
|
||||
Items: utils.ProtoItems2ReceiptItems(in.MainSettings.Items),
|
||||
}),
|
||||
}
|
||||
link, err := provider.CreateInvoice(ctx, request)
|
||||
if err != nil {
|
||||
r.logger.Error("failed to create payment",
|
||||
zap.String("provider", provider.GetName()),
|
||||
zap.Error(err))
|
||||
return nil, errors.GRPC("failed to create payment", err)
|
||||
}
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
||||
|
||||
func (r *PaymentController) GetPaymentLinkBankCard(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
r.logger.Info("f<GetPaymentLinkBankCard> of <PaymentController>", zap.Any("Customer", in.MainSettings.Customer))
|
||||
return r.createPayment(ctx, models.PaymentTypeBankCard, in)
|
||||
}
|
||||
|
||||
func (r *PaymentController) GetPaymentLinkYooMoney(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
return r.createPayment(ctx, models.PaymentTypeYoomoney, in)
|
||||
}
|
||||
|
||||
func (r *PaymentController) GetPaymentLinkTinkoff(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
return r.createPayment(ctx, models.PaymentTypeTinkoff, in)
|
||||
}
|
||||
|
||||
func (r *PaymentController) GetPaymentLinkSBP(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
return r.createPayment(ctx, models.PaymentTypeSBP, in)
|
||||
}
|
||||
|
||||
func (r *PaymentController) GetPaymentLinkSberPay(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
return r.createPayment(ctx, models.PaymentTypeSberPay, in)
|
||||
}
|
||||
|
||||
func (r *PaymentController) GetPaymentLinkSberbankB2B(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
return r.createPayment(ctx, models.PaymentTypeSberB2B, in)
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
package rest
|
||||
package http_controllers
|
||||
|
||||
import (
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type PaymentService interface {
|
||||
// GetAvailablePaymentMethods(context.Context) ([]models.PaymentType, errors.Error)
|
||||
// GetAvailablePaymentMethods(context.Context) ([]models.PaymentType, errors.Error)
|
||||
}
|
||||
|
||||
type CommonControllerDeps struct {
|
||||
@ -36,7 +35,7 @@ func NewCommonController(deps CommonControllerDeps) (*CommonController, errors.E
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *CommonController) GetAvailablePayments(ctx echo.Context) error {
|
||||
func (r *CommonController) GetAvailablePayments(ctx *fiber.Ctx) 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))
|
28
internal/controller/http_controllers/payment/payment.go
Normal file
28
internal/controller/http_controllers/payment/payment.go
Normal file
@ -0,0 +1,28 @@
|
||||
package payment
|
||||
|
||||
import (
|
||||
"gitea.pena/PenaSide/treasurer/internal/payment_provider"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type PaymentController struct {
|
||||
paymentProviders []payment_provider.PaymentProvider
|
||||
}
|
||||
|
||||
// todo нужно реализовать как сказал Миша, без создания отдельного пакета
|
||||
func NewPaymentController(paymentProviders []payment_provider.PaymentProvider) *PaymentController {
|
||||
return &PaymentController{
|
||||
paymentProviders: paymentProviders,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *PaymentController) Register(router fiber.Router) {
|
||||
// вебхуки для каждого провайдера
|
||||
for _, provider := range r.paymentProviders {
|
||||
provider.RegisterWebhookHandlers(router)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *PaymentController) Name() string {
|
||||
return ""
|
||||
}
|
15
internal/controller/http_controllers/yandex/route.go
Normal file
15
internal/controller/http_controllers/yandex/route.go
Normal file
@ -0,0 +1,15 @@
|
||||
package yandex
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
|
||||
func (r *YandexStatusController) Register(router fiber.Router) {
|
||||
router.Post("/yandex/payment/status/canceled", r.SetPaymentStatusCanceled)
|
||||
router.Post("/yandex/refund/status/succeeded", r.SetRefundStatusSucceeded)
|
||||
router.Post("/yandex/payment/status/succeeded", r.SetPaymentStatusSucceeded)
|
||||
router.Post("/yandex/payment/status/waiting", r.SetPaymentStatusWaiting)
|
||||
|
||||
}
|
||||
|
||||
func (r *YandexStatusController) Name() string {
|
||||
return ""
|
||||
}
|
126
internal/controller/http_controllers/yandex/yandex.go
Normal file
126
internal/controller/http_controllers/yandex/yandex.go
Normal file
@ -0,0 +1,126 @@
|
||||
package yandex
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitea.pena/PenaSide/treasurer/internal/service/callback"
|
||||
"gitea.pena/PenaSide/treasurer/internal/service/status"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"net/http"
|
||||
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type YandexStatusControllerDeps struct {
|
||||
Logger *zap.Logger
|
||||
StatusService *status.Service
|
||||
CallbackService *callback.Service
|
||||
}
|
||||
|
||||
type YandexStatusController struct {
|
||||
logger *zap.Logger
|
||||
statusService *status.Service
|
||||
callbackService *callback.Service
|
||||
}
|
||||
|
||||
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,
|
||||
callbackService: deps.CallbackService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *YandexStatusController) SetPaymentStatusCanceled(ctx *fiber.Ctx) error {
|
||||
var request yandex.WebhookNotification[yandex.Payment]
|
||||
if err := ctx.BodyParser(&request); err != nil {
|
||||
r.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 := r.statusService.SetStatusCanceled(ctx.Context(), request.Object.ID)
|
||||
if setStatusErr != nil {
|
||||
r.logger.Error("failed to set canceled payment status on <SetPaymentStatusCanceled> of <YandexStatusController>", zap.Error(setStatusErr))
|
||||
return errors.HTTP(ctx, setStatusErr)
|
||||
}
|
||||
|
||||
if err := r.callbackService.OnFailure(ctx.Context(), &models.Event{
|
||||
Key: string(request.Event),
|
||||
Message: "yandex send event: payment canceled",
|
||||
Payment: payment,
|
||||
}); err != nil {
|
||||
r.logger.Error("failed send success callback on <SetPaymentStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.SendStatus(http.StatusOK)
|
||||
}
|
||||
|
||||
func (r *YandexStatusController) SetPaymentStatusSucceeded(ctx *fiber.Ctx) error {
|
||||
var request yandex.WebhookNotification[yandex.Payment]
|
||||
if err := ctx.BodyParser(&request); err != nil {
|
||||
r.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 := r.statusService.SetStatusSuccess(ctx.Context(), request.Object.ID)
|
||||
if setStatusErr != nil {
|
||||
r.logger.Error("failed to set success payment status on <SetPaymentStatusSucceeded> of <YandexStatusController>", zap.Error(setStatusErr))
|
||||
return errors.HTTP(ctx, setStatusErr)
|
||||
}
|
||||
|
||||
if err := r.callbackService.OnSuccess(ctx.Context(), &models.Event{
|
||||
Key: string(request.Event),
|
||||
Message: "yandex send event: payment succeeded",
|
||||
Payment: payment,
|
||||
}); err != nil {
|
||||
r.logger.Error("failed send success callback on <SetPaymentStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.SendStatus(http.StatusOK)
|
||||
}
|
||||
|
||||
func (r *YandexStatusController) SetPaymentStatusWaiting(ctx *fiber.Ctx) error {
|
||||
var request yandex.WebhookNotification[yandex.Payment]
|
||||
if err := ctx.BodyParser(&request); err != nil {
|
||||
r.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 := r.statusService.SetStatusWaiting(ctx.Context(), request.Object.ID); err != nil {
|
||||
r.logger.Error("failed to set waiting payment status on <SetPaymentStatusWaiting> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.SendStatus(http.StatusOK)
|
||||
}
|
||||
|
||||
func (r *YandexStatusController) SetRefundStatusSucceeded(ctx *fiber.Ctx) error {
|
||||
var request yandex.WebhookNotification[yandex.Payment]
|
||||
if err := ctx.BodyParser(&request); err != nil {
|
||||
r.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 := r.statusService.SetStatusRefund(ctx.Context(), request.Object.ID); err != nil {
|
||||
r.logger.Error("failed to set payment status refund on <SetRefundStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.SendStatus(http.StatusOK)
|
||||
}
|
@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// todo rework errors package
|
||||
|
||||
type ErrorType error
|
||||
|
||||
var (
|
||||
@ -43,22 +45,22 @@ func NewWithMessage(message string, errorType ErrorType) Error {
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *customError) Error() string {
|
||||
return receiver.err.Error()
|
||||
func (e *customError) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
func (receiver *customError) Type() ErrorType {
|
||||
return receiver.errorType
|
||||
func (e *customError) Type() ErrorType {
|
||||
return e.errorType
|
||||
}
|
||||
|
||||
func (receiver *customError) Wrap(message string) Error {
|
||||
receiver.err = fmt.Errorf("%s: %w", message, receiver.err)
|
||||
func (e *customError) Wrap(message string) Error {
|
||||
e.err = fmt.Errorf("%s: %w", message, e.err)
|
||||
|
||||
return receiver
|
||||
return e
|
||||
}
|
||||
|
||||
func (receiver *customError) SetType(errorType ErrorType) Error {
|
||||
receiver.errorType = errorType
|
||||
func (e *customError) SetType(errorType ErrorType) Error {
|
||||
e.errorType = errorType
|
||||
|
||||
return receiver
|
||||
return e
|
||||
}
|
||||
|
@ -1,34 +1,29 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
const defaultHTTPCode = http.StatusInternalServerError
|
||||
const defaultHTTPCode = fiber.StatusInternalServerError
|
||||
|
||||
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,
|
||||
ErrInternalError: fiber.StatusInternalServerError,
|
||||
ErrInvalidArgs: fiber.StatusBadRequest,
|
||||
ErrNoAccess: fiber.StatusForbidden,
|
||||
ErrNotFound: fiber.StatusNotFound,
|
||||
ErrMethodNotImplemented: fiber.StatusNotImplemented,
|
||||
ErrConflict: fiber.StatusConflict,
|
||||
ErrInsufficientFunds: fiber.StatusPaymentRequired,
|
||||
}
|
||||
|
||||
func HTTP(ctx echo.Context, err Error) error {
|
||||
func HTTP(ctx *fiber.Ctx, err Error) error {
|
||||
status, ok := httpStatuses[err.Type()]
|
||||
if !ok {
|
||||
return ctx.JSON(http.StatusInternalServerError, models.ResponseErrorHTTP{
|
||||
StatusCode: defaultHTTPCode,
|
||||
Message: err.Error(),
|
||||
})
|
||||
status = defaultHTTPCode
|
||||
}
|
||||
|
||||
return ctx.JSON(status, models.ResponseErrorHTTP{
|
||||
return ctx.Status(status).JSON(models.ResponseErrorHTTP{
|
||||
StatusCode: status,
|
||||
Message: err.Error(),
|
||||
})
|
||||
|
@ -1,13 +0,0 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/interface/swagger"
|
||||
)
|
||||
|
||||
func NewAPI(controllers *Controllers) (*swagger.API, errors.Error) {
|
||||
return swagger.New(swagger.Deps{
|
||||
CommonController: controllers.CommonREST,
|
||||
YandexStatusController: controllers.YandexStatusREST,
|
||||
})
|
||||
}
|
@ -1,15 +1,14 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/client"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/interface/client"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type ClientsDeps struct {
|
||||
Logger *zap.Logger
|
||||
YoomoneyConfiguration *models.YoomomeyConfiguration
|
||||
Logger *zap.Logger
|
||||
Config Config
|
||||
}
|
||||
|
||||
type Clients struct {
|
||||
@ -24,8 +23,11 @@ func NewClients(deps ClientsDeps) (*Clients, errors.Error) {
|
||||
}
|
||||
|
||||
yandexClient, err := client.NewYandexClient(client.YandexClientDeps{
|
||||
Logger: deps.Logger,
|
||||
Configuration: deps.YoomoneyConfiguration,
|
||||
Logger: deps.Logger,
|
||||
YooMoneyStoreID: deps.Config.YooMoneyStoreID,
|
||||
YooMoneySecretKey: deps.Config.YooMoneySecretKey,
|
||||
YooMoneyWebhooksURL: deps.Config.YooMoneyWebhooksURL,
|
||||
YooMoneyPaymentsURL: deps.Config.YooMoneyPaymentsURL,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1,15 +1,27 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/env"
|
||||
"gitea.pena/PenaSide/common/mongo"
|
||||
"github.com/caarlos0/env/v8"
|
||||
)
|
||||
|
||||
func Configuration(path string) (*models.Config, error) {
|
||||
config, err := env.Parse[models.Config](path)
|
||||
if err != nil {
|
||||
type Config struct {
|
||||
HttpURL string `env:"HTTP_URL" envDefault:"0.0.0.0:8080"`
|
||||
HttpDomain string `env:"HTTP_DOMAIN" envDefault:"http://localhost:8080"`
|
||||
GrpcURL string `env:"GRPC_URL,required" envDefault:"localhost:9000"`
|
||||
YooMoneyStoreID string `env:"YOOMONEY_STORE_ID" envDefault:"storeid"`
|
||||
YooMoneySecretKey string `env:"YOOMONEY_SECRET_KEY" envDefault:"secret"`
|
||||
IsMock bool `env:"IS_MOCK" envDefault:"false"`
|
||||
MockServiceHost string `env:"MOCK_SERVICE_HOST" envDefault:"http://treasurer-mock:8080"`
|
||||
YooMoneyWebhooksURL string `env:"YOOMONEY_WEBHOOKS_URL" envDefault:"http://treasurer-mock:8080/webhooks"`
|
||||
YooMoneyPaymentsURL string `env:"YOOMONEY_PAYMENTS_URL" envDefault:"http://treasurer-mock:8080/payments"`
|
||||
Database mongo.Configuration
|
||||
}
|
||||
|
||||
func LoadConfig() (*Config, error) {
|
||||
var config Config
|
||||
if err := env.Parse(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return config, nil
|
||||
return &config, nil
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/controller/grpc"
|
||||
"gitea.pena/PenaSide/treasurer/internal/controller/http_controllers/payment"
|
||||
"gitea.pena/PenaSide/treasurer/internal/controller/http_controllers/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/interface/controller/grpc"
|
||||
"gitea.pena/PenaSide/treasurer/internal/interface/controller/rest"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type ControllersDeps struct {
|
||||
@ -13,21 +14,13 @@ type ControllersDeps struct {
|
||||
}
|
||||
|
||||
type Controllers struct {
|
||||
CommonREST *rest.CommonController
|
||||
YandexStatusREST *rest.YandexStatusController
|
||||
YandexStatusREST *yandex.YandexStatusController
|
||||
PaymentGRPC *grpc.PaymentController
|
||||
PaymentRest *payment.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{
|
||||
yandexStatusControllerREST, err := yandex.NewYandexStatusController(yandex.YandexStatusControllerDeps{
|
||||
Logger: deps.Logger,
|
||||
StatusService: deps.Services.Status,
|
||||
CallbackService: deps.Services.Callback,
|
||||
@ -37,16 +30,18 @@ func NewControllers(deps ControllersDeps) (*Controllers, errors.Error) {
|
||||
}
|
||||
|
||||
paymentControllerGRPC, err := grpc.NewPaymentController(grpc.PaymentControllerDeps{
|
||||
Logger: deps.Logger,
|
||||
PaymentService: deps.Services.Payment,
|
||||
Logger: deps.Logger,
|
||||
PaymentProviders: deps.Services.PaymentProviders,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
paymentControllerRest := payment.NewPaymentController(deps.Services.PaymentProviders)
|
||||
|
||||
return &Controllers{
|
||||
CommonREST: commonControllerREST,
|
||||
YandexStatusREST: yandexStatusControllerREST,
|
||||
PaymentGRPC: paymentControllerGRPC,
|
||||
PaymentRest: paymentControllerRest,
|
||||
}, nil
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/repository"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/interface/repository"
|
||||
)
|
||||
|
||||
type RepositoriesDeps struct {
|
||||
|
@ -1,22 +1,21 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/payment_provider"
|
||||
"gitea.pena/PenaSide/treasurer/internal/payment_provider/yoomoney"
|
||||
"gitea.pena/PenaSide/treasurer/internal/service/callback"
|
||||
"gitea.pena/PenaSide/treasurer/internal/service/mock"
|
||||
"gitea.pena/PenaSide/treasurer/internal/service/payment"
|
||||
"gitea.pena/PenaSide/treasurer/internal/service/status"
|
||||
"gitea.pena/PenaSide/treasurer/internal/service/webhook"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type ServicesDeps struct {
|
||||
Logger *zap.Logger
|
||||
Repositories Repositories
|
||||
Clients Clients
|
||||
ConfigurationHTTP *models.ConfigurationHTTP
|
||||
Configuration *models.ServiceConfiguration
|
||||
Logger *zap.Logger
|
||||
Repositories Repositories
|
||||
Clients Clients
|
||||
Config Config
|
||||
}
|
||||
|
||||
type Services struct {
|
||||
@ -24,8 +23,9 @@ type Services struct {
|
||||
Payment *payment.Service
|
||||
YandexPayment *payment.Yandex
|
||||
Status *status.Service
|
||||
YandexWebhook *webhook.Yandex
|
||||
Mock *mock.Service
|
||||
//YandexWebhook *webhook.Yandex
|
||||
Mock *mock.Service
|
||||
PaymentProviders []payment_provider.PaymentProvider
|
||||
}
|
||||
|
||||
func NewServices(deps ServicesDeps) (*Services, errors.Error) {
|
||||
@ -63,18 +63,19 @@ func NewServices(deps ServicesDeps) (*Services, errors.Error) {
|
||||
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
|
||||
}
|
||||
// todo не используется
|
||||
//yandexWebhookService, err := webhook.NewYandex(webhook.YandexDeps{
|
||||
// Logger: deps.Logger,
|
||||
// YandexWebhookClient: deps.Clients.Yandex,
|
||||
// HttpDomain: deps.Config.HttpDomain,
|
||||
//})
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
yoomoneyMockService, err := mock.NewYoomoneyMockService(mock.YoomoneyMockServiceDeps{
|
||||
Logger: deps.Logger,
|
||||
YoomoneyURL: &deps.Configuration.MockConfiguration.YoomomeyURL,
|
||||
Logger: deps.Logger,
|
||||
YooMoneyPaymentsURL: deps.Config.YooMoneyPaymentsURL,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -82,20 +83,36 @@ func NewServices(deps ServicesDeps) (*Services, errors.Error) {
|
||||
|
||||
mockService, err := mock.New(mock.Deps{
|
||||
Logger: deps.Logger,
|
||||
Enabled: deps.Configuration.MockConfiguration.IsMock,
|
||||
MockServiceHost: deps.Configuration.MockConfiguration.Host,
|
||||
Enabled: deps.Config.IsMock,
|
||||
MockServiceHost: deps.Config.MockServiceHost,
|
||||
YoomoneyMockService: yoomoneyMockService,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
yooMoneyProvider, err := yoomoney.New(yoomoney.Deps{
|
||||
Logger: deps.Logger,
|
||||
Config: &yoomoney.Config{
|
||||
StoreID: deps.Config.YooMoneyStoreID,
|
||||
SecretKey: deps.Config.YooMoneySecretKey,
|
||||
WebhooksURL: deps.Config.YooMoneyWebhooksURL,
|
||||
PaymentsURL: deps.Config.YooMoneyPaymentsURL,
|
||||
},
|
||||
Repository: deps.Repositories.Payment,
|
||||
CallbackService: callbackService,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Services{
|
||||
Callback: callbackService,
|
||||
Payment: paymentService,
|
||||
YandexPayment: yandexPaymentService,
|
||||
Status: statusService,
|
||||
YandexWebhook: yandexWebhookService,
|
||||
Mock: mockService,
|
||||
//YandexWebhook: yandexWebhookService,
|
||||
Mock: mockService,
|
||||
PaymentProviders: []payment_provider.PaymentProvider{yooMoneyProvider},
|
||||
}, nil
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
svc_mock "gitea.pena/PenaSide/treasurer/internal/service/mock"
|
||||
"gitea.pena/PenaSide/treasurer/internal/worker/mock"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type WorkersDeps struct {
|
||||
Logger *zap.Logger
|
||||
Services Services
|
||||
Logger *zap.Logger
|
||||
Service *svc_mock.Service
|
||||
}
|
||||
|
||||
type Workers struct {
|
||||
@ -18,7 +19,7 @@ type Workers struct {
|
||||
func NewWorkers(deps WorkersDeps) (*Workers, errors.Error) {
|
||||
mockWorker, err := mock.New(mock.WorkerDeps{
|
||||
Logger: deps.Logger,
|
||||
MockService: deps.Services.Mock,
|
||||
MockService: deps.Service,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1,107 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/utils"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/client"
|
||||
)
|
||||
|
||||
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) {
|
||||
receiver.logger.Info("fai<CreatePayment> of <YandexClient>", zap.Any("CRP",request))
|
||||
response, err := client.Post[yandex.Payment, any](ctx, &client.RequestSettings{
|
||||
URL: receiver.configuration.URL.Payments,
|
||||
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) {
|
||||
receiver.logger.Info("fai2<CreatePayment> of <YandexClient>", zap.Any("CRP",request))
|
||||
response, err := client.Post[yandex.Payment, any](ctx, &client.RequestSettings{
|
||||
URL: receiver.configuration.URL.Payments,
|
||||
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) {
|
||||
receiver.logger.Info("fai3<CreatePayment> of <YandexClient>", zap.Any("CRP",request))
|
||||
response, err := client.Post[yandex.Payment, any](ctx, &client.RequestSettings{
|
||||
URL: receiver.configuration.URL.Payments,
|
||||
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
|
||||
}
|
@ -1,205 +0,0 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/utils"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
)
|
||||
|
||||
type PaymentService interface {
|
||||
CreatePaymentBankCard(context.Context, *models.CreatePayment[yandex.Receipt]) (string, errors.Error)
|
||||
CreatePayment(context.Context, *models.CreatePayment[yandex.Receipt]) (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.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
receiver.logger.Info("f<GetPaymentLinkBankCard> of <PaymentController>", zap.Any("Customer", in.MainSettings.Customer))
|
||||
link, err := receiver.paymentService.CreatePaymentBankCard(ctx, &models.CreatePayment[yandex.Receipt]{
|
||||
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: yandex.Receipt{
|
||||
TaxSystemCode: 2,
|
||||
Customer: yandex.Customer{
|
||||
FullName: in.MainSettings.Customer.FullName,
|
||||
Email: in.MainSettings.Customer.Email,
|
||||
},
|
||||
Items: utils.ProtoItems2ReceiptItems(in.MainSettings.Items),
|
||||
|
||||
},
|
||||
})
|
||||
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[yandex.Receipt]{
|
||||
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,
|
||||
Requisites: yandex.Receipt{
|
||||
TaxSystemCode: 2,
|
||||
Customer: yandex.Customer{
|
||||
FullName: in.MainSettings.Customer.FullName,
|
||||
Email: in.MainSettings.Customer.Email,
|
||||
},
|
||||
Items: utils.ProtoItems2ReceiptItems(in.MainSettings.Items),
|
||||
|
||||
},
|
||||
})
|
||||
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) GetPaymentLinkTinkoff(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePayment(ctx, &models.CreatePayment[yandex.Receipt]{
|
||||
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,
|
||||
Requisites: yandex.Receipt{
|
||||
TaxSystemCode: 2,
|
||||
Customer: yandex.Customer{
|
||||
FullName: in.MainSettings.Customer.FullName,
|
||||
Email: in.MainSettings.Customer.Email,
|
||||
},
|
||||
Items: utils.ProtoItems2ReceiptItems(in.MainSettings.Items),
|
||||
|
||||
},
|
||||
})
|
||||
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[yandex.Receipt]{
|
||||
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,
|
||||
Requisites: yandex.Receipt{
|
||||
TaxSystemCode: 2,
|
||||
Customer: yandex.Customer{
|
||||
FullName: in.MainSettings.Customer.FullName,
|
||||
Email: in.MainSettings.Customer.Email,
|
||||
},
|
||||
Items: utils.ProtoItems2ReceiptItems(in.MainSettings.Items),
|
||||
|
||||
},
|
||||
})
|
||||
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) GetPaymentLinkSberPay(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePayment(ctx, &models.CreatePayment[yandex.Receipt]{
|
||||
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: yandex.Receipt{
|
||||
TaxSystemCode: 2,
|
||||
Customer: yandex.Customer{
|
||||
FullName: in.MainSettings.Customer.FullName,
|
||||
Email: in.MainSettings.Customer.Email,
|
||||
},
|
||||
Items: utils.ProtoItems2ReceiptItems(in.MainSettings.Items),
|
||||
|
||||
},
|
||||
})
|
||||
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) GetPaymentLinkSberbankB2B(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
||||
link, err := receiver.paymentService.CreatePayment(ctx, &models.CreatePayment[yandex.Receipt]{
|
||||
Type: models.PaymentTypeSberB2B,
|
||||
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: yandex.Receipt{
|
||||
TaxSystemCode: 2,
|
||||
Customer: yandex.Customer{
|
||||
FullName: in.MainSettings.Customer.FullName,
|
||||
Email: in.MainSettings.Customer.Email,
|
||||
},
|
||||
Items: utils.ProtoItems2ReceiptItems(in.MainSettings.Items),
|
||||
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLinkB2B> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to get payment link", err)
|
||||
}
|
||||
|
||||
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/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,
|
||||
callbackService: deps.CallbackService,
|
||||
}, 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 {
|
||||
fmt.Println("SUUUUUUUUUUUU0")
|
||||
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))
|
||||
}
|
||||
fmt.Println("SUUUUUUUUUUUU1", request)
|
||||
|
||||
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)
|
||||
}
|
||||
fmt.Println("SUUUUUUUUUUUU2", payment, 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)
|
||||
}
|
@ -1,225 +0,0 @@
|
||||
// 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+FWLbQwIwlpw2DeBbUhRF0EMDG0VRJIaxoVYOU4tkSMqJEQjQT9IEddAg",
|
||||
"QQ89FCnS9lxIsmXT+qFfYfYV+iTFzC4lUtrYVoHccmnlJbkz+33zfTObJ8zxa4HvCS+O2NoTFjn3RY3T",
|
||||
"zxs1v+7F+CsI/UCEsSto3amHofCcPfxdEZETukHs+h5bY/CnbMJAPoOe7MAQ+jCACUzkPpxYMIQUDi3o",
|
||||
"QxdG8hfZlvsW9C35FFLZhDF0ZRsG1q2Nb698fnX1OrOZeMxrwY5ga2z9u5vMZvFegH9Eceh626xhs12+",
|
||||
"UxeGHN7JDoxxR9wf+nIferIJXcwEUsxkmgIMCnFWyyvl8mKkhs1C8bDuhqLC1u7osPYMhc3pF/69B8KJ",
|
||||
"MbevdoVCTnj1Gn4V8L2a8OKVR9yNXW97q+qHWw4P4nqIe2VPo7rjCFERldyawz1H7NBSKKp1r5J7a9MA",
|
||||
"y2313UbM43qUT+E9oYVXwS9tlg8+DWqKsC4cN3CFqTS442DNbLkVAzG/wSEWhGxDIp9CAkMiPZVNC9mC",
|
||||
"A+jCMSQw0cz98w2PIm5ifpvH4hHfWzaKbMkO9KALQ1rs0EvdcwnPnakQ2sT7hogL+K+Lh3URGYASWYF8",
|
||||
"GooqW2OflGYyLGkNllQVNewswDmv/8C9inis4+NnKr1FkUICpxak0JM/wwCGiMKKBX8jWLIFiWxCSiJR",
|
||||
"ihlYcIykyOck5wQG1r/NXy3Pj92q63Dc1bokO6T2Q0hhDKPsxcsFfeW/OBd1emprnKYImDAvHnuxJKcu",
|
||||
"dhZ22usaWPokjcoWjw3YvUGDg7F8ZcEpGpps47llE45U2UGiHo2UocGRqcBs5vhe1Q1rCgpTlJxpkX3K",
|
||||
"FsaTLWTt/4SeweWEgsfnH49CHcMh5UA7H5NyUKPGIxV2Wtj4LZxCIltqtznfNTxc2F08DtxQROdkbVtY",
|
||||
"gdRrlOYhhQNc6GO3GUMKRzCgRgM9GBCmCq0JvoTfjDWSbfnSggRGkMyjfZg9zSFtynhZCywQVzTAGVQ8",
|
||||
"qlSv8+gL/O+16jX80xjbc/ya2Fq29ANuTPoP2YREeQAM0Td0qoipsSju+f6O4J7akmS5VRPxfb9i7NZt",
|
||||
"2cRpQbZlB0seeUKOUqy9eVguzUhUfI0gkc8pmZeyhVWaynZBLAt7XDaJIsy3tLPAmvW+RtaP+b0dk8u+",
|
||||
"If2odCeYja4a7a4DXMDq6tN7fTw6HuoUUuvG7VtGMFU81O6SxEbTYeCs94uTA/YP3brOrAfElc6S0lFO",
|
||||
"VIEM6Dw/QQKJ4ShzXk+dVedoZ4adJ6XgWjovXa4FFhbbQ4PUUPWNltSjutDEpFrhLfV/1fw0SbJFB+or",
|
||||
"l7KuKE8YyY58nrmBmlrkM5pyadIYw1h27JwZ4fRBLyqTQulQNVDPbcuXtqVCKTNMUWvoFic6pQROCrvR",
|
||||
"VD3dDedcSiqzL5s8BIOotBOsxazotEpwBNgnM3pV0DVi7MbKnN/Njn6FprQDctuDBeeSr7HS5b58ZtEt",
|
||||
"4IWeAk6YzXZFGCnYV1fKK2WaaQLh8cBla+yzlfLKKvEZ36ciLfFd7u5kutoWpiKcmgSCNMr6saIka4ZT",
|
||||
"LIdIzqEWYQdOdZo45FAtd8mSUwRMb1YEA+cJ6tW3KmyNfS3iG1mCWjMR1WEU+F6kpo6r5TJdlXwv1q7C",
|
||||
"g2BHDz+lB5Fqkkp5NA9mFn+HPXQfuQiZq4Zf1/vRr1axtN1Y1GjzBb/XCzwM+Z6q+SJa80V1ESDyCOCO",
|
||||
"Md+O9E2GbeJCaY8Gr5K2+JIScGl6dcBJzDcayO/z3MkOFWaX5s0+DEkHuEBNobXYB+4yeJt1a/kaJnfZ",
|
||||
"AksbIi5MhsrWvszfpmg2v+lX9pai6iwLfd/832goz1uskDlo/iKqUDw4cRuQ6c4hg/RfM271Biayg91V",
|
||||
"38Jfqfb4AhLo4UZLsTq7HH5gWvMApBemdSN3d/3I6xK86n8U+OBihSNIsssEDC7M6/c6vY+sns2qmoE+",
|
||||
"tFgLo+qScl2nDD+q9SK8zlaeMI/XsLXjk8Zm478AAAD//0NwNQGuFQAA",
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"gitea.pena/PenaSide/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)
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
output: api.gen.go
|
||||
package: swagger
|
||||
generate:
|
||||
echo-server: true
|
||||
models: false
|
||||
embedded-spec: true
|
@ -1,104 +0,0 @@
|
||||
// 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 Event.
|
||||
const (
|
||||
PaymentCanceled Event = "payment.canceled"
|
||||
PaymentSucceeded Event = "payment.succeeded"
|
||||
PaymentWaitingForCapture Event = "payment.waiting_for_capture"
|
||||
RefundSucceeded Event = "refund.succeeded"
|
||||
)
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// Event defines model for Event.
|
||||
type Event string
|
||||
|
||||
// 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 Event `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
|
@ -1,4 +0,0 @@
|
||||
output: models.gen.go
|
||||
package: swagger
|
||||
generate:
|
||||
models: true
|
@ -1,45 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"gitea.pena/PenaSide/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
|
||||
MockConfiguration MockConfiguration
|
||||
}
|
||||
|
||||
type MockConfiguration struct {
|
||||
IsMock bool `env:"IS_MOCK,default=false"`
|
||||
Host string `env:"MOCK_SERVICE_HOST,default=http://localhost:8080"`
|
||||
YoomomeyURL YoomomeyURL
|
||||
}
|
||||
|
||||
type YoomomeyConfiguration struct {
|
||||
StoreID string `env:"YOOMONEY_STORE_ID,required"`
|
||||
SecretKey string `env:"YOOMONEY_SECRET_KEY,required"`
|
||||
URL YoomomeyURL
|
||||
}
|
||||
|
||||
type YoomomeyURL struct {
|
||||
Webhooks string `env:"YOOMONEY_WEBHOOKS_URL,required"`
|
||||
Payments string `env:"YOOMONEY_PAYMENTS_URL,required"`
|
||||
}
|
@ -31,17 +31,17 @@ type Payment struct {
|
||||
CallbackHostGRPC []string `json:"callbackHostGrpc" bson:"callbackHostGrpc"`
|
||||
}
|
||||
|
||||
func (receiver *Payment) Sanitize() *Payment {
|
||||
func (p *Payment) Sanitize() *Payment {
|
||||
now := time.Now()
|
||||
|
||||
receiver.ID = ""
|
||||
receiver.CreatedAt = now
|
||||
receiver.UpdatedAt = now
|
||||
receiver.DeletedAt = nil
|
||||
receiver.IsDeleted = false
|
||||
receiver.Completed = false
|
||||
p.ID = ""
|
||||
p.CreatedAt = now
|
||||
p.UpdatedAt = now
|
||||
p.DeletedAt = nil
|
||||
p.IsDeleted = false
|
||||
p.Completed = false
|
||||
|
||||
return receiver
|
||||
return p
|
||||
}
|
||||
|
||||
type CreatePaymentResult struct {
|
||||
@ -71,23 +71,23 @@ type BankCard struct {
|
||||
type PaymentType string
|
||||
|
||||
const (
|
||||
PaymentTypeBankCard PaymentType = "bankCard"
|
||||
PaymentTypeTinkoff PaymentType = "tinkoffBank"
|
||||
PaymentTypeSberPay PaymentType = "sberbank"
|
||||
PaymentTypeYoomoney PaymentType = "yoomoney"
|
||||
PaymentTypeMobile PaymentType = "mobile"
|
||||
PaymentTypeSBP PaymentType = "sbp"
|
||||
PaymentTypeSberB2B PaymentType = "b2bSberbank"
|
||||
PaymentTypeBankCard PaymentType = "bankCard"
|
||||
PaymentTypeTinkoff PaymentType = "tinkoffBank"
|
||||
PaymentTypeSberPay PaymentType = "sberbank"
|
||||
PaymentTypeYoomoney PaymentType = "yoomoney"
|
||||
PaymentTypeMobile PaymentType = "mobile"
|
||||
PaymentTypeSBP PaymentType = "sbp"
|
||||
PaymentTypeSberB2B PaymentType = "b2bSberbank"
|
||||
)
|
||||
|
||||
var (
|
||||
YandexPaymentTypeMap = map[PaymentType]yandex.PaymentType{
|
||||
PaymentTypeBankCard: yandex.PaymentTypeBankCard,
|
||||
PaymentTypeTinkoff: yandex.PaymentTypeTinkoff,
|
||||
PaymentTypeSberPay: yandex.PaymentTypeSberPay,
|
||||
PaymentTypeYoomoney: yandex.PaymentTypeYoomoney,
|
||||
PaymentTypeMobile: yandex.PaymentTypeMobile,
|
||||
PaymentTypeSBP: yandex.PaymentTypeSBP,
|
||||
PaymentTypeSberB2B: yandex.PaymentTypeSberB2B,
|
||||
PaymentTypeBankCard: yandex.PaymentTypeBankCard,
|
||||
PaymentTypeTinkoff: yandex.PaymentTypeTinkoff,
|
||||
PaymentTypeSberPay: yandex.PaymentTypeSberPay,
|
||||
PaymentTypeYoomoney: yandex.PaymentTypeYoomoney,
|
||||
PaymentTypeMobile: yandex.PaymentTypeMobile,
|
||||
PaymentTypeSBP: yandex.PaymentTypeSBP,
|
||||
PaymentTypeSberB2B: yandex.PaymentTypeSberB2B,
|
||||
}
|
||||
)
|
||||
|
15
internal/payment_provider/provider.go
Normal file
15
internal/payment_provider/provider.go
Normal file
@ -0,0 +1,15 @@
|
||||
package payment_provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type PaymentProvider interface {
|
||||
GetName() string
|
||||
RegisterWebhookHandlers(router fiber.Router)
|
||||
GetSupportedPaymentMethods() []models.PaymentType
|
||||
CreateInvoice(ctx context.Context, request map[string]string) (string, errors.Error)
|
||||
}
|
212
internal/payment_provider/yoomoney/provider.go
Normal file
212
internal/payment_provider/yoomoney/provider.go
Normal file
@ -0,0 +1,212 @@
|
||||
package yoomoney
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/repository"
|
||||
"gitea.pena/PenaSide/treasurer/internal/service/callback"
|
||||
"gitea.pena/PenaSide/treasurer/internal/utils"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
ProviderName = "yoomoney"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
StoreID string `env:"YOOMONEY_STORE_ID"`
|
||||
SecretKey string `env:"YOOMONEY_SECRET_KEY"`
|
||||
WebhooksURL string `env:"YOOMONEY_WEBHOOKS_URL"`
|
||||
PaymentsURL string `env:"YOOMONEY_PAYMENTS_URL"`
|
||||
}
|
||||
|
||||
type Provider struct {
|
||||
logger *zap.Logger
|
||||
config *Config
|
||||
httpClient *resty.Client
|
||||
repository *repository.PaymentRepository
|
||||
callbackService *callback.Service
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
Config *Config
|
||||
Repository *repository.PaymentRepository
|
||||
CallbackService *callback.Service
|
||||
}
|
||||
|
||||
func New(deps Deps) (*Provider, errors.Error) {
|
||||
return &Provider{
|
||||
logger: deps.Logger,
|
||||
config: deps.Config,
|
||||
httpClient: resty.New(),
|
||||
repository: deps.Repository,
|
||||
callbackService: deps.CallbackService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Provider) GetName() string {
|
||||
return ProviderName
|
||||
}
|
||||
|
||||
func (p *Provider) GetSupportedPaymentMethods() []models.PaymentType {
|
||||
return []models.PaymentType{
|
||||
models.PaymentTypeBankCard,
|
||||
models.PaymentTypeTinkoff,
|
||||
models.PaymentTypeSberPay,
|
||||
models.PaymentTypeYoomoney,
|
||||
models.PaymentTypeMobile,
|
||||
models.PaymentTypeSBP,
|
||||
models.PaymentTypeSberB2B,
|
||||
}
|
||||
}
|
||||
|
||||
// *models.CreatePayment[yandex.Receipt]
|
||||
func (p *Provider) CreateInvoice(ctx context.Context, req map[string]string) (string, errors.Error) {
|
||||
request, err := utils.MapToCreatePaymentYandexReceipt(req)
|
||||
if err != nil {
|
||||
p.logger.Error("failed to create payment yandex receipt by parse map", zap.Error(err))
|
||||
return "", errors.NewWithMessage("failed to parse input request by parse map", errors.ErrInvalidArgs)
|
||||
}
|
||||
idempotenceKey := uuid.New().String()
|
||||
|
||||
yandexPayment, err := p.httpClient.R().
|
||||
SetContext(ctx).
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetHeader("Idempotence-Key", idempotenceKey).
|
||||
SetHeader("Authorization", utils.ConvertYoomoneySercetsToAuth("Basic", p.config.StoreID, p.config.SecretKey)).
|
||||
SetBody(&yandex.CreatePaymentRequest[yandex.PaymentMethodType]{
|
||||
Amount: yandex.Amount{
|
||||
Value: utils.ConvertAmountToStringFloat(request.Amount),
|
||||
Currency: request.Currency,
|
||||
},
|
||||
Receipt: yandex.Receipt{
|
||||
TaxSystemCode: 2, //https://yookassa.ru/developers/payment-acceptance/receipts/54fz/other-services/parameters-values#tax-systems
|
||||
Customer: request.Requisites.Customer,
|
||||
Items: request.Requisites.Items,
|
||||
},
|
||||
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,
|
||||
}).
|
||||
Post(p.config.PaymentsURL)
|
||||
|
||||
if err != nil {
|
||||
p.logger.Error("failed to create payment", zap.Error(err), zap.String("payment_method", string(request.Type)))
|
||||
return "", errors.NewWithError(fmt.Errorf("failed to create payment: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
if yandexPayment.StatusCode() != http.StatusOK {
|
||||
p.logger.Error("failed to create payment", zap.Int("status_code", yandexPayment.StatusCode()), zap.String("response", yandexPayment.String()))
|
||||
return "", errors.NewWithMessage("failed to create payment", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
var payment yandex.Payment
|
||||
if err := json.Unmarshal(yandexPayment.Body(), &payment); err != nil {
|
||||
p.logger.Error("failed to unmarshal payment response", zap.Error(err))
|
||||
return "", errors.NewWithError(fmt.Errorf("failed to unmarshal payment response: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
_, err = p.repository.Insert(ctx, &models.Payment{
|
||||
UserID: request.UserID,
|
||||
PaymentID: payment.ID,
|
||||
IdempotencePaymentID: idempotenceKey,
|
||||
ClientIP: request.ClientIP,
|
||||
Currency: request.Currency,
|
||||
Amount: request.Amount,
|
||||
Type: request.Type,
|
||||
Status: models.PaymentStatusMap[string(payment.Status)],
|
||||
Completed: false,
|
||||
RawPaymentBody: payment,
|
||||
CallbackHostGRPC: request.CallbackHostGRPC,
|
||||
})
|
||||
if err != nil {
|
||||
p.logger.Error("failed to save payment to database", zap.Error(err))
|
||||
return "", errors.NewWithError(fmt.Errorf("failed to save payment to database: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return payment.Confirmation.ConfirmationURL, nil
|
||||
}
|
||||
|
||||
func (p *Provider) RegisterWebhookHandlers(router fiber.Router) {
|
||||
router.Post(p.config.WebhooksURL, p.handleWebhook)
|
||||
}
|
||||
|
||||
func (p *Provider) handleWebhook(ctx *fiber.Ctx) error {
|
||||
var notification yandex.WebhookNotification[yandex.Payment]
|
||||
if err := ctx.BodyParser(¬ification); err != nil {
|
||||
p.logger.Error("failed to parse webhook notification", zap.Error(err))
|
||||
return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse webhook notification: %w", err), errors.ErrInternalError))
|
||||
}
|
||||
|
||||
var payment *models.Payment
|
||||
var err errors.Error
|
||||
|
||||
switch notification.Event {
|
||||
case yandex.WebhookEventPaymentSucceeded:
|
||||
payment, err = p.repository.SetPaymentStatus(ctx.Context(), notification.Object.ID, models.PaymentStatusSuccessfully)
|
||||
if err != nil {
|
||||
p.logger.Error("failed to set payment complete", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
case yandex.WebhookEventPaymentCanceled:
|
||||
payment, err = p.repository.SetPaymentStatus(ctx.Context(), notification.Object.ID, models.PaymentStatusCanceled)
|
||||
if err != nil {
|
||||
p.logger.Error("failed to set payment status canceled", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
case yandex.WebhookEventPaymentWaiting:
|
||||
payment, err = p.repository.SetPaymentStatus(ctx.Context(), notification.Object.ID, models.PaymentStatusWaiting)
|
||||
if err != nil {
|
||||
p.logger.Error("failed to set payment status waiting", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
case yandex.WebhookEventRefundSucceeded:
|
||||
payment, err = p.repository.SetPaymentStatus(ctx.Context(), notification.Object.ID, models.PaymentStatusRefund)
|
||||
if err != nil {
|
||||
p.logger.Error("failed to set payment status refund", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
default:
|
||||
p.logger.Warn("unknown webhook event type", zap.String("event", string(notification.Event)))
|
||||
return errors.HTTP(ctx, errors.NewWithMessage(fmt.Sprintf("unknown webhook event type: %s", notification.Event), errors.ErrInvalidArgs))
|
||||
}
|
||||
|
||||
if payment != nil {
|
||||
event := &models.Event{
|
||||
Key: string(notification.Event),
|
||||
Message: fmt.Sprintf("yoomoney send event: %s", notification.Event),
|
||||
Payment: payment,
|
||||
}
|
||||
|
||||
if notification.Event == yandex.WebhookEventPaymentSucceeded {
|
||||
if err := p.callbackService.OnSuccess(ctx.Context(), event); err != nil {
|
||||
p.logger.Error("failed to send success callback", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
}
|
||||
|
||||
if notification.Event == yandex.WebhookEventPaymentCanceled {
|
||||
if err := p.callbackService.OnFailure(ctx.Context(), event); err != nil {
|
||||
p.logger.Error("failed to send failure callback", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.SendStatus(http.StatusOK)
|
||||
}
|
@ -75,7 +75,7 @@ func NewPaymentRepository(deps PaymentRepositoryDeps) (*PaymentRepository, error
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentRepository) SetPaymentComplete(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
func (r *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}
|
||||
@ -84,8 +84,8 @@ func (receiver *PaymentRepository) SetPaymentComplete(ctx context.Context, payme
|
||||
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>",
|
||||
if err := r.collection.FindOneAndUpdate(ctx, filter, update, options).Decode(&payment); err != nil {
|
||||
r.logger.Error("failed to set payment complete on <SetPaymentComplete> of <PaymentRepository>",
|
||||
zap.Error(err),
|
||||
zap.String("paymentID", paymentID),
|
||||
)
|
||||
@ -105,12 +105,12 @@ func (receiver *PaymentRepository) SetPaymentComplete(ctx context.Context, payme
|
||||
return &payment, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentRepository) Insert(ctx context.Context, payment *models.Payment) (*models.Payment, errors.Error) {
|
||||
func (r *PaymentRepository) Insert(ctx context.Context, payment *models.Payment) (*models.Payment, errors.Error) {
|
||||
sanitizedPayment := payment.Sanitize()
|
||||
|
||||
result, err := receiver.collection.InsertOne(ctx, sanitizedPayment)
|
||||
result, err := r.collection.InsertOne(ctx, sanitizedPayment)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to insert payment on <Insert> of <PaymentRepository>",
|
||||
r.logger.Error("failed to insert payment on <Insert> of <PaymentRepository>",
|
||||
zap.Any("payment", sanitizedPayment),
|
||||
zap.Error(err),
|
||||
)
|
||||
@ -127,7 +127,7 @@ func (receiver *PaymentRepository) Insert(ctx context.Context, payment *models.P
|
||||
return sanitizedPayment, nil
|
||||
}
|
||||
|
||||
func (receiver *PaymentRepository) SetPaymentStatus(ctx context.Context, paymentID string, status models.PaymentStatus) (*models.Payment, errors.Error) {
|
||||
func (r *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}
|
||||
@ -136,8 +136,8 @@ func (receiver *PaymentRepository) SetPaymentStatus(ctx context.Context, payment
|
||||
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>",
|
||||
if err := r.collection.FindOneAndUpdate(ctx, filter, update, options).Decode(&payment); err != nil {
|
||||
r.logger.Error("failed to set payment status on <SetPaymentStatus> of <PaymentRepository>",
|
||||
zap.Error(err),
|
||||
zap.String("paymentID", paymentID),
|
||||
)
|
@ -1,79 +0,0 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
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"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/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, grpc.ConnectionTimeout(5*time.Second)),
|
||||
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)
|
||||
}
|
69
internal/server/grpc/grpc_server.go
Normal file
69
internal/server/grpc/grpc_server.go
Normal file
@ -0,0 +1,69 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
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"
|
||||
)
|
||||
|
||||
type GRPC struct {
|
||||
grpc *grpc.Server
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewGRPC(logger *zap.Logger) (*GRPC, error) {
|
||||
grpcStreamInterceptor := grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
|
||||
grpc_zap.StreamServerInterceptor(logger),
|
||||
grpc_recovery.StreamServerInterceptor(),
|
||||
))
|
||||
|
||||
grpcUnaryInterceptor := grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
|
||||
grpc_zap.UnaryServerInterceptor(logger),
|
||||
grpc_recovery.UnaryServerInterceptor(),
|
||||
))
|
||||
|
||||
return &GRPC{
|
||||
grpc: grpc.NewServer(grpcStreamInterceptor, grpcUnaryInterceptor, grpc.ConnectionTimeout(5*time.Second)),
|
||||
logger: logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *GRPC) Run(addr string) {
|
||||
connectionString := fmt.Sprintf(addr)
|
||||
|
||||
s.logger.Info("Starting GRPC Server", zap.String("host", connectionString))
|
||||
|
||||
if err := s.listen(connectionString); err != nil && err != grpc.ErrServerStopped {
|
||||
s.logger.Error("GRPC Listen error", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *GRPC) Stop(_ context.Context) error {
|
||||
s.grpc.GracefulStop()
|
||||
s.logger.Info("Shutting down GRPC server...")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *GRPC) Register(server treasurer.TreasurerServiceServer) *GRPC {
|
||||
treasurer.RegisterTreasurerServiceServer(s.grpc, server)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *GRPC) listen(address string) error {
|
||||
listener, err := net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.grpc.Serve(listener)
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
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"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/interface/swagger"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
)
|
||||
|
||||
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: 20 * time.Second,
|
||||
WriteTimeout: 20 * time.Second,
|
||||
IdleTimeout: 20 * 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
|
||||
}
|
65
internal/server/http/http_server.go
Normal file
65
internal/server/http/http_server.go
Normal file
@ -0,0 +1,65 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type ServerConfig struct {
|
||||
Logger *zap.Logger
|
||||
Controllers []Controller
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Logger *zap.Logger
|
||||
Controllers []Controller
|
||||
app *fiber.App
|
||||
}
|
||||
|
||||
func NewServer(config ServerConfig) *Server {
|
||||
app := fiber.New()
|
||||
s := &Server{
|
||||
Logger: config.Logger,
|
||||
Controllers: config.Controllers,
|
||||
app: app,
|
||||
}
|
||||
|
||||
s.registerRoutes()
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Server) Start(addr string) error {
|
||||
if err := s.app.Listen(addr); err != nil {
|
||||
s.Logger.Error("Failed to start server", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) Shutdown(ctx context.Context) error {
|
||||
return s.app.Shutdown()
|
||||
}
|
||||
|
||||
func (s *Server) registerRoutes() {
|
||||
for _, c := range s.Controllers {
|
||||
router := s.app.Group(c.Name())
|
||||
c.Register(router)
|
||||
}
|
||||
}
|
||||
|
||||
type Controller interface {
|
||||
Register(router fiber.Router)
|
||||
Name() string
|
||||
}
|
||||
|
||||
func (s *Server) ListRoutes() {
|
||||
fmt.Println("Registered routes:")
|
||||
for _, stack := range s.app.Stack() {
|
||||
for _, route := range stack {
|
||||
fmt.Printf("%s %s\n", route.Method, route.Path)
|
||||
}
|
||||
}
|
||||
}
|
@ -2,32 +2,25 @@ package callback
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gitea.pena/PenaSide/treasurer/internal/client"
|
||||
"gitea.pena/PenaSide/treasurer/internal/repository"
|
||||
"sync"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
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
|
||||
CallbackClient *client.CallbackClient
|
||||
PaymentRepository *repository.PaymentRepository
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
callbackClient CallbackClient
|
||||
paymentRepository PaymentRepository
|
||||
callbackClient *client.CallbackClient
|
||||
paymentRepository *repository.PaymentRepository
|
||||
}
|
||||
|
||||
func New(deps Deps) (*Service, errors.Error) {
|
||||
@ -50,7 +43,7 @@ func New(deps Deps) (*Service, errors.Error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) OnSuccess(ctx context.Context, event *models.Event) errors.Error {
|
||||
func (s *Service) OnSuccess(ctx context.Context, event *models.Event) errors.Error {
|
||||
waitGroup := sync.WaitGroup{}
|
||||
mutex := sync.Mutex{}
|
||||
executeErrors := make([]error, 0)
|
||||
@ -61,8 +54,8 @@ func (receiver *Service) OnSuccess(ctx context.Context, event *models.Event) err
|
||||
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>")
|
||||
if err := s.callbackClient.SendOnSuccess(ctx, url, event); err != nil {
|
||||
s.logger.Error("failid to send callback on <OnSuccess> of <CallbackService>")
|
||||
|
||||
mutex.Lock()
|
||||
executeErrors = append(executeErrors, err)
|
||||
@ -71,8 +64,8 @@ func (receiver *Service) OnSuccess(ctx context.Context, event *models.Event) err
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := receiver.paymentRepository.SetPaymentComplete(ctx, event.Payment.PaymentID); err != nil {
|
||||
receiver.logger.Error("failid to set payment complete on <OnSuccess> of <CallbackService>")
|
||||
if _, err := s.paymentRepository.SetPaymentComplete(ctx, event.Payment.PaymentID); err != nil {
|
||||
s.logger.Error("failid to set payment complete on <OnSuccess> of <CallbackService>")
|
||||
|
||||
mutex.Lock()
|
||||
executeErrors = append(executeErrors, err)
|
||||
@ -86,14 +79,14 @@ func (receiver *Service) OnSuccess(ctx context.Context, event *models.Event) err
|
||||
waitGroup.Wait()
|
||||
|
||||
if len(executeErrors) >= len(event.Payment.CallbackHostGRPC) {
|
||||
receiver.logger.Error("failid to success payment on <OnSuccess> of <CallbackService>", zap.Errors("errors", executeErrors))
|
||||
s.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 {
|
||||
func (s *Service) OnFailure(ctx context.Context, event *models.Event) errors.Error {
|
||||
waitGroup := sync.WaitGroup{}
|
||||
mutex := sync.Mutex{}
|
||||
executeErrors := make([]error, 0)
|
||||
@ -104,8 +97,8 @@ func (receiver *Service) OnFailure(ctx context.Context, event *models.Event) err
|
||||
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>")
|
||||
if err := s.callbackClient.SendOnFailure(ctx, url, event); err != nil {
|
||||
s.logger.Error("failid to send callback on <OnFailure> of <CallbackService>")
|
||||
|
||||
mutex.Lock()
|
||||
executeErrors = append(executeErrors, err)
|
||||
@ -119,7 +112,7 @@ func (receiver *Service) OnFailure(ctx context.Context, event *models.Event) err
|
||||
waitGroup.Wait()
|
||||
|
||||
if len(executeErrors) >= len(event.Payment.CallbackHostGRPC) {
|
||||
receiver.logger.Error("failid to success payment on <OnFailure> of <CallbackService>", zap.Errors("errors", executeErrors))
|
||||
s.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)
|
||||
}
|
||||
|
||||
|
@ -1,27 +1,23 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/validate"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type MockStrategyService interface {
|
||||
Register(host string) errors.Error
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
MockServiceHost string
|
||||
Enabled bool
|
||||
YoomoneyMockService MockStrategyService
|
||||
YoomoneyMockService *YoomoneyMockService
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
mockServiceHost string
|
||||
enabled bool
|
||||
yoomoneyMockService MockStrategyService
|
||||
yoomoneyMockService *YoomoneyMockService
|
||||
}
|
||||
|
||||
func New(deps Deps) (*Service, errors.Error) {
|
||||
@ -45,14 +41,14 @@ func New(deps Deps) (*Service, errors.Error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) Register() bool {
|
||||
if !receiver.enabled {
|
||||
receiver.logger.Info("register mocks is disabled")
|
||||
func (s *Service) Register() bool {
|
||||
if !s.enabled {
|
||||
s.logger.Info("register mocks is disabled")
|
||||
return false
|
||||
}
|
||||
|
||||
if err := receiver.yoomoneyMockService.Register(receiver.mockServiceHost); err != nil {
|
||||
receiver.logger.Error("failed to register yoomoney mocks", zap.Error(err), zap.String("host", receiver.mockServiceHost))
|
||||
if err := s.yoomoneyMockService.Register(s.mockServiceHost); err != nil {
|
||||
s.logger.Error("failed to register yoomoney mocks", zap.Error(err), zap.String("host", s.mockServiceHost))
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -4,21 +4,20 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
)
|
||||
|
||||
type YoomoneyMockServiceDeps struct {
|
||||
Logger *zap.Logger
|
||||
YoomoneyURL *models.YoomomeyURL
|
||||
Logger *zap.Logger
|
||||
YooMoneyPaymentsURL string
|
||||
}
|
||||
|
||||
type YoomoneyMockService struct {
|
||||
logger *zap.Logger
|
||||
yoomoneyURL *models.YoomomeyURL
|
||||
logger *zap.Logger
|
||||
yooMoneyPaymentsURL string
|
||||
}
|
||||
|
||||
func NewYoomoneyMockService(deps YoomoneyMockServiceDeps) (*YoomoneyMockService, errors.Error) {
|
||||
@ -26,26 +25,22 @@ func NewYoomoneyMockService(deps YoomoneyMockServiceDeps) (*YoomoneyMockService,
|
||||
return nil, errors.NewWithMessage("logger is nil on <NewYoomoneyMockService>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if deps.YoomoneyURL == nil {
|
||||
return nil, errors.NewWithMessage("yoomoney urls is nil on <NewYoomoneyMockService>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
return &YoomoneyMockService{
|
||||
logger: deps.Logger,
|
||||
yoomoneyURL: deps.YoomoneyURL,
|
||||
logger: deps.Logger,
|
||||
yooMoneyPaymentsURL: deps.YooMoneyPaymentsURL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *YoomoneyMockService) Register(host string) errors.Error {
|
||||
return receiver.RegisterPayments(host)
|
||||
func (s *YoomoneyMockService) Register(host string) errors.Error {
|
||||
return s.RegisterPayments(host)
|
||||
}
|
||||
|
||||
func (receiver *YoomoneyMockService) RegisterPayments(host string) errors.Error {
|
||||
paymentsURL, parseErr := url.Parse(receiver.yoomoneyURL.Payments)
|
||||
func (s *YoomoneyMockService) RegisterPayments(host string) errors.Error {
|
||||
paymentsURL, parseErr := url.Parse(s.yooMoneyPaymentsURL)
|
||||
if parseErr != nil {
|
||||
receiver.logger.Error("failed to parse payment url on <RegisterPayment> of <YoomoneyMockService>",
|
||||
s.logger.Error("failed to parse payment url on <RegisterPayment> of <YoomoneyMockService>",
|
||||
zap.Error(parseErr),
|
||||
zap.String("url", receiver.yoomoneyURL.Payments),
|
||||
zap.String("url", s.yooMoneyPaymentsURL),
|
||||
)
|
||||
|
||||
return errors.NewWithError(fmt.Errorf("failed to parse payment url: %w", parseErr), errors.ErrInternalError)
|
||||
@ -53,9 +48,9 @@ func (receiver *YoomoneyMockService) RegisterPayments(host string) errors.Error
|
||||
|
||||
hostURL, parseErr := url.Parse(host)
|
||||
if parseErr != nil {
|
||||
receiver.logger.Error("failed to parse payment url on <RegisterPayment> of <YoomoneyMockService>",
|
||||
s.logger.Error("failed to parse payment url on <RegisterPayment> of <YoomoneyMockService>",
|
||||
zap.Error(parseErr),
|
||||
zap.String("url", receiver.yoomoneyURL.Payments),
|
||||
zap.String("url", s.yooMoneyPaymentsURL),
|
||||
)
|
||||
|
||||
return errors.NewWithError(fmt.Errorf("failed to parse payment url: %w", parseErr), errors.ErrInternalError)
|
||||
@ -92,9 +87,9 @@ func (receiver *YoomoneyMockService) RegisterPayments(host string) errors.Error
|
||||
AtPriority(1)
|
||||
|
||||
if err := mockClient.StubFor(rule); err != nil {
|
||||
receiver.logger.Error("failed to init payment mock handler on <RegisterPayment> of <YoomoneyMockService>",
|
||||
s.logger.Error("failed to init payment mock handler on <RegisterPayment> of <YoomoneyMockService>",
|
||||
zap.Error(err),
|
||||
zap.String("payments full url", receiver.yoomoneyURL.Payments),
|
||||
zap.String("payments full url", s.yooMoneyPaymentsURL),
|
||||
zap.String("payments path", paymentsURL.Path),
|
||||
)
|
||||
|
||||
@ -103,9 +98,9 @@ func (receiver *YoomoneyMockService) RegisterPayments(host string) errors.Error
|
||||
|
||||
isVerified, err := mockClient.Verify(wiremock.NewRequest("post", wiremock.URLPathEqualTo(paymentsURL.Path)), 0)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to verify payment mock handler on <RegisterPayment> of <YoomoneyMockService>",
|
||||
s.logger.Error("failed to verify payment mock handler on <RegisterPayment> of <YoomoneyMockService>",
|
||||
zap.Error(err),
|
||||
zap.String("payments full url", receiver.yoomoneyURL.Payments),
|
||||
zap.String("payments full url", s.yooMoneyPaymentsURL),
|
||||
zap.String("payments path", paymentsURL.Path),
|
||||
)
|
||||
|
||||
|
@ -3,33 +3,25 @@ package payment
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"gitea.pena/PenaSide/treasurer/internal/repository"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/utils"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type PaymentStrategyService interface {
|
||||
CreatePaymentBankCard(ctx context.Context, uuid string, payment *models.CreatePayment[yandex.Receipt]) (*models.CreatePaymentResult, errors.Error)
|
||||
CreatePayment(ctx context.Context, uuid string, payment *models.CreatePayment[yandex.Receipt]) (*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
|
||||
PaymentStrategyService *Yandex
|
||||
PaymentRepository *repository.PaymentRepository
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
paymentStrategyService PaymentStrategyService
|
||||
paymentRepository PaymentRepository
|
||||
paymentStrategyService *Yandex
|
||||
paymentRepository *repository.PaymentRepository
|
||||
}
|
||||
|
||||
func New(deps Deps) (*Service, errors.Error) {
|
||||
@ -52,43 +44,43 @@ func New(deps Deps) (*Service, errors.Error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) CreatePaymentBankCard(ctx context.Context, request *models.CreatePayment[yandex.Receipt]) (string, errors.Error) {
|
||||
receiver.logger.Info("f<CreatePaymentBankCard> of <YandexPaymentService>", zap.Any("Customer", request.Requisites.Customer), zap.Any("Items",request.Requisites.Items))
|
||||
func (s *Service) CreatePaymentBankCard(ctx context.Context, request *models.CreatePayment[yandex.Receipt]) (string, errors.Error) {
|
||||
s.logger.Info("f<CreatePaymentBankCard> of <YandexPaymentService>", zap.Any("Customer", request.Requisites.Customer), zap.Any("Items", request.Requisites.Items))
|
||||
paymentUUID, generateErr := utils.GenerateUUID()
|
||||
if generateErr != nil {
|
||||
receiver.logger.Error("failed to generate uuid on <CreatePaymentBankCard> of <PaymentService>", zap.Error(generateErr))
|
||||
s.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)
|
||||
response, err := s.paymentStrategyService.CreatePaymentBankCard(ctx, paymentUUID, request)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentBankCard> of <PaymentService>", zap.Error(err))
|
||||
s.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))
|
||||
if _, err := s.paymentRepository.Insert(ctx, response.Payment); err != nil {
|
||||
s.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[yandex.Receipt]) (string, errors.Error) {
|
||||
func (s *Service) CreatePayment(ctx context.Context, request *models.CreatePayment[yandex.Receipt]) (string, errors.Error) {
|
||||
paymentUUID, generateErr := utils.GenerateUUID()
|
||||
if generateErr != nil {
|
||||
receiver.logger.Error("failed to generate uuid on <CreatePayment> of <PaymentService>", zap.Error(generateErr))
|
||||
s.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)
|
||||
response, err := s.paymentStrategyService.CreatePayment(ctx, paymentUUID, request)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePayment> of <PaymentService>", zap.Error(err))
|
||||
s.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))
|
||||
if _, err := s.paymentRepository.Insert(ctx, response.Payment); err != nil {
|
||||
s.logger.Error("failed to insert payment on <CreatePayment> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
@ -2,28 +2,23 @@ package payment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gitea.pena/PenaSide/treasurer/internal/client"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/utils"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type YandexPaymentClient interface {
|
||||
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)
|
||||
}
|
||||
|
||||
type YandexPaymentServiceDeps struct {
|
||||
Logger *zap.Logger
|
||||
YandexPaymentClient YandexPaymentClient
|
||||
YandexPaymentClient *client.YandexClient
|
||||
}
|
||||
|
||||
type Yandex struct {
|
||||
logger *zap.Logger
|
||||
yandexPaymentClient YandexPaymentClient
|
||||
yandexPaymentClient *client.YandexClient
|
||||
}
|
||||
|
||||
func NewYandex(deps YandexPaymentServiceDeps) (*Yandex, errors.Error) {
|
||||
@ -41,9 +36,9 @@ func NewYandex(deps YandexPaymentServiceDeps) (*Yandex, errors.Error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) CreatePaymentBankCard(ctx context.Context, uuid string, request *models.CreatePayment[yandex.Receipt]) (*models.CreatePaymentResult, errors.Error) {
|
||||
receiver.logger.Info("f<CreatePaymentBankCard> of <YandexPaymentService>", zap.Any("Customer", request.Requisites.Customer), zap.Any("Items",request.Requisites.Items))
|
||||
yandexPayment, err := receiver.yandexPaymentClient.CreatePaymentBankCard(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodBankCard]{
|
||||
func (s *Yandex) CreatePaymentBankCard(ctx context.Context, uuid string, request *models.CreatePayment[yandex.Receipt]) (*models.CreatePaymentResult, errors.Error) {
|
||||
s.logger.Info("f<CreatePaymentBankCard> of <YandexPaymentService>", zap.Any("Customer", request.Requisites.Customer), zap.Any("Items", request.Requisites.Items))
|
||||
yandexPayment, err := s.yandexPaymentClient.CreatePaymentBankCard(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodBankCard]{
|
||||
Amount: yandex.Amount{
|
||||
Value: utils.ConvertAmountToStringFloat(request.Amount),
|
||||
Currency: request.Currency,
|
||||
@ -51,8 +46,8 @@ func (receiver *Yandex) CreatePaymentBankCard(ctx context.Context, uuid string,
|
||||
Description: "Пополнение пользовательского баланса платформы Pena Hub",
|
||||
Receipt: yandex.Receipt{
|
||||
TaxSystemCode: 2, //https://yookassa.ru/developers/payment-acceptance/receipts/54fz/other-services/parameters-values#tax-systems
|
||||
Customer: request.Requisites.Customer,
|
||||
Items: request.Requisites.Items,
|
||||
Customer: request.Requisites.Customer,
|
||||
Items: request.Requisites.Items,
|
||||
},
|
||||
PaymentMethodData: &yandex.PaymentMethodBankCard{
|
||||
Type: models.YandexPaymentTypeMap[request.Type],
|
||||
@ -67,7 +62,7 @@ func (receiver *Yandex) CreatePaymentBankCard(ctx context.Context, uuid string,
|
||||
ClientIP: request.ClientIP,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePaymentBankCard> of <YandexPaymentService>", zap.Error(err))
|
||||
s.logger.Error("failed to create payment on <CreatePaymentBankCard> of <YandexPaymentService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -89,16 +84,16 @@ func (receiver *Yandex) CreatePaymentBankCard(ctx context.Context, uuid string,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) CreatePayment(ctx context.Context, uuid string, request *models.CreatePayment[yandex.Receipt]) (*models.CreatePaymentResult, errors.Error) {
|
||||
yandexPayment, err := receiver.yandexPaymentClient.CreatePayment(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodType]{
|
||||
func (s *Yandex) CreatePayment(ctx context.Context, uuid string, request *models.CreatePayment[yandex.Receipt]) (*models.CreatePaymentResult, errors.Error) {
|
||||
yandexPayment, err := s.yandexPaymentClient.CreatePayment(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodType]{
|
||||
Amount: yandex.Amount{
|
||||
Value: utils.ConvertAmountToStringFloat(request.Amount),
|
||||
Currency: request.Currency,
|
||||
},
|
||||
Receipt: yandex.Receipt{
|
||||
TaxSystemCode: 2, //https://yookassa.ru/developers/payment-acceptance/receipts/54fz/other-services/parameters-values#tax-systems
|
||||
Customer: request.Requisites.Customer,
|
||||
Items: request.Requisites.Items,
|
||||
Customer: request.Requisites.Customer,
|
||||
Items: request.Requisites.Items,
|
||||
},
|
||||
PaymentMethodData: &yandex.PaymentMethodType{Type: models.YandexPaymentTypeMap[request.Type]},
|
||||
Confirmation: &yandex.CreateConfirmationRedirect{
|
||||
@ -111,7 +106,7 @@ func (receiver *Yandex) CreatePayment(ctx context.Context, uuid string, request
|
||||
ClientIP: request.ClientIP,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create payment on <CreatePayment> of <YandexPaymentService>", zap.Error(err))
|
||||
s.logger.Error("failed to create payment on <CreatePayment> of <YandexPaymentService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -2,24 +2,21 @@ package status
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gitea.pena/PenaSide/treasurer/internal/repository"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type PaymentRepository interface {
|
||||
SetPaymentStatus(ctx context.Context, paymentID string, status models.PaymentStatus) (*models.Payment, errors.Error)
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
PaymentRepository PaymentRepository
|
||||
PaymentRepository *repository.PaymentRepository
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
paymentRepository PaymentRepository
|
||||
paymentRepository *repository.PaymentRepository
|
||||
}
|
||||
|
||||
func New(deps Deps) (*Service, errors.Error) {
|
||||
@ -37,40 +34,40 @@ func New(deps Deps) (*Service, errors.Error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) SetStatusCanceled(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
payment, err := receiver.paymentRepository.SetPaymentStatus(ctx, paymentID, models.PaymentStatusCanceled)
|
||||
func (s *Service) SetStatusCanceled(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
payment, err := s.paymentRepository.SetPaymentStatus(ctx, paymentID, models.PaymentStatusCanceled)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to set payment status on <SetStatusCanceled> of <StatusService>", zap.Error(err))
|
||||
s.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)
|
||||
func (s *Service) SetStatusSuccess(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
payment, err := s.paymentRepository.SetPaymentStatus(ctx, paymentID, models.PaymentStatusSuccessfully)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to set payment status on <SetStatusSuccess> of <StatusService>", zap.Error(err))
|
||||
s.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)
|
||||
func (s *Service) SetStatusWaiting(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
payment, err := s.paymentRepository.SetPaymentStatus(ctx, paymentID, models.PaymentStatusWaiting)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to set payment status on <SetStatusWaiting> of <StatusService>", zap.Error(err))
|
||||
s.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)
|
||||
func (s *Service) SetStatusRefund(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
||||
payment, err := s.paymentRepository.SetPaymentStatus(ctx, paymentID, models.PaymentStatusRefund)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to set payment status on <SetStatusRefund> of <StatusService>", zap.Error(err))
|
||||
s.logger.Error("failed to set payment status on <SetStatusRefund> of <StatusService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,9 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -23,132 +22,129 @@ type YandexWebhookClient interface {
|
||||
|
||||
type YandexDeps struct {
|
||||
Logger *zap.Logger
|
||||
Configuration *models.ConfigurationHTTP
|
||||
HttpDomain string
|
||||
YandexWebhookClient YandexWebhookClient
|
||||
}
|
||||
|
||||
type Yandex struct {
|
||||
logger *zap.Logger
|
||||
configuration *models.ConfigurationHTTP
|
||||
httpDomain string
|
||||
yandexWebhookClient YandexWebhookClient
|
||||
}
|
||||
|
||||
// todo не используется
|
||||
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,
|
||||
httpDomain: deps.HttpDomain,
|
||||
yandexWebhookClient: deps.YandexWebhookClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) SetOnPaymentSuccess(ctx context.Context) errors.Error {
|
||||
url, urlErr := url.JoinPath(receiver.configuration.Domen, "yandex", "payment", "status", "succeeded")
|
||||
func (s *Yandex) SetOnPaymentSuccess(ctx context.Context) errors.Error {
|
||||
url, urlErr := url.JoinPath(s.httpDomain, "yandex", "payment", "status", "succeeded")
|
||||
if urlErr != nil {
|
||||
receiver.logger.Error("failed to join url path on <SetOnPaymentSuccess> of <WebhookService>", zap.Error(urlErr))
|
||||
s.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{
|
||||
if err := s.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))
|
||||
s.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")
|
||||
func (s *Yandex) SetOnPaymentCanceled(ctx context.Context) errors.Error {
|
||||
url, urlErr := url.JoinPath(s.httpDomain, "yandex", "payment", "status", "canceled")
|
||||
if urlErr != nil {
|
||||
receiver.logger.Error("failed to join url path on <SetOnPaymentCanceled> of <WebhookService>", zap.Error(urlErr))
|
||||
s.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{
|
||||
if err := s.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))
|
||||
s.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")
|
||||
func (s *Yandex) SetOnPaymentWaiting(ctx context.Context) errors.Error {
|
||||
url, urlErr := url.JoinPath(s.httpDomain, "yandex", "payment", "status", "waiting")
|
||||
if urlErr != nil {
|
||||
receiver.logger.Error("failed to join url path on <SetOnPaymentWaiting> of <WebhookService>", zap.Error(urlErr))
|
||||
s.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{
|
||||
if err := s.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))
|
||||
s.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")
|
||||
func (s *Yandex) SetOnPaymentRefund(ctx context.Context) errors.Error {
|
||||
url, urlErr := url.JoinPath(s.httpDomain, "yandex", "refund", "status", "canceled")
|
||||
if urlErr != nil {
|
||||
receiver.logger.Error("failed to join url path on <SetOnPaymentRefund> of <WebhookService>", zap.Error(urlErr))
|
||||
s.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{
|
||||
if err := s.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))
|
||||
s.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)
|
||||
func (s *Yandex) SetWebhook(ctx context.Context, idempotenceKey string, request *yandex.CreateWebhookRequest) errors.Error {
|
||||
webhook, err := s.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))
|
||||
s.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>")
|
||||
s.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
|
||||
// }
|
||||
//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) {
|
||||
func (s *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))
|
||||
@ -171,10 +167,10 @@ func (receiver *Yandex) GetWebhookByType(ctx context.Context, event yandex.Webho
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (receiver *Yandex) UnsetWebhook(ctx context.Context, event yandex.WebhookEventType) errors.Error {
|
||||
_, err := receiver.GetWebhookByType(ctx, event)
|
||||
func (s *Yandex) UnsetWebhook(ctx context.Context, event yandex.WebhookEventType) errors.Error {
|
||||
_, err := s.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)))
|
||||
s.logger.Error("failed to get webhook on <UnsetWebhook> of <WebhookService>", zap.Error(err), zap.String("event", string(event)))
|
||||
return err
|
||||
}
|
||||
|
||||
|
44
internal/utils/parse_map.go
Normal file
44
internal/utils/parse_map.go
Normal file
@ -0,0 +1,44 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func MapToCreatePaymentYandexReceipt(data map[string]string) (*models.CreatePayment[yandex.Receipt], error) {
|
||||
amount, err := strconv.ParseInt(data["amount"], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid amount: %w", err)
|
||||
}
|
||||
|
||||
var callbackHosts []string
|
||||
if val, ok := data["callback_host_grpc"]; ok && val != "" {
|
||||
callbackHosts = strings.Split(val, ",")
|
||||
}
|
||||
|
||||
var requisites yandex.Receipt
|
||||
if val, ok := data["requisites"]; ok && val != "" {
|
||||
if err := json.Unmarshal([]byte(val), &requisites); err != nil {
|
||||
return nil, fmt.Errorf("invalid requisites JSON: %w", err)
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("missing requisites field")
|
||||
}
|
||||
|
||||
payment := &models.CreatePayment[yandex.Receipt]{
|
||||
Type: models.PaymentType(data["type"]),
|
||||
Currency: data["currency"],
|
||||
Amount: amount,
|
||||
CallbackHostGRPC: callbackHosts,
|
||||
ReturnURL: data["return_url"],
|
||||
UserID: data["user_id"],
|
||||
ClientIP: data["client_ip"],
|
||||
Requisites: requisites,
|
||||
}
|
||||
|
||||
return payment, nil
|
||||
}
|
@ -2,10 +2,11 @@ package utils
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ConvertYoomoneySercetsToAuth(authType, storeID, secretKey string) string {
|
||||
@ -20,14 +21,14 @@ func ProtoItem2ReceiptItem(in *treasurer.Item) yandex.Item {
|
||||
return yandex.Item{
|
||||
Description: in.Description,
|
||||
Amount: yandex.ReceiptAmount{
|
||||
Value: in.Money,
|
||||
Value: in.Money,
|
||||
Currency: in.Currency,
|
||||
},
|
||||
VatCode: 1,
|
||||
Quantity: 1,
|
||||
Measure: in.Measure,
|
||||
VatCode: 1,
|
||||
Quantity: 1,
|
||||
Measure: in.Measure,
|
||||
PaymentSubject: "service",
|
||||
PaymentMode: "full_prepayment",
|
||||
PaymentMode: "full_prepayment",
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +38,12 @@ func ProtoItems2ReceiptItems(in []*treasurer.Item) []yandex.Item {
|
||||
|
||||
for i, item := range in {
|
||||
out[i] = ProtoItem2ReceiptItem(item)
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func ToJSON(v any) string {
|
||||
b, _ := json.Marshal(v)
|
||||
return string(b)
|
||||
}
|
||||
|
@ -4,22 +4,19 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gitea.pena/PenaSide/treasurer/internal/errors"
|
||||
svc_mock "gitea.pena/PenaSide/treasurer/internal/service/mock"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type mockService interface {
|
||||
Register() bool
|
||||
}
|
||||
|
||||
type WorkerDeps struct {
|
||||
Logger *zap.Logger
|
||||
MockService mockService
|
||||
MockService *svc_mock.Service
|
||||
}
|
||||
|
||||
type Worker struct {
|
||||
logger *zap.Logger
|
||||
mockService mockService
|
||||
mockService *svc_mock.Service
|
||||
}
|
||||
|
||||
func New(deps WorkerDeps) (*Worker, errors.Error) {
|
||||
@ -37,24 +34,24 @@ func New(deps WorkerDeps) (*Worker, errors.Error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Worker) Run(ctx context.Context) {
|
||||
func (w *Worker) Run(ctx context.Context) {
|
||||
after := time.After(10 * time.Second)
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
receiver.logger.Info("register mocks operations canceled <mocks>")
|
||||
w.logger.Info("register mocks operations canceled <mocks>")
|
||||
return
|
||||
case <-after:
|
||||
receiver.logger.Info("register yoomoney mocks <mocks>")
|
||||
w.logger.Info("register yoomoney mocks <mocks>")
|
||||
|
||||
isSuccess := receiver.mockService.Register()
|
||||
isSuccess := w.mockService.Register()
|
||||
|
||||
if isSuccess {
|
||||
receiver.logger.Info("register yoomoney mocks complete <mocks>")
|
||||
w.logger.Info("register yoomoney mocks complete <mocks>")
|
||||
}
|
||||
|
||||
if !isSuccess {
|
||||
receiver.logger.Info("register yoomoney mocks failure <mocks>")
|
||||
w.logger.Info("register yoomoney mocks failure <mocks>")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,49 +2,36 @@ package closer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Callback func(ctx context.Context) error
|
||||
|
||||
type Closer struct {
|
||||
mutex sync.Mutex
|
||||
callbacks []Callback
|
||||
type Closer interface {
|
||||
Close(ctx context.Context) error
|
||||
}
|
||||
|
||||
func New() *Closer {
|
||||
return &Closer{}
|
||||
type CloserFunc func(ctx context.Context) error
|
||||
|
||||
func (cf CloserFunc) Close(ctx context.Context) error {
|
||||
return cf(ctx)
|
||||
}
|
||||
|
||||
func (receiver *Closer) Add(callback Callback) {
|
||||
receiver.mutex.Lock()
|
||||
defer receiver.mutex.Unlock()
|
||||
|
||||
receiver.callbacks = append(receiver.callbacks, callback)
|
||||
type CloserGroup struct {
|
||||
closers []Closer
|
||||
}
|
||||
|
||||
func (receiver *Closer) Close(ctx context.Context) error {
|
||||
receiver.mutex.Lock()
|
||||
defer receiver.mutex.Unlock()
|
||||
func NewCloserGroup() *CloserGroup {
|
||||
return &CloserGroup{}
|
||||
}
|
||||
|
||||
complete := make(chan struct{}, 1)
|
||||
func (cg *CloserGroup) Add(c Closer) {
|
||||
cg.closers = append(cg.closers, c)
|
||||
}
|
||||
|
||||
go func() {
|
||||
for index, callback := range receiver.callbacks {
|
||||
if err := callback(ctx); err != nil {
|
||||
log.Printf("[! (%d)] %v", index, err)
|
||||
}
|
||||
func (cg *CloserGroup) Call(ctx context.Context) error {
|
||||
var closeErr error
|
||||
for i := len(cg.closers) - 1; i >= 0; i-- {
|
||||
if err := cg.closers[i].Close(ctx); err != nil && closeErr == nil {
|
||||
closeErr = err
|
||||
}
|
||||
|
||||
complete <- struct{}{}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-complete:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("shutdown cancelled: %v", ctx.Err())
|
||||
}
|
||||
return closeErr
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
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
|
||||
}
|
23
pkg/env/parse.go
vendored
23
pkg/env/parse.go
vendored
@ -1,23 +0,0 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
envLoader "github.com/joho/godotenv"
|
||||
envParser "github.com/sethvargo/go-envconfig"
|
||||
)
|
||||
|
||||
func Parse[T interface{}](envFilePath string) (*T, error) {
|
||||
var configuration T
|
||||
|
||||
if err := envLoader.Load(envFilePath); err != nil {
|
||||
log.Printf("load local env file error: %s", err.Error())
|
||||
}
|
||||
if err := envParser.Process(context.Background(), &configuration); err != nil {
|
||||
return nil, fmt.Errorf("parsing env error: %s", err.Error())
|
||||
}
|
||||
|
||||
return &configuration, nil
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func EncodeBuffer(body interface{}) (*bytes.Buffer, error) {
|
||||
buffer := new(bytes.Buffer)
|
||||
|
||||
if err := json.NewEncoder(buffer).Encode(body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buffer, nil
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package mongo
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type Configuration struct {
|
||||
Host string `env:"MONGO_HOST,default=localhost"`
|
||||
Port string `env:"MONGO_PORT,default=27017"`
|
||||
User string `env:"MONGO_USER,required"`
|
||||
Password string `env:"MONGO_PASSWORD,required"`
|
||||
Auth string `env:"MONGO_AUTH,required"`
|
||||
DatabaseName string `env:"MONGO_DB_NAME,required"`
|
||||
}
|
||||
|
||||
type RequestSettings struct {
|
||||
Driver *mongo.Collection
|
||||
Options *options.FindOptions
|
||||
Filter primitive.M
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
package mongo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/event"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type ConnectDeps struct {
|
||||
Configuration *Configuration
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
func Connect(ctx context.Context, deps *ConnectDeps) (*mongo.Database, error) {
|
||||
if deps == nil {
|
||||
return nil, ErrEmptyArgs
|
||||
}
|
||||
|
||||
mongoURI := &url.URL{
|
||||
Scheme: "mongodb",
|
||||
Host: net.JoinHostPort(deps.Configuration.Host, deps.Configuration.Port),
|
||||
}
|
||||
|
||||
cmdMonitor := &event.CommandMonitor{
|
||||
Started: func(_ context.Context, evt *event.CommandStartedEvent) {
|
||||
log.Println(evt.Command)
|
||||
},
|
||||
Succeeded: func(_ context.Context, evt *event.CommandSucceededEvent) {
|
||||
log.Println(evt.Reply)
|
||||
},
|
||||
Failed: func(_ context.Context, evt *event.CommandFailedEvent) {
|
||||
log.Println(evt.Failure)
|
||||
},
|
||||
}
|
||||
|
||||
connectionOptions := options.Client().
|
||||
ApplyURI(mongoURI.String()).
|
||||
SetAuth(options.Credential{
|
||||
AuthMechanism: "SCRAM-SHA-1",
|
||||
AuthSource: deps.Configuration.Auth,
|
||||
Username: deps.Configuration.User,
|
||||
Password: deps.Configuration.Password,
|
||||
}).
|
||||
SetMonitor(cmdMonitor)
|
||||
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
timeoutExceeded := time.After(deps.Timeout)
|
||||
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
connection, err := mongo.Connect(ctx, connectionOptions)
|
||||
if err == nil {
|
||||
return connection.Database(deps.Configuration.DatabaseName), nil
|
||||
}
|
||||
|
||||
log.Printf("failed to connect to db <%s>: %s", mongoURI.String(), err.Error())
|
||||
case <-timeoutExceeded:
|
||||
return nil, fmt.Errorf("db connection <%s> failed after %d timeout", mongoURI, deps.Timeout)
|
||||
default:
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package mongo
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrEmptyArgs = errors.New("arguments are empty")
|
||||
)
|
@ -1,55 +0,0 @@
|
||||
package mongo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
)
|
||||
|
||||
func Find[T any](ctx context.Context, settings *RequestSettings) ([]T, error) {
|
||||
if settings == nil {
|
||||
return []T{}, ErrEmptyArgs
|
||||
}
|
||||
|
||||
results := make([]T, 0)
|
||||
|
||||
cursor, err := settings.Driver.Find(ctx, settings.Filter, settings.Options)
|
||||
if err != nil {
|
||||
return []T{}, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := cursor.Close(ctx); err != nil {
|
||||
log.Printf("failed to close cursor: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
for cursor.Next(ctx) {
|
||||
result := new(T)
|
||||
|
||||
if err := cursor.Decode(result); err != nil {
|
||||
return []T{}, err
|
||||
}
|
||||
|
||||
results = append(results, *result)
|
||||
}
|
||||
|
||||
if err := cursor.Err(); err != nil {
|
||||
return []T{}, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func FindOne[T any](ctx context.Context, settings *RequestSettings) (*T, error) {
|
||||
if settings == nil {
|
||||
return nil, ErrEmptyArgs
|
||||
}
|
||||
|
||||
result := new(T)
|
||||
|
||||
if err := settings.Driver.FindOne(ctx, settings.Filter).Decode(result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
@ -4,10 +4,9 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
mongopkg "gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
)
|
||||
|
||||
type MongoHelper struct {
|
||||
@ -26,15 +25,15 @@ func NewMongoHelper(ctx context.Context, config *mongopkg.Configuration) (*Mongo
|
||||
return &MongoHelper{collection: database.Collection("payments")}, nil
|
||||
}
|
||||
|
||||
func (receiver *MongoHelper) GetPayments(ctx context.Context) ([]models.Payment, error) {
|
||||
func (h *MongoHelper) GetPayments(ctx context.Context) ([]models.Payment, error) {
|
||||
return mongopkg.Find[models.Payment](ctx, &mongopkg.RequestSettings{
|
||||
Driver: receiver.collection,
|
||||
Driver: h.collection,
|
||||
Filter: bson.M{},
|
||||
})
|
||||
}
|
||||
|
||||
func (receiver *MongoHelper) Clear(ctx context.Context) error {
|
||||
if _, err := receiver.collection.DeleteMany(ctx, bson.M{}); err != nil {
|
||||
func (h *MongoHelper) Clear(ctx context.Context) error {
|
||||
if _, err := h.collection.DeleteMany(ctx, bson.M{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/array"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/tests/data"
|
||||
"gitea.pena/PenaSide/treasurer/tests/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func TestCreatePaymentAlfaClick(t *testing.T) {
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/array"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/tests/data"
|
||||
"gitea.pena/PenaSide/treasurer/tests/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func TestCreatePaymentBankCard(t *testing.T) {
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/array"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/tests/data"
|
||||
"gitea.pena/PenaSide/treasurer/tests/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func TestCreatePaymentCash(t *testing.T) {
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/array"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/tests/data"
|
||||
"gitea.pena/PenaSide/treasurer/tests/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func TestCreatePaymentInstallments(t *testing.T) {
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/array"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/tests/data"
|
||||
"gitea.pena/PenaSide/treasurer/tests/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func TestCreatePaymentMobile(t *testing.T) {
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/array"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/tests/data"
|
||||
"gitea.pena/PenaSide/treasurer/tests/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func TestCreatePaymentQIWI(t *testing.T) {
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/array"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/tests/data"
|
||||
"gitea.pena/PenaSide/treasurer/tests/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func TestCreatePaymentSberpay(t *testing.T) {
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/array"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/tests/data"
|
||||
"gitea.pena/PenaSide/treasurer/tests/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func TestCreatePaymentSBP(t *testing.T) {
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/array"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/tests/data"
|
||||
"gitea.pena/PenaSide/treasurer/tests/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func TestCreatePaymentTinkoff(t *testing.T) {
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models"
|
||||
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
||||
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/array"
|
||||
"gitea.pena/PenaSide/treasurer/pkg/mongo"
|
||||
"gitea.pena/PenaSide/treasurer/tests/data"
|
||||
"gitea.pena/PenaSide/treasurer/tests/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/walkerus/go-wiremock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func TestCreatePaymentYoomoney(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user