diff --git a/api/openapi/v1/openapi.yaml b/api/openapi/v1/openapi.yaml
index fdf1340..c9857a6 100644
--- a/api/openapi/v1/openapi.yaml
+++ b/api/openapi/v1/openapi.yaml
@@ -519,6 +519,23 @@ paths:
schema:
$ref: "#/components/schemas/Error"
+ /wallet/rspay:
+ post:
+ summary: Обработка запроса RSPay
+ security:
+ - Bearer: [ ]
+ responses:
+ '200':
+ description: Успех
+ '500':
+ description: Внутренняя ошибка сервера
+ '403':
+ description: Запрещено
+ content:
+ application/json:
+ example:
+ message: not allowed for non organizations
+
/history:
get:
tags:
diff --git a/cmd/app/main.go b/cmd/app/main.go
index c24ec01..13a61ca 100644
--- a/cmd/app/main.go
+++ b/cmd/app/main.go
@@ -4,8 +4,6 @@ import (
"encoding/json"
"fmt"
"log"
- "os"
- "path/filepath"
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/app"
@@ -17,15 +15,8 @@ func main() {
if err != nil {
log.Fatalf("failed to init zap logger: %v", err)
}
- // todo убрать
- currentDir, err := os.Getwd()
- if err != nil {
- logger.Fatal("failed to get current directory: %v", zap.Error(err))
- }
- envFilePath := filepath.Join(currentDir, "deployments", "local", ".env.test")
-
- config, err := initialize.Configuration(envFilePath)
+ config, err := initialize.Configuration(".env.test")
if err != nil {
logger.Fatal("failed to init config: %v", zap.Error(err))
}
diff --git a/deployments/local/.env.test b/deployments/local/.env.test
index 7a26c62..99cfd19 100644
--- a/deployments/local/.env.test
+++ b/deployments/local/.env.test
@@ -4,7 +4,7 @@ JWT_AUDIENCE="pena"
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm69\n80fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6B\ndA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y\n+3GyaOY536H47qyXAgMBAAE=\n-----END PUBLIC KEY-----"
HTTP_HOST=0.0.0.0
-HTTP_PORT=8000
+HTTP_PORT=8003
GRPC_HOST=0.0.0.0
GRPC_PORT=9000
@@ -20,10 +20,16 @@ MONGO_AUTH=admin
KAFKA_BROKERS=localhost:9092
KAFKA_TOPIC_TARIFF=tariffs
-AUTH_MICROSERVICE_USER_URL=http://localhost:8002/user
+AUTH_MICROSERVICE_USER_URL=http://localhost:8000/user
HUBADMIN_MICROSERVICE_TARIFF_URL=http://localhost:8001/tariff
CURRENCY_MICROSERVICE_TRANSLATE_URL=http://cbrfworker-service:8000/change
DISCOUNT_MICROSERVICE_GRPC_HOST=localhost:9040
PAYMENT_MICROSERVICE_GRPC_HOST=treasurer-service:9085
VERIFICATION_MICROSERVICE_USER_URL=http://10.8.0.8:7035/verification
-TEMPLATEGEN_MICROSERVICE_URL=10.6.0.17
\ No newline at end of file
+TEMPLATEGEN_MICROSERVICE_URL=10.6.0.17
+
+API_URL=https://api.smtp.bz/v1/smtp/send
+MAIL_SENDER=noreply@mailing.pena.digital
+MAIL_API_KEY=P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev
+MAIL_AUTH_USERNAME=kotilion.95@gmail.com
+MAIL_AUTH_PASSWORD=vWwbCSg4bf0p
\ No newline at end of file
diff --git a/go.mod b/go.mod
index af6aacf..42a25ac 100644
--- a/go.mod
+++ b/go.mod
@@ -6,6 +6,7 @@ require (
github.com/deepmap/oapi-codegen v1.12.4
github.com/getkin/kin-openapi v0.116.0
github.com/go-resty/resty/v2 v2.7.0
+ github.com/gofiber/fiber/v2 v2.52.0
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/joho/godotenv v1.5.1
@@ -24,6 +25,7 @@ require (
)
require (
+ github.com/andybalholm/brotli v1.0.5 // indirect
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
@@ -31,34 +33,38 @@ require (
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
- github.com/google/uuid v1.4.0 // indirect
+ github.com/google/uuid v1.5.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/invopop/yaml v0.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
- github.com/klauspost/compress v1.16.7 // indirect
+ github.com/klauspost/compress v1.17.0 // 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.20 // indirect
+ github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/perimeterx/marshmallow v1.1.4 // indirect
github.com/pierrec/lz4/v4 v4.1.17 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/rivo/uniseg v0.2.0 // indirect
github.com/twmb/franz-go/pkg/kmsg v1.4.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
+ github.com/valyala/fasthttp v1.51.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // 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-20181117223130-1be2e3e5546d // indirect
go.uber.org/multierr v1.11.0 // indirect
- golang.org/x/crypto v0.12.0 // indirect
- golang.org/x/net v0.14.0 // indirect
+ golang.org/x/crypto v0.14.0 // indirect
+ golang.org/x/net v0.17.0 // indirect
golang.org/x/sync v0.5.0 // indirect
- golang.org/x/sys v0.14.0 // indirect
- golang.org/x/text v0.12.0 // indirect
+ golang.org/x/sys v0.15.0 // indirect
+ golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index dd7292c..d8f5036 100644
--- a/go.sum
+++ b/go.sum
@@ -1,6 +1,8 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
+github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
+github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
@@ -33,6 +35,8 @@ github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSM
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.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE=
+github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
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=
@@ -55,8 +59,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
-github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
+github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
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=
@@ -71,8 +75,8 @@ github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPci
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.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
-github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
+github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -97,6 +101,8 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
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.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
@@ -113,6 +119,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
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=
@@ -145,9 +153,13 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
+github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
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/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
+github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
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.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
@@ -176,8 +188,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
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.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
-golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
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=
@@ -198,8 +210,8 @@ 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.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
-golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
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=
@@ -225,8 +237,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
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.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
-golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
+golang.org/x/sys v0.15.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=
@@ -235,8 +247,8 @@ 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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
-golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/internal/app/app.go b/internal/app/app.go
index d527232..301553d 100644
--- a/internal/app/app.go
+++ b/internal/app/app.go
@@ -75,6 +75,7 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
PaymentServiceConfiguration: &config.Service.PaymentMicroservice,
VerificationURL: &config.Service.VerificationMicroservice.URL,
TemplategenURL: &config.Service.TemplategenMicroserviceURL.URL,
+ MailClient: &config.Service.Mail,
})
repositories := initialize.NewRepositories(initialize.RepositoriesDeps{
diff --git a/internal/initialize/clients.go b/internal/initialize/clients.go
index e991489..0e65e70 100644
--- a/internal/initialize/clients.go
+++ b/internal/initialize/clients.go
@@ -1,6 +1,7 @@
package initialize
import (
+ "github.com/gofiber/fiber/v2"
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
@@ -15,6 +16,7 @@ type ClientsDeps struct {
PaymentServiceConfiguration *models.PaymentMicroserviceConfiguration
VerificationURL *models.VerificationMicroserviceURL
TemplategenURL *models.TemplategenMicroserviceURL
+ MailClient *models.MailConfiguration
}
type Clients struct {
@@ -25,6 +27,7 @@ type Clients struct {
PaymentClient *client.PaymentClient
VerificationClient *client.VerificationClient
TemplateClient *client.TemplateClient
+ MailClient *client.MailClient
}
func NewClients(deps ClientsDeps) *Clients {
@@ -57,5 +60,17 @@ func NewClients(deps ClientsDeps) *Clients {
Logger: deps.Logger,
URLs: deps.TemplategenURL,
}),
+ MailClient: client.NewMailClient(client.MailClientDeps{
+ Logger: deps.Logger,
+ ApiUrl: deps.MailClient.ApiUrl,
+ Sender: deps.MailClient.Sender,
+ Auth: &models.PlainAuth{
+ Identity: deps.MailClient.Auth.Identity,
+ Username: deps.MailClient.Auth.Username,
+ Password: deps.MailClient.Auth.Password,
+ },
+ ApiKey: deps.MailClient.ApiKey,
+ FiberClient: fiber.AcquireClient(),
+ }),
}
}
diff --git a/internal/initialize/services.go b/internal/initialize/services.go
index a7ee20a..c260b82 100644
--- a/internal/initialize/services.go
+++ b/internal/initialize/services.go
@@ -40,10 +40,13 @@ func NewServices(deps ServicesDeps) *Services {
})
walletService := wallet.New(wallet.Deps{
- Logger: deps.Logger,
- Repository: deps.Repositories.AccountRepository,
- CurrencyClient: deps.Clients.CurrencyClient,
- HistoryService: historyService,
+ Logger: deps.Logger,
+ Repository: deps.Repositories.AccountRepository,
+ CurrencyClient: deps.Clients.CurrencyClient,
+ VerificationClient: deps.Clients.VerificationClient,
+ AuthClient: deps.Clients.AuthClient,
+ MailClient: deps.Clients.MailClient,
+ HistoryService: historyService,
})
tariffBrokerService := tariff.New(tariff.Deps{
diff --git a/internal/interface/client/mail.go b/internal/interface/client/mail.go
new file mode 100644
index 0000000..eb22922
--- /dev/null
+++ b/internal/interface/client/mail.go
@@ -0,0 +1,88 @@
+package client
+
+import (
+ "bytes"
+ "fmt"
+ "github.com/gofiber/fiber/v2"
+ "go.uber.org/zap"
+ "mime/multipart"
+ "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
+ "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
+)
+
+type MailClientDeps struct {
+ ApiUrl string
+ Sender string
+ Auth *models.PlainAuth
+ ApiKey string
+ FiberClient *fiber.Client
+ Logger *zap.Logger
+}
+
+type MailClient struct {
+ deps MailClientDeps
+}
+
+func NewMailClient(deps MailClientDeps) *MailClient {
+ if deps.FiberClient == nil {
+ deps.FiberClient = fiber.AcquireClient()
+ }
+ return &MailClient{
+ deps: deps,
+ }
+}
+
+func (receiver *MailClient) SendMessage(userEmail string, verification *models.Verification) errors.Error {
+ body := fmt.Sprintf("
Поступила заявка на оплату через Р/С от пользователя с почтой %s (%s)
"+
+ "Вот файлы его верификации:
", userEmail, verification.UserID)
+
+ for _, file := range verification.Files {
+ body += fmt.Sprintf("%s: %s
", file.Name, file.URL, file.URL)
+ }
+
+ form := new(bytes.Buffer)
+ writer := multipart.NewWriter(form)
+ defer writer.Close()
+
+ fields := map[string]string{
+ "from": receiver.deps.Sender,
+ "to": "pashamullin202@gmail.com",
+ "subject": "Новая заявка на оплату через Р/С",
+ "html": body,
+ }
+
+ for key, value := range fields {
+ if err := writer.WriteField(key, value); err != nil {
+ return handleError(receiver.deps.Logger, "Error writing form field", err)
+ }
+ }
+
+ if err := writer.Close(); err != nil {
+ return handleError(receiver.deps.Logger, "Error closing form writer", err)
+ }
+
+ req := receiver.deps.FiberClient.Post(receiver.deps.ApiUrl).Body(form.Bytes()).ContentType(writer.FormDataContentType())
+ if receiver.deps.ApiKey != "" {
+ req.Set("Authorization", receiver.deps.ApiKey)
+ }
+
+ statusCode, _, errs := req.Bytes()
+ if errs != nil {
+ return handleError(receiver.deps.Logger, "Error sending request", errs[0])
+ }
+
+ if statusCode != fiber.StatusOK {
+ err := fmt.Errorf("the SMTP service returned an error: %s", statusCode)
+ return handleError(receiver.deps.Logger, "Error sending email", err)
+ }
+
+ return nil
+}
+
+func handleError(logger *zap.Logger, message string, err error) errors.Error {
+ logger.Error(message, zap.Error(err))
+ return errors.New(
+ fmt.Errorf("failed to send email on of : %w", err),
+ errors.ErrInternalError,
+ )
+}
diff --git a/internal/interface/client/verification.go b/internal/interface/client/verification.go
index 5093359..478cd5a 100644
--- a/internal/interface/client/verification.go
+++ b/internal/interface/client/verification.go
@@ -51,6 +51,9 @@ func (receiver *VerificationClient) GetVerification(ctx context.Context, userID
Headers: map[string]string{"Content-Type": "application/json"},
})
if err != nil {
+ if response.StatusCode == 404 {
+ return nil, errors.New(err, errors.ErrNotFound)
+ }
return nil, errors.New(err, errors.ErrInternalError)
}
diff --git a/internal/interface/controller/rest/wallet/wallet.go b/internal/interface/controller/rest/wallet/wallet.go
index c883440..a424095 100644
--- a/internal/interface/controller/rest/wallet/wallet.go
+++ b/internal/interface/controller/rest/wallet/wallet.go
@@ -121,3 +121,27 @@ func (receiver *Controller) GetPaymentLink(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, &models.GetPaymentLinkResponse{Link: link})
}
+
+func (receiver *Controller) PostWalletRspay(ctx echo.Context) error {
+ userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
+ if !ok {
+ receiver.logger.Error("failed to convert jwt payload to string on of ")
+
+ return errors.HTTP(ctx, errors.New(
+ fmt.Errorf("failed to convert jwt payload to string: %s", userID),
+ errors.ErrInvalidArgs,
+ ))
+ }
+
+ if err := receiver.walletService.PostWalletRspay(ctx.Request().Context(), userID); err != nil {
+ if err == errors.ErrNoAccess {
+ return errors.HTTP(ctx, err)
+ }
+ return errors.HTTP(ctx, errors.New(
+ fmt.Errorf("failed to process rspay: %w", err),
+ errors.ErrInternalError,
+ ))
+ }
+
+ return ctx.NoContent(http.StatusOK)
+}
diff --git a/internal/interface/swagger/api.2.go b/internal/interface/swagger/api.2.go
index 68271ec..931529c 100644
--- a/internal/interface/swagger/api.2.go
+++ b/internal/interface/swagger/api.2.go
@@ -46,6 +46,7 @@ type clients struct {
payment *client.PaymentClient
verify *client.VerificationClient
template *client.TemplateClient
+ mail *client.MailClient
}
var _ ServerInterface = (*API2)(nil)
@@ -597,7 +598,6 @@ func (api *API2) ChangeCurrency(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, updatedAccount)
}
-// todo need tests
func (api *API2) CalculateLTV(ctx echo.Context) error {
var req CalculateLTVJSONBody
@@ -749,3 +749,41 @@ func (api *API2) SendReport(ctx echo.Context) error {
return ctx.NoContent(http.StatusOK)
}
+
+func (api *API2) PostWalletRspay(ctx echo.Context) error {
+ userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
+ if !ok {
+ return api.noauth(ctx)
+ }
+
+ user, err := api.account.FindByUserID(ctx.Request().Context(), userID)
+ if err != nil {
+ return api.errorOld(ctx, err)
+ }
+
+ if user.Status != models.AccountStatusNko && user.Status != models.AccountStatusOrg {
+ return api.error(ctx, http.StatusForbidden, "not allowed for non organizations")
+ }
+
+ verification, err := api.clients.verify.GetVerification(ctx.Request().Context(), userID)
+ if err == errors.ErrNotFound {
+ return api.error(ctx, http.StatusForbidden, "no verification data found")
+ }
+
+ if (user.Status == models.AccountStatusOrg && len(verification.Files) != 3) ||
+ (user.Status == models.AccountStatusNko && len(verification.Files) != 4) {
+ return api.error(ctx, http.StatusForbidden, "not enough verification files")
+ }
+
+ authData, err := api.clients.auth.GetUser(ctx.Request().Context(), userID)
+ if err != nil {
+ return api.errorOld(ctx, err)
+ }
+
+ err = api.clients.mail.SendMessage(authData.Login, verification)
+ if err != nil {
+ return api.errorOld(ctx, err)
+ }
+
+ return ctx.NoContent(http.StatusOK)
+}
diff --git a/internal/interface/swagger/api.gen.go b/internal/interface/swagger/api.gen.go
index a98df6c..2e4485b 100644
--- a/internal/interface/swagger/api.gen.go
+++ b/internal/interface/swagger/api.gen.go
@@ -77,6 +77,9 @@ type ServerInterface interface {
// Запрос на получение ссылки на оплату
// (POST /wallet)
RequestMoney(ctx echo.Context) error
+ // Обработка запроса RSPay
+ // (POST /wallet/rspay)
+ PostWalletRspay(ctx echo.Context) error
}
// ServerInterfaceWrapper converts echo contexts to parameters.
@@ -374,6 +377,17 @@ func (w *ServerInterfaceWrapper) RequestMoney(ctx echo.Context) error {
return err
}
+// PostWalletRspay converts echo context to params.
+func (w *ServerInterfaceWrapper) PostWalletRspay(ctx echo.Context) error {
+ var err error
+
+ ctx.Set(BearerScopes, []string{})
+
+ // Invoke the callback with all the unmarshaled arguments
+ err = w.Handler.PostWalletRspay(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
@@ -421,87 +435,89 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
router.POST(baseURL+"/sendReport", wrapper.SendReport)
router.PATCH(baseURL+"/wallet", wrapper.ChangeCurrency)
router.POST(baseURL+"/wallet", wrapper.RequestMoney)
+ router.POST(baseURL+"/wallet/rspay", wrapper.PostWalletRspay)
}
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "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",
- "WKMkDmpVAAA=",
+ "H4sIAAAAAAAC/+xcbXMbR3L+K1ObfDhXViBI0dGZ32TKlyh19rn05lKJrLslMCD3BOzCuwvLjAtVJGCL",
+ "VlEWI+dScV0s+ey7qnxLQIgQQRIA/0LPP0p1z+z7gAQpihJj31XJILC7M9MvTz/d07NfGCW3Vncd7gS+",
+ "MfeF4ZdWeM2ij1dLJbfhBPix7rl17gU2px9+b5fxP/xzq1avcmPO+HXxSmW6cuXKUqny6+lS+cp7781e",
+ "fq84PW2YRrBaxyv8wLOdZaNpGiXLC1J33zvq9jE/zRiLpmEHvEbzyY2hvrA8z1qlMT1uBbx8lQauuF7N",
+ "Cow5o2wF/FJg17hummVe5Se8xfavyZtSy6tYVZ9HVy+5bpVbDl7uWDWOV/69xyvGnPF3U7EippQWpj7C",
+ "a5qm4QdW0PCPu1op7Ka8uGkajXr5pOtu+Ny7/grqfWBVqzw4bqafyKuaTdPw+KcN20Oh3SPDiqagTCV6",
+ "pJJYJIxIR0ZSwclFL0bzc5f+yEsBzi8tI1ym06jh2I6LI9zHf11vOXFvvLb3Lef+vOWV8x5Rsrzyilst",
+ "cw//KnO/5Nn1wHYdY86A72Agthh04QA6sAM9OBCPxUPoMNiHjlgTLbFpmAlxX79z9SOG//zujtaB/JJm",
+ "kD/DCHbY/J35GQZ9OIA+m79zZ8Zkl8M/Z5lYhz4MoAsjnInJ4BB6YgM6ogUd6ImWWMdpDnFiI9gWa/TL",
+ "EEawx8S6aMFIrMEIhtAbN/Hiu7r58s/rtrf6oesEK5p5fw89HFc8ZNCnUXBKPRhCX2zhsDjkfkpW7Fcf",
+ "fvjOxOPe5ZZOJ/9O4pp8yLt3795NDzpTnNE6gNOoLWnN4BmMYAA9sTZOfDduv59/YMZD1NNTq0uLWGf0",
+ "H3ie6+WttsZ931rmaWdH72OOG7CK23DKuhVK/5t3y+k7Z4uzZgwythP842x8t+0EfJl7ufWU8ClmNBPd",
+ "5P/Z9gPXW9U4nVurcScdTAxU4TdorGju5GzQgQO09RF+CwPRZmKDLpid0brX+cSKV4DYE8YZz3pwjQeW",
+ "XfU1Rvm/JBlp7uTZAxjBC9FmcCjWoAc79PMBjOAl9EVLPDbJemEf+nj1tmjDjmiLFhNfIs6Ix6Il1sQm",
+ "PTV0L8SNPvRNqYRvIjVEQ6CKXkBHPGHQDbXH1MA9edlIPgkHP4AO/iEeEypJb0WlrrM/+q5TYAy+g228",
+ "dAcOENBwui9hB9eFVtGCPhzicnehA4c4RegzwrUOmkwXRmKrkPLLLxaMwPLsSsVfMObuLYzV1YJhHvXj",
+ "YlOnTPlF0hRKDT9wa9wryEE/cMpc64bnHtwzrpuO1XTt8SHZjLzWNPyG9HGd03+kyFHa4yu25wchb4qX",
+ "AN9BFzow1C25ZpfLVT7+HhhBF/piQ3ev6y1rbnyO/2cLCwsYvEZoYc/R3lRw7OAPWtTkJdcpHz0Rrcxz",
+ "svnYWkUJ3gotRxGYpZCdmEZgO/fdSgX5imEan9oPbBT3EveW5DerrltzHb6KyOsu2VXUnO34gVWt1igR",
+ "QO7lr9BNdcM0lmaWbsZ3W9WKRR91HOkWGe31a3nlye9OaXg5IXwS8cwsE/N1NONH0YYBDKDDaOGS+yD6",
+ "dBGBxFMYou5C/oOcAEFFPII+7DH6uCbWk6gwXbxSnJ4g3plGqeF53Cmtamb1k3YYRgZxIJ5MxhBQh6jL",
+ "/OP/hKxGPIYXiHAS35DpiBaCbxeRcYRygD0iJF8VGPw3gfM2ATiidiQnsY73iqfIFcVXKlYgk9xF3kQY",
+ "eyAxF4lUD14g7ZS/YdzdxzgBnYIME/uIuWJNtKEHA8k69xGCdxTbjNcPPTPEZhlrcPb4+xCDDilwSOPt",
+ "mUxNRMWWnniqZqniG7zE0U6nwnrDK61YPvev1sKMOCPq57AtHpEBifXI1GJpUNQcyVgoNqXshuIp6prC",
+ "nHgMu4REHTK9A/HYmGhifp2fYDrEgYjXS747FJuoy4TOdvGyrlhH4XVJvAP1DPGIjKBFSpeAhXSZqABa",
+ "TxuGaBvGKShg6B8R6ITYlBV7uN58wJD42vDsYPUmppgSC97nliep+BJ9+k04s3/55BbFqqTMPnAC7rFg",
+ "hbPAvc8d9sAOVujPP8jHzLE/sLrHK/bnJuOF5QJbUM9n1lKpzKdnLs++u2Agc6Akl0iYHD+a7UoQ1I0m",
+ "TtZ2Kq5ebQl6QwbTVZkZfSJjl1Soj2QFXbNLFKbDLsV8Sl7RoYyT8prQDfJ29oSJL1F3sC8eoq+iq+EU",
+ "pL2uwS700UwYQgF+87W0TlR5gQJNQMA0rzgLu5SaVsjBRJvmlpiRJGYHODVpODCAvmEan3HPl8KYLhQL",
+ "RYrCde5YdduYMy4XigUMD3UrWCEFT1lxiUoyD41QD1XetSGz3IzJMolMcCBjgNgkjMCIYuEDkC0Zkm6H",
+ "5TC0Xr/uOr40spliUSYjTqB80arXq3aJbp9CShqX1SYs4EgbSS9DtMU6gfHXBJK9aN6xhrOu2DSN2eL0",
+ "mU1OJpGaqcEz6KFuI6q/G0JEyjGNuXuxS95bbC4iA6zVLEztjGg1fcXsKQwlzF5sYmBILRHtz1r2EUNC",
+ "O1hsmsYy1yHidyQ+5QIYecJ6h4pzuxjXKAb1mHgCu2TEHUpI1sMyAUaWAoN/gz3YgT5pog/7qcvlEO3Y",
+ "2Pqwyyio7tM6OplIsBczkR3oYHyVs+rK/OSFSr66eDuzGsGK69n/StrLWek/8eAtM9GENJSRvhU2iVOY",
+ "PYcp/ETmKtPOMfBLfLMnWpM7CvyQlWmSrfbkYBkkSFjoGJ+pW0FpRVu63EXshKHYCs2ZapmST8JuyARQ",
+ "2SjnF+pP9CaMJ/2xC8+Z7/yK5SynQPbTBveD993y6pnpSpbTNar6Xno+TpTWKGVL1ZO3AuvXiWnvxMK+",
+ "yFgPzxV1x/XsI5eh3JmMA+U/CcjXXV+H8j+GckIkZTKp1kSOiJdEfmFixrBOhXJiI5Hf9sSjKJPYFpuI",
+ "xjnTvVouv23k4P+XwcRqJQMZp1atrTTNiCZOfSHLVc0j+eL3iHRyewCzIuQhkhgg9tGgXQS7dVU7wn8H",
+ "MsRLYjxiCj/QwF9K84KBmeDCCd6W48FjyOc12+OlRHyvW55V4wH3fJJcegnXr+nyMht/Quoc7qTNxdW7",
+ "OB8LvAY3E0rPlmIW34yFw18vJP09L6rxjKJzGrnGBd7J3e6vKU6ehdBDyTSIC5+Iir9mB8uyTvxKAqGq",
+ "d4zSLtfTMelf/O1YLv+Lx529x8XkfrzPobWNyyZSueomIw/ph1XVtMQUQT9pQjAmjU4Vo9BfqXC1Bn1Z",
+ "8I3TAeWjXbGZLVLJQmOLgnybSlr6Z5hMbOFdMiWR6TLxNkXmGDyDP8Nzk8H/4B//BX3xUE5JNkLA3ygp",
+ "j3/I+f/NKJO+wz27okznZth28max4HRZUXqT5FTtRPldmGaz+bagk8aeiAYn7emig8O3E6xxjM8cx4xJ",
+ "efpona1okeSll+9nTX2EkZs2mtq05bIrw27UQkSRekh+12P/wGSf0SPoyZaiEVGNjXifQfP4nK9+bC3b",
+ "Dv15NVzKMR6aaMRJz0ls0iZSB9FX7QaKdTYt+2uq1O6imizInT9tcG819ue6tcyNpPeWecVqVANjblq3",
+ "BZKdFU1jd8y8JpxC1a7ZwZg5FIuaWbwquUijStKWot7MiTw837EZuIFV/dhalk+Ot+y0sszj0ilKkzmh",
+ "66yPnDUuWoeusK+1VSa39zrwQtnTQ+Kce2OdMWyNjVPTtK3f4DX3M/4bz63Ny87IjJ3rbMI+OsScajv+",
+ "jXHSRMo3kqX19DbVz42ByirsntzBjePNHn2UUeDk6R7yKsmWsuJNPja2YbLaozjjs2ySR+FQ1fxksKLG",
+ "MtWWp11GZg9aMk9dIW6m9LN0jT+hhBPMYBQ2eETaa//iHK/iHAkBhw6SFfCR7hHi+1Tdkq2s+gL2f0In",
+ "7HdUrdiRo6g+DbnXAofUKNDCMJWGwDxBWlXR4o1Xpqm/Kpp6rsngYtWk43WoVH2fitTS1fTql40uii0p",
+ "tp2rPM3HV72iyhInbGTj2O2b1wzTmL967SSnZ05LpiJq1En0c2UIVOLGaN8/kVyMqGt3O2zzktW7+FkJ",
+ "IYctRBSGGhrB3qYO1IxsT5dKn5VYmxdGvYh8shZ7cLyCz8mHb1uO6obg5RN5bbQUtaX96iaHvr0SH1IY",
+ "59jhOYYLmZ7CX95AempqGmb7cBh2B20S9m5NOLpqUB9fXTM13Q87ao8gLqdQyMiV+AoM/kNtH9NWcbL+",
+ "YaZaV/vJAmq86y3LmP3xA2b7iAoTLltlmNevGa9zlyFdCPB4yfXKk9cBQs94/XWASbY1ktYFexeLlOSb",
+ "g6h97IU825JYFh11EVthhY5wDilntogxSEBeiHEpxJuqBp8l+WymqceqlhpVK+C/vXXHOKvqdcVza9o0",
+ "s0NFSvQsxTV3Qp7ZZeJLEutAVl7Zbcf+nAV2jfuBVasn3LdoMgyAlC4MVULVJz30ZEeJGiR3vKkwWcd2",
+ "4I45vDmkFtXXNfFUj1gv0dxdOEXHNimAlrI4ic/9IJN8ueOrmiDWqMuZDiNAh8XWEafizTOFJGWluVMh",
+ "sg1peEQJWv66J/ecX8IOHVyTm11ik+oksrF+ncjRDrndgEXJAd4j3WgSKZ8IwGivPClJkiPhVfGc8ErW",
+ "b1Rz7m6cuybaqdBYGGzLkCe+hp7JCJ4GLHDfkpLEu+cir2/Th1bEFmXD4mvowzax6GgPVXZqTo76f0mY",
+ "AJ1fDm2aNp6Uq8uIwOBleDAnslGxFXeOpnqR2K9+e+vOO2MjgMdLSlz6naNvKSHukoU+0u0e0cEDdXgI",
+ "QVtGoaiIIreTqAyZRtqoBTvf6Zrdrgp51W6+n5ooVI6l36BFyVNs/pmFLPsMD10uvoZ92IloWnS0b4Ik",
+ "ModTSXR4OzDqXBvBpUWLTdVJmqhMyrrXRYcgDfEcqg7fLqWJWcceiyo+d8o3eN2VW2ETl0lHohWdMdrH",
+ "GC1bi6MCavgqgIjs4qXbeJum/SOawQX3/2NrsUmhXbSm4OTk424p6pI6RuNhZR1GYkO0UuXatC3GL7MZ",
+ "t7f1Q3R6KLTH0PQzO15zC84lBs+JVVJPJR0hSvS9Z/e/OvKdMeFB2E62NtWhB+YaxqJOR5wHFQ3SxwRL",
+ "S16F/Yq4K146kHPHfGMDvWaoXgQh35WwQWjxWEbV3ZAov6NGjg5QqwOJiWPL7dxpQSZbQ0bQFW160UN8",
+ "bYFhAqQufgr7MstCYW7QTpZ4SJoc0SLXVQ2S8DyUmTyxnOzRV4chiYAPqSy/x5BxtMKnRocoFQ0iNTwh",
+ "IrQXXkbbRdnXVsginDw2Fr7PZYdoxYGctWpND89Ly0PX/fRLdrpyUUN5nHrMWZj5+GDs2aBQ8iR6jEWy",
+ "bHw07MTVzre0CUxWQxXL7aRO0OdM8fzox09jPHkoq+opd/5Zbc/+oD/0nmdHJ4gH0Vm1EAqPgqME5CuQ",
+ "H3+q6BKDv6kaTPTWghTkE7IkYBbHS+zQmkyylHyr+yAqHogWbItvKBUaQD8D7R05YnQcnD5mgT21JyzW",
+ "Gb2xAbFQbnqH7/UKr2mnDqISJA8pEIzSJ1Ij+NecHc/h1g0JUx+q8/tng1pW9M6FuPz7bnGmqKuuLSXe",
+ "0HaUZUZvcjvy/RzXb/7u0uzM9JVUDW6SF3JU3WXbSaMsffX7gPuB7ob6iuvwj6I3h8W3XXmvGP5Pd5/H",
+ "g4bn3Paq6btWgqDuz01N+XbAC15jSvXEjH350FGiSr5tJhsW1J5K4g0OSlmvI0xkCnq2c1+/6GXXXa7i",
+ "sid5kcwJM9fEyzLOL2v7MflChVTnR5jatuEgkceJ9glQU9NwouuMDKGknwcSHZTG5HnK8zMdL5n2FNcP",
+ "5Lt8btCFkyQykYq+khHr8gRKiOwk8do7w3EDZlWr7gNeZhXXY47rMNdbthx1xt7X6iMUWY/Y4hBGCVM4",
+ "t4T7uXxDo0xoJMFOJiEdduPmx2FpRqknN7vs4cn0lqGh2RFV7xYRbTgMc4z0u4rUIyJE0Dwj0fNDcTi8",
+ "BTFqzOVRahBfrkxNc0OiVkibw+qGMLNrLjb/LwAA//9Csvzr9FYAAA==",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/internal/interface/swagger/api.go b/internal/interface/swagger/api.go
index 7257ceb..21378cd 100644
--- a/internal/interface/swagger/api.go
+++ b/internal/interface/swagger/api.go
@@ -31,6 +31,7 @@ type cartController interface {
type walletController interface {
ChangeCurrency(ctx echo.Context) error
GetPaymentLink(ctx echo.Context) error
+ PostWalletRspay(ctx echo.Context) error
}
type historyController interface {
@@ -171,3 +172,7 @@ func (receiver *API) RequestMoney(ctx echo.Context) error {
func (receiver *API) ChangeCurrency(ctx echo.Context) error {
return receiver.walletController.ChangeCurrency(ctx)
}
+
+func (receiver *API) PostWalletRspay(ctx echo.Context) error {
+ return receiver.walletController.PostWalletRspay(ctx)
+}
diff --git a/internal/models/config.go b/internal/models/config.go
index 964683f..f280e8a 100644
--- a/internal/models/config.go
+++ b/internal/models/config.go
@@ -35,6 +35,7 @@ type ServiceConfiguration struct {
TemplategenMicroserviceURL TemplategenMicroserviceConfiguration
JWT JWTConfiguration
Kafka KafkaConfiguration
+ Mail MailConfiguration
}
type KafkaConfiguration struct {
@@ -102,3 +103,16 @@ type VerificationMicroserviceURL struct {
type TemplategenMicroserviceURL struct {
Templategen string `env:"TEMPLATEGEN_MICROSERVICE_URL,required"`
}
+
+type MailConfiguration struct {
+ ApiUrl string `env:"API_URL,required"`
+ Sender string `env:"MAIL_SENDER,required"`
+ Auth PlainAuth
+ ApiKey string `env:"MAIL_API_KEY,required"`
+}
+
+type PlainAuth struct {
+ Identity string `env:"MAIL_AUTH_IDENTITY"`
+ Username string `env:"MAIL_AUTH_USERNAME,required"`
+ Password string `env:"MAIL_AUTH_PASSWORD,required"`
+}
diff --git a/internal/service/history/history.go b/internal/service/history/history.go
index c249cb9..caeacdf 100644
--- a/internal/service/history/history.go
+++ b/internal/service/history/history.go
@@ -46,7 +46,7 @@ type authClient interface {
}
type verificationClient interface {
- GetUser(ctx context.Context, userID string) (*models.Verification, errors.Error)
+ GetVerification(ctx context.Context, userID string) (*models.Verification, errors.Error)
}
type temlategenClient interface {
@@ -198,7 +198,7 @@ func (receiver *Service) GetHistoryByID(ctx context.Context, historyID string) e
return err
}
- verifuser, err := receiver.VerificationClient.GetUser(ctx, tariffs.UserID)
+ verifuser, err := receiver.VerificationClient.GetVerification(ctx, tariffs.UserID)
if err != nil {
receiver.logger.Error("failed to get user verification on of ",
zap.Error(err),
diff --git a/internal/service/wallet/wallet.go b/internal/service/wallet/wallet.go
index e3a8c50..855bcf6 100644
--- a/internal/service/wallet/wallet.go
+++ b/internal/service/wallet/wallet.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log"
+ "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
@@ -20,22 +21,36 @@ type currencyClient interface {
Translate(context.Context, *models.TranslateCurrency) (int64, errors.Error)
}
+type verificationClient interface {
+ GetVerification(ctx context.Context, userID string) (*models.Verification, errors.Error)
+}
+
+type authClient interface {
+ GetUser(ctx context.Context, userID string) (*models.User, errors.Error)
+}
+
type historyService interface {
CreateHistory(ctx context.Context, history *models.History) (*models.History, errors.Error)
}
type Deps struct {
- Logger *zap.Logger
- Repository accountRepository
- CurrencyClient currencyClient
- HistoryService historyService
+ Logger *zap.Logger
+ Repository accountRepository
+ CurrencyClient currencyClient
+ HistoryService historyService
+ VerificationClient verificationClient
+ AuthClient authClient
+ MailClient *client.MailClient
}
type Service struct {
- logger *zap.Logger
- repository accountRepository
- currencyClient currencyClient
- historyService historyService
+ logger *zap.Logger
+ repository accountRepository
+ currencyClient currencyClient
+ historyService historyService
+ verificationClient verificationClient
+ authClient authClient
+ mailClient *client.MailClient
}
func New(deps Deps) *Service {
@@ -51,15 +66,30 @@ func New(deps Deps) *Service {
log.Panicln("CurrencyClient is nil on ")
}
+ if deps.VerificationClient == nil {
+ log.Panicln("VerificationClient is nil on ")
+ }
+
+ if deps.AuthClient == nil {
+ log.Panicln("AuthClient is nil on ")
+ }
+
+ if deps.MailClient == nil {
+ log.Panicln("MailClient is nil on ")
+ }
+
if deps.HistoryService == nil {
log.Panicln("HistoryService is nil on ")
}
return &Service{
- logger: deps.Logger,
- repository: deps.Repository,
- currencyClient: deps.CurrencyClient,
- historyService: deps.HistoryService,
+ logger: deps.Logger,
+ repository: deps.Repository,
+ currencyClient: deps.CurrencyClient,
+ verificationClient: deps.VerificationClient,
+ authClient: deps.AuthClient,
+ mailClient: deps.MailClient,
+ historyService: deps.HistoryService,
}
}
@@ -253,3 +283,48 @@ func (receiver *Service) ChangeCurrency(ctx context.Context, userID string, curr
return updatedAccount, nil
}
+
+func (receiver *Service) PostWalletRspay(ctx context.Context, userID string) errors.Error {
+ user, err := receiver.repository.FindByUserID(ctx, userID)
+ if err != nil {
+ return err
+ }
+ if user.Status != models.AccountStatusNko && user.Status != models.AccountStatusOrg {
+ return errors.New(
+ fmt.Errorf("not allowed for non organizations"),
+ errors.ErrNoAccess,
+ )
+ }
+
+ verification, err := receiver.verificationClient.GetVerification(ctx, userID)
+ if err == errors.ErrNotFound {
+ return errors.New(
+ fmt.Errorf("no verification data found"),
+ errors.ErrNoAccess,
+ )
+ }
+
+ if user.Status == models.AccountStatusOrg && len(verification.Files) != 3 {
+ return errors.New(
+ fmt.Errorf("not enough verification files"),
+ errors.ErrNoAccess,
+ )
+ } else if user.Status == models.AccountStatusNko && len(verification.Files) != 4 {
+ return errors.New(
+ fmt.Errorf("not enough verification files"),
+ errors.ErrNoAccess,
+ )
+ }
+
+ authData, err := receiver.authClient.GetUser(ctx, userID)
+ if err != nil {
+ return err
+ }
+
+ err = receiver.mailClient.SendMessage(authData.Login, verification)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/tests/e2e/rspay_test.go b/tests/e2e/rspay_test.go
new file mode 100644
index 0000000..7f558f9
--- /dev/null
+++ b/tests/e2e/rspay_test.go
@@ -0,0 +1,39 @@
+package e2e
+
+import (
+ "context"
+ "fmt"
+ "github.com/stretchr/testify/assert"
+ "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
+ "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/client"
+ "penahub.gitlab.yandexcloud.net/pena-services/customer/tests/helpers"
+ "testing"
+)
+
+func TestGetAccount(t *testing.T) {
+ jwtUtil := helpers.InitializeJWT()
+
+ t.Run("rspay", func(t *testing.T) {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ assert.NotPanics(t, func() {
+ token, tokenErr := jwtUtil.Create("6597babdd1ba7e2dbd32d7e3")
+ if isNoError := assert.NoError(t, tokenErr); !isNoError {
+ return
+ }
+
+ response, err := client.Post[interface{}, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
+ URL: "http://localhost:8000/wallet/rspay",
+ Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
+ })
+ if isNoError := assert.NoError(t, err); !isNoError {
+ return
+ }
+ if isNoRequestError := assert.Nil(t, response.Error); !isNoRequestError {
+ return
+ }
+ })
+ })
+
+}
diff --git a/tests/integration/mail_test.go b/tests/integration/mail_test.go
new file mode 100644
index 0000000..b436121
--- /dev/null
+++ b/tests/integration/mail_test.go
@@ -0,0 +1,36 @@
+package integration
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/stretchr/testify/assert"
+ "go.uber.org/zap"
+ "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
+ "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
+ "testing"
+)
+
+func TestSendMessage(t *testing.T) {
+ sender := "noreply@mailing.pena.digital"
+ apiKey := "P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev"
+
+ mailClient := client.NewMailClient(client.MailClientDeps{
+ ApiUrl: "https://api.smtp.bz/v1/smtp/send",
+ Sender: sender,
+ ApiKey: apiKey,
+ Auth: &models.PlainAuth{Username: "kotilion.95@gmail.com", Password: "vWwbCSg4bf0p"},
+ FiberClient: fiber.AcquireClient(),
+ Logger: zap.NewExample(),
+ })
+
+ userEmail := "test@example.com"
+ verification := &models.Verification{
+ UserID: "test",
+ Files: []models.VerificationFile{
+ {Name: "file1", URL: "http://test/file1"},
+ {Name: "file2", URL: "http://test/file2"},
+ },
+ }
+
+ err := mailClient.SendMessage(userEmail, verification)
+ assert.NoError(t, err, "successful")
+}