Compare commits

..

41 Commits

Author SHA1 Message Date
ziming 874d773152 代码调整 2025-06-23 09:16:19 +08:00
ziming d9c8d22239 代码调整 2025-06-19 09:59:50 +08:00
ziming 394c97167d 代码调整 2025-06-17 16:16:09 +08:00
ziming b66023880d 代码调整 2025-06-16 19:04:07 +08:00
ziming e2c5113d4c 代码调整 2025-04-21 11:20:42 +08:00
ziming 607a05aa5a 代码调整 2025-04-21 11:18:43 +08:00
ziming c40e98e812 代码调整 2025-04-17 17:03:10 +08:00
ziming c616d31af9 代码调整 2025-04-17 17:01:47 +08:00
ziming df44886c9a 代码调整 2025-04-03 16:35:22 +08:00
李子铭 bf28ed8e63 代码调整 2025-03-05 18:18:09 +08:00
李子铭 d9adae9639 代码调整 2025-03-05 15:54:57 +08:00
李子铭 fc6f3533ab 插件v1恢复 2025-01-22 18:20:03 +08:00
李子铭 662d82326c 插件v2调整,账号验证 2025-01-22 18:13:13 +08:00
李子铭 36b9f16a74 插件v2调整 2025-01-22 18:01:45 +08:00
李子铭 3e4f3ce530 插件调试 2025-01-13 10:04:31 +08:00
李子铭 f56ca30040 插件调试 2025-01-13 10:04:18 +08:00
李子铭 c009c63edc 插件调试 2025-01-09 11:35:53 +08:00
李子铭 a88469dc45 插件调试 2025-01-07 14:28:30 +08:00
李子铭 2ac9ccba43 插件调试 2025-01-07 11:23:55 +08:00
李子铭 507e120fc3 插件调试 2025-01-07 10:59:07 +08:00
李子铭 7428fb1892 代码优化 2024-12-19 11:24:16 +08:00
李子铭 3913f00b13 ysf 2024-12-10 16:03:53 +08:00
李子铭 c3c84f4519 ysf 2024-12-10 16:02:57 +08:00
李子铭 b597b9e664 ysf 2024-12-10 15:56:10 +08:00
李子铭 d188d5d1e4 ysf 2024-12-10 15:53:48 +08:00
李子铭 6be34832c2 ysf 2024-12-10 15:46:52 +08:00
李子铭 ce9fc21598 ysf 2024-12-10 15:46:23 +08:00
李子铭 8ef34584ad request.go 2024-12-10 15:29:27 +08:00
李子铭 2ed01d42ea ysf red 2024-12-10 15:21:50 +08:00
李子铭 2a21ea4782 ysf red 2024-12-10 14:43:24 +08:00
李子铭 eded0a5a1f ysf red 2024-12-10 14:29:19 +08:00
李子铭 2a4c5b9373 ysf cpn 2024-12-10 14:12:32 +08:00
李子铭 d28961f0ba ysf cpn 2024-12-10 14:10:42 +08:00
李子铭 c5c809a019 ysf cpn 2024-12-10 13:49:47 +08:00
李子铭 2016395646 responseHeadersBytes 2024-12-04 11:25:18 +08:00
李子铭 5f1681c8b4 responseHeadersBytes 2024-12-04 11:25:01 +08:00
李子铭 7b6cea7598 js direct 2024-12-03 17:49:54 +08:00
李子铭 3bfb0d30aa return 2024-12-03 09:49:56 +08:00
李子铭 03f7733cdd return 2024-11-29 14:23:29 +08:00
李子铭 45212916ce 自定消息类型,风险排查 2024-11-28 14:42:53 +08:00
李子铭 fde43f6237 自定消息类型 2024-11-28 11:52:10 +08:00
72 changed files with 1227 additions and 526 deletions

View File

@ -13,7 +13,7 @@ build-win:
export GO111MODULE=on; \ export GO111MODULE=on; \
export CGO_ENABLED=0; \ export CGO_ENABLED=0; \
export GOPROXY=https://goproxy.cn,direct; \ export GOPROXY=https://goproxy.cn,direct; \
cd ${name} && go build -o ../../pkg/win/${name}.so . cd ${name} && go build -o ../../pkg/win/${name}.so .
build-linux: build-linux:
cd plugins; \ cd plugins; \
@ -41,18 +41,6 @@ zltx_v2:
make build-linux name=zltx_v2 && \ make build-linux name=zltx_v2 && \
make build-win name=zltx_v2 make build-win name=zltx_v2
.PHONY: union_pay_cpn
union_pay_cpn:
make build-mac name=union_pay_cpn && \
make build-linux name=union_pay_cpn && \
make build-win name=union_pay_cpn
.PHONY: union_pay_redpack
union_pay_redpack:
make build-mac name=union_pay_redpack && \
make build-linux name=union_pay_redpack && \
make build-win name=union_pay_redpack
.PHONY: alipay_cpn .PHONY: alipay_cpn
alipay_cpn: alipay_cpn:
make build-mac name=alipay_cpn && \ make build-mac name=alipay_cpn && \
@ -77,5 +65,17 @@ wechat_redpack:
make build-linux name=wechat_redpack && \ make build-linux name=wechat_redpack && \
make build-win name=wechat_redpack make build-win name=wechat_redpack
.PHONY: union_pay_cpn
union_pay_cpn:
make build-mac name=union_pay_cpn && \
make build-linux name=union_pay_cpn && \
make build-win name=union_pay_cpn
.PHONY: union_pay_redpack
union_pay_redpack:
make build-mac name=union_pay_redpack && \
make build-linux name=union_pay_redpack && \
make build-win name=union_pay_redpack
.PHONY: all .PHONY: all
all: zltx_v1 zltx_card_v1 union_pay_cpn union_pay_redpack alipay_cpn alipay_redpack wechat_cpn wechat_redpack zltx_v2 all: zltx_v1 zltx_card_v1 alipay_cpn alipay_redpack wechat_cpn wechat_redpack union_pay_cpn union_pay_redpack

View File

@ -64,7 +64,7 @@ func alipayOrderRedPack() {
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }
log.Printf("Order res:%+v", result) log.Printf("Order res:%+v\n", result)
} }
func alipayQueryRedPack() { func alipayQueryRedPack() {
@ -86,7 +86,7 @@ func alipayQueryRedPack() {
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }
log.Printf("Query res:%+v", resQuery) log.Printf("Query res:%+v\n", resQuery)
} }
func alipayNotifyRedPack() { func alipayNotifyRedPack() {

5
cmd/log.log Normal file
View File

@ -0,0 +1,5 @@
ERROR ts=2025-06-16T17:21:22+08:00 caller=client/order_digit.go:196 service.id=6551dda3098b service.name=market-gatway service.version=v1.0.1-631-gb1b82e6e msg=回调调用插件服务失败:
map[body:{"cardCode":"krorwUJwLmlr7pec6pjcOTOdsc4RrkPFOb27YhFGts3ljozBAeGFmAzZKlFK/RFU","merchantId":25943,"outTradeNo":"202506160907157760019451","status":"01"}
config:{"app_id":"101","app_key":"95E7EC7D4A394FF8D11788E5E436DE99","base_uri":"https://openapi.1688sup.com","merchant_id":25943,"notify_url":"https://market.86698.cn/v1/order/direct/notify"}
err:rpc error: code = Internal desc = 系统错误rpc error: code = Unavailable desc = connection error: desc = "transport: error while dialing: dial unix /tmp/plugin1274584100: connect: connection refused"
headers:{"Accept":["*/*"],"Accept-Encoding":["gzip, deflate, br"],"Authorization":["MD5 appid=101,sign=7EF17E77501F943FF98620D6D7D45140"],"Connection":["close"],"Content-Length":["152"],"Content-Type":["application/json"],"User-Agent":["Apifox/1.0.0 (https://apifox.com)"],"X-Forwarded-For":["117.175.169.61"],"X-Real-Ip":["117.175.169.61"],"X-Remoteaddr":["172.18.0.1"]} tag:zltx_card_v1]

View File

@ -2,5 +2,10 @@ package main
// main 这只是一个演示 // main 这只是一个演示
func main() { func main() {
alipayOrderRedPack() //alipayOrderRedPack()
//zltxQuery()
//wechatQueryCpn()
//alipayQueryRedPack()
//wechatOrderCpn()
zltxCardNotify()
} }

View File

@ -10,25 +10,27 @@ import (
) )
var zltxConf = &manage.Config{ var zltxConf = &manage.Config{
Cmd: "pkg/mac/zltx.so", Cmd: "pkg/mac/zltx_v1.so",
Tag: "zltx", Tag: "zltx_v1",
Version: 1, Version: 1,
CookieKey: "zltx", CookieKey: "zltx_v1",
CookieValue: "zltx", CookieValue: "zltx_v1",
} }
func config() []byte { func config() []byte {
type Config struct { type Config struct {
AppId string `json:"app_id"` AppId string `json:"app_id"`
AppKey string `json:"app_key"` AppKey string `json:"app_key"`
BaseUri string `json:"base_uri"` BaseUri string `json:"base_uri"`
NotifyUrl string `json:"notify_url"` NotifyUrl string `json:"notify_url"`
MerchantId int64 `json:"merchant_id"`
} }
c := &Config{ c := &Config{
AppId: "23329", AppId: "1",
AppKey: "8db16e8cc8363ed4eb4c14f9520bcc32", AppKey: "1e2bf7a04b8b1e6be5dc78d04e8639c9",
BaseUri: "http://test.openapi.1688sup.cn", BaseUri: "http://test.openapi.1688sup.cn",
NotifyUrl: "http://test.openapi.1688sup.cn", NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
MerchantId: 25537,
} }
marshal, _ := json.Marshal(c) marshal, _ := json.Marshal(c)
return marshal return marshal
@ -72,3 +74,22 @@ func zltx() {
} }
log.Printf("Query res:%+v", resQuery) log.Printf("Query res:%+v", resQuery)
} }
func zltxQuery() {
err := manage.Add(zltxConf)
if err != nil {
log.Fatalln(err)
}
defer manage.Close()
queryRequest := &proto.QueryRequest{
Config: config(),
Order: &proto.QueryRequest_Order{
OrderNo: "test_plugin_zltx_v1_direct_2",
},
}
resQuery, err := instance.Query(context.Background(), zltxConf.Tag, queryRequest)
if err != nil {
log.Fatalln(err)
}
log.Printf("Query res:%+v", resQuery)
}

78
cmd/zltx_card.go Normal file
View File

@ -0,0 +1,78 @@
package main
import (
"context"
"fmt"
"gitea.cdlsxd.cn/sdk/plugin/instance"
"gitea.cdlsxd.cn/sdk/plugin/manage"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"log"
)
var zltxCardConf = &manage.Config{
Cmd: "pkg/mac/zltx_card_v1.so",
Tag: "zltx_card_v1",
Version: 1,
CookieKey: "zltx_card_v1",
CookieValue: "zltx_card_v1",
}
func zlxtCardCf() []byte {
return []byte(`{"app_id":"101","app_key":"95E7EC7D4A394FF8D11788E5E436DE99","base_uri":"https://openapi.1688sup.com","merchant_id":25943,"notify_url":"https://market.86698.cn/v1/order/direct/notify"}`)
//type Config struct {
// AppId string `json:"app_id"`
// AppKey string `json:"app_key"`
// BaseUri string `json:"base_uri"`
// NotifyUrl string `json:"notify_url"`
// MerchantId int64 `json:"merchant_id"`
//}
//c := &Config{
// AppId: "101",
// AppKey: "95E7EC7D4A394FF8D11788E5E436DE99",
// BaseUri: "https://openapi.1688sup.com",
// NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
// MerchantId: 25943,
//}
//marshal, _ := json.Marshal(c)
//return marshal
}
// main 这只是一个演示
func zltxCardNotify() {
err := manage.Add(zltxCardConf)
if err != nil {
log.Fatalln(err)
}
defer func() {
fmt.Println("zltx_card_v1 close start")
manage.Close()
fmt.Println("zltx_card_v1 close end")
}()
//req := &proto.NotifyRequest{
// Config: zlxtCardCf(),
// Queries: []byte(``),
// Headers: []byte(`{"Accept-Encoding":["gzip, deflate, br"],"Authorization":["MD5 appid=101,sign=1A821E1E6FA824C7099D7F17F58E1650"],"Connection":["close"],"Content-Length":["183"],"Content-Type":["application/json"],"Cookie":[""],"User-Agent":["GuzzleHttp/6.5.5 curl/7.69.1 PHP/7.2.34"],"X-Forwarded-For":["47.96.248.136"],"X-Real-Ip":["47.96.248.136"],"X-Remoteaddr":["172.18.0.1"]}`),
// Body: []byte(`{"merchantId":25943,"outTradeNo":"202506161700247580010056","tradeNo":"789175179564695553","status":"01","cardCode":"XPHrv0+uPVQOqfymz1jJAsLOOuGpfvgXi9RIF1m4tRCsDdvcZDDNY21M/22F56M1"`),
//}
// transport: error while dialing: dial unix /tmp/plugin2702936918: connect: connection refused
for i := 0; i < 5; i++ {
req := &proto.NotifyRequest{
Config: zlxtCardCf(),
Queries: []byte(``),
Headers: []byte(`{"Accept":["*/*"],"Accept-Encoding":["gzip, deflate, br"],"Authorization":["MD5 appid=101,sign=7EF17E77501F943FF98620D6D7D45140"],"Connection":["close"],"Content-Length":["152"],"Content-Type":["application/json"],"User-Agent":["Apifox/1.0.0 (https://apifox.com)"],"X-Forwarded-For":["117.175.169.61"],"X-Real-Ip":["117.175.169.61"],"X-Remoteaddr":["172.18.0.1"]}`),
Body: []byte(`{"cardCode":"krorwUJwLmlr7pec6pjcOTOdsc4RrkPFOb27YhFGts3ljozBAeGFmAzZKlFK/RFU","merchantId":25943,"outTradeNo":"202506160907157760019451","status":"01"}`),
}
res, err := instance.Notify(context.Background(), zltxCardConf.Tag, req)
if err != nil {
log.Printf("Order err:%+v i:%d", err, i)
} else {
log.Printf("Order res:%+v i:%d", res, i)
}
}
}

3
go.mod
View File

@ -3,7 +3,7 @@ module plugins
go 1.22.2 go 1.22.2
require ( require (
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca gitea.cdlsxd.cn/sdk/plugin v1.0.17
plugins/utils v0.0.0-00010101000000-000000000000 plugins/utils v0.0.0-00010101000000-000000000000
) )
@ -12,6 +12,7 @@ replace plugins/utils => ./utils
require ( require (
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-kratos/kratos/v2 v2.8.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-playground/validator/v10 v10.22.0 // indirect

6
go.sum
View File

@ -1,5 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA= gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
@ -11,6 +11,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-kratos/kratos/v2 v2.8.2 h1:EsEA7AmPQ2YQQ0FZrDWO2HgBNqeWM8z/mWKzS5UkQaQ=
github.com/go-kratos/kratos/v2 v2.8.2/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=

View File

@ -5,8 +5,7 @@ go 1.22.2
replace plugins/utils => ../../utils replace plugins/utils => ../../utils
require ( require (
gitea.cdlsxd.cn/sdk/plugin v1.0.6 gitea.cdlsxd.cn/sdk/plugin v1.0.19
github.com/carlmjohnson/requests v0.24.2
github.com/go-playground/validator/v10 v10.22.0 github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
@ -17,6 +16,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-kratos/kratos/v2 v2.8.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.4 // indirect

View File

@ -1,17 +1,17 @@
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA= gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.6 h1:fcQrgdRT4zVmxqK8rsB4Oo7jnhnXDqsgQ8GagR+DSic= gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.6/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso=
github.com/carlmjohnson/requests v0.24.2/go.mod h1:duYA/jDnyZ6f3xbcF5PpZ9N8clgopubP2nK5i6MVMhU=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-kratos/kratos/v2 v2.8.2 h1:EsEA7AmPQ2YQQ0FZrDWO2HgBNqeWM8z/mWKzS5UkQaQ=
github.com/go-kratos/kratos/v2 v2.8.2/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -32,6 +32,10 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@ -45,6 +49,8 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 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/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
@ -64,7 +70,8 @@ google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -2,13 +2,14 @@ package internal
import ( import (
"context" "context"
"fmt" "encoding/json"
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/carlmjohnson/requests"
"plugins/alipay_cpn/internal/po" "plugins/alipay_cpn/internal/po"
) )
// 插件通信信息,若不对应则会报错panic // 插件通信信息,若不对应则会报错panic
// https://opendocs.alipay.com/open/282/105997?pathHash=3f0dc947
// https://www.yuque.com/xv2p76/manual/wpg9cl
const ( const (
Tag = "alipay_cpn" Tag = "alipay_cpn"
Version = 1 Version = 1
@ -30,24 +31,32 @@ func (s *AlipayCpnService) Order(ctx context.Context, request *proto.OrderReques
if err != nil { if err != nil {
return nil, err return nil, err
} }
poReq, err := orderReq(request.Order, request.Product) poReq, err := orderReq(request.Order, request.Product)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorParamFail(err.Error())
} }
param, err := c.paramReq(poReq, orderMethod) param, err := c.paramReq(poReq, orderMethod)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorParamFail(err.Error())
} }
uv, err := req(c, param) uv, err := req(c, param)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var response *po.OrderResp _, bodyBytes, err := Post(ctx, uv)
if err = requests.URL(baseUri).Post().Params(uv).ToJSON(&response).Fetch(ctx); err != nil { if err != nil {
return nil, err return nil, err
} }
var response *po.OrderResp
if err = json.Unmarshal(bodyBytes, &response); err != nil {
return nil, proto.ErrorResponseFail(err.Error())
}
return orderResp(request, response), nil return orderResp(request, response), nil
} }
@ -56,22 +65,30 @@ func (s *AlipayCpnService) Query(ctx context.Context, request *proto.QueryReques
if err != nil { if err != nil {
return nil, err return nil, err
} }
poReq, err := queryReq(request.Order) poReq, err := queryReq(request.Order)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorParamFail(err.Error())
} }
param, err := c.paramReq(poReq, queryMethod) param, err := c.paramReq(poReq, queryMethod)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorParamFail(err.Error())
} }
uv, err := req(c, param) uv, err := req(c, param)
if err != nil { if err != nil {
return nil, err return nil, err
} }
_, bodyBytes, err := Post(ctx, uv)
if err != nil {
return nil, err
}
var response po.QueryResp var response po.QueryResp
if err = requests.URL(baseUri).Post().BodyForm(uv).ToJSON(&response).Fetch(ctx); err != nil { if err = json.Unmarshal(bodyBytes, &response); err != nil {
return nil, fmt.Errorf("请求异常msg:" + err.Error()) return nil, proto.ErrorResponseFail(err.Error())
} }
return queryResp(request, response), nil return queryResp(request, response), nil
@ -82,6 +99,7 @@ func (s *AlipayCpnService) Notify(_ context.Context, request *proto.NotifyReques
if err != nil { if err != nil {
return nil, err return nil, err
} }
n := notifyReq(request) n := notifyReq(request)
b, err := Verify(n, c.Npk) b, err := Verify(n, c.Npk)
@ -89,7 +107,8 @@ func (s *AlipayCpnService) Notify(_ context.Context, request *proto.NotifyReques
return nil, err return nil, err
} }
if !b { if !b {
return nil, fmt.Errorf("验签失败") return nil, proto.ErrorSignFail("验签失败")
} }
return notifyResp(n), nil
return notifyResp(n)
} }

View File

@ -3,6 +3,7 @@ package po
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
@ -31,7 +32,7 @@ func (req *OrderReq) Validate() error {
err := validator.New().Struct(req) err := validator.New().Struct(req)
if err != nil { if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("参数有误:" + err.Error()) return proto.ErrorParamFail(fmt.Sprintf("参数有误: %v", err))
} }
} }
return nil return nil
@ -46,7 +47,7 @@ func (req *QueryReq) Validate() error {
err := validator.New().Struct(req) err := validator.New().Struct(req)
if err != nil { if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("参数有误:" + err.Error()) return proto.ErrorParamFail(fmt.Sprintf("参数有误: %v", err))
} }
} }
return nil return nil
@ -61,7 +62,7 @@ func (req *Notify) Validate() error {
err := validator.New().Struct(req) err := validator.New().Struct(req)
if err != nil { if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("参数有误:" + err.Error()) return proto.ErrorParamFail(fmt.Sprintf("参数有误: %v", err))
} }
} }
return nil return nil

View File

@ -6,6 +6,7 @@ import (
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"html" "html"
"net/http"
"plugins/alipay_cpn/internal/po" "plugins/alipay_cpn/internal/po"
"plugins/alipay_cpn/internal/vo" "plugins/alipay_cpn/internal/vo"
"time" "time"
@ -17,11 +18,11 @@ type Config struct {
Npk string `validate:"required" json:"npk"` // 回调公钥 Npk string `validate:"required" json:"npk"` // 回调公钥
} }
func (c *Config) Validate() error { func (c *Config) validate() error {
err := validator.New().Struct(c) err := validator.New().Struct(c)
if err != nil { if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("配置有误:" + err.Error()) return proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
} }
} }
return nil return nil
@ -31,9 +32,9 @@ func transConfig(config []byte) (*Config, error) {
var c Config var c Config
err := json.Unmarshal(config, &c) err := json.Unmarshal(config, &c)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorConfigFail(fmt.Sprintf("配置参数解析失败: %v", err))
} }
if err = c.Validate(); err != nil { if err = c.validate(); err != nil {
return nil, err return nil, err
} }
return &c, nil return &c, nil
@ -65,7 +66,7 @@ func orderReq(order *proto.OrderRequest_Order, product *proto.OrderRequest_Produ
if order.Extra != nil { if order.Extra != nil {
err := json.Unmarshal(order.Extra, &extra) err := json.Unmarshal(order.Extra, &extra)
if err != nil { if err != nil {
return nil, fmt.Errorf("order拓展参数 json unmarshal error: %v", err) return nil, proto.ErrorParamFail(fmt.Sprintf("order拓展参数转换有误: %v", err))
} }
} }
o := &po.OrderReq{ o := &po.OrderReq{
@ -101,7 +102,7 @@ func queryReq(in *proto.QueryRequest_Order) (*po.QueryReq, error) {
if in.Extra != nil { if in.Extra != nil {
err := json.Unmarshal(in.Extra, &extra) err := json.Unmarshal(in.Extra, &extra)
if err != nil { if err != nil {
return nil, fmt.Errorf("order拓展参数 json unmarshal error: %v", err) return nil, proto.ErrorParamFail(fmt.Sprintf("order拓展参数转换有误: %v", err))
} }
} }
return &po.QueryReq{ return &po.QueryReq{
@ -134,10 +135,11 @@ func notifyReq(in *proto.NotifyRequest) *po.Notify {
return n return n
} }
func notifyResp(n *po.Notify) *proto.NotifyResponse { func notifyResp(n *po.Notify) (*proto.NotifyResponse, error) {
var b po.NotifyBizContent var b po.NotifyBizContent
_ = json.Unmarshal([]byte(n.BizContent), &b) _ = json.Unmarshal([]byte(n.BizContent), &b)
return &proto.NotifyResponse{
pb := &proto.NotifyResponse{
Result: &proto.Result{ Result: &proto.Result{
Status: b.BizType.GetOrderStatus(), Status: b.BizType.GetOrderStatus(),
OrderNo: b.OrderID, OrderNo: b.OrderID,
@ -146,4 +148,15 @@ func notifyResp(n *po.Notify) *proto.NotifyResponse {
}, },
Return: "success", Return: "success",
} }
headers := make(http.Header)
headers.Set("Content-Type", "text/plain")
headersBytes, err := json.Marshal(headers)
if err != nil {
return nil, err
}
pb.Headers = string(headersBytes)
return pb, nil
} }

View File

@ -1,6 +1,7 @@
package internal package internal
import ( import (
"context"
"crypto" "crypto"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
@ -8,11 +9,13 @@ import (
"crypto/x509" "crypto/x509"
"encoding/base64" "encoding/base64"
"encoding/pem" "encoding/pem"
"errors"
"fmt" "fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"gitea.cdlsxd.cn/sdk/plugin/utils" "gitea.cdlsxd.cn/sdk/plugin/utils"
"net/http"
"net/url" "net/url"
"plugins/alipay_cpn/internal/po" "plugins/alipay_cpn/internal/po"
"plugins/utils/request"
"strings" "strings"
) )
@ -33,28 +36,39 @@ func req(config *Config, req *po.Param) (url.Values, error) {
s := strings.TrimRight(strToBeSigned.String(), "&") s := strings.TrimRight(strToBeSigned.String(), "&")
sign, err := Sign(s, []byte(utils.NewPrivate().Build(config.Prk))) sign, err := Sign(s, []byte(utils.NewPrivate().Build(config.Prk)))
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorSignFail(err.Error())
} }
uv.Set("sign", sign) uv.Set("sign", sign)
return uv, nil return uv, nil
} }
func Post(ctx context.Context, uv url.Values) (http.Header, []byte, error) {
h := http.Header{
"Content-Type": []string{"application/x-www-form-urlencoded"},
}
respHeader, respBody, err := request.Post(ctx, baseUri+"?"+uv.Encode(), nil, request.WithHeaders(h))
if err != nil {
return nil, nil, proto.ErrorRequestFail(err.Error())
}
return respHeader, respBody, nil
}
func Sign(data string, privateKeyPEM []byte) (string, error) { func Sign(data string, privateKeyPEM []byte) (string, error) {
block, _ := pem.Decode(privateKeyPEM) block, _ := pem.Decode(privateKeyPEM)
if block == nil { if block == nil {
return "", errors.New("failed to parse PEM block containing the private key") return "", proto.ErrorSignFail("failed to parse PEM block containing the private key")
} }
privyKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) privyKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil { if err != nil {
return "", fmt.Errorf("failed to parse DER encoded private key: %v", err) return "", proto.ErrorSignFail(fmt.Sprintf("failed to parse DER encoded private key: %v", err))
} }
hashed := sha256.Sum256([]byte(data)) hashed := sha256.Sum256([]byte(data))
signature, err := rsa.SignPKCS1v15(rand.Reader, privyKey.(*rsa.PrivateKey), crypto.SHA256, hashed[:]) signature, err := rsa.SignPKCS1v15(rand.Reader, privyKey.(*rsa.PrivateKey), crypto.SHA256, hashed[:])
if err != nil { if err != nil {
return "", fmt.Errorf("failed to sign: %v", err) return "", proto.ErrorSignFail(fmt.Sprintf("failed to sign:%v", err))
} }
return base64.StdEncoding.EncodeToString(signature), nil return base64.StdEncoding.EncodeToString(signature), nil
@ -78,7 +92,12 @@ func Verify(n *po.Notify, publicKeyPEM string) (bool, error) {
strToBeSigned.WriteString(fmt.Sprintf("%s=%s&", kv.Key, kv.Value)) strToBeSigned.WriteString(fmt.Sprintf("%s=%s&", kv.Key, kv.Value))
} }
s := strings.TrimRight(strToBeSigned.String(), "&") s := strings.TrimRight(strToBeSigned.String(), "&")
return check(s, n.Sign, []byte(utils.NewPublic().Build(publicKeyPEM))) b, err := check(s, n.Sign, []byte(utils.NewPublic().Build(publicKeyPEM)))
if err != nil {
return false, proto.ErrorSignFail(err.Error())
}
return b, nil
} }
func check(data, signature string, publicKeyPEM []byte) (bool, error) { func check(data, signature string, publicKeyPEM []byte) (bool, error) {

View File

@ -5,8 +5,7 @@ go 1.22.2
replace plugins/utils => ../../utils replace plugins/utils => ../../utils
require ( require (
gitea.cdlsxd.cn/sdk/plugin v1.0.6 gitea.cdlsxd.cn/sdk/plugin v1.0.19
github.com/carlmjohnson/requests v0.24.2
github.com/go-playground/validator/v10 v10.22.0 github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
@ -17,6 +16,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-kratos/kratos/v2 v2.8.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.4 // indirect

View File

@ -1,17 +1,17 @@
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA= gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.6 h1:fcQrgdRT4zVmxqK8rsB4Oo7jnhnXDqsgQ8GagR+DSic= gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.6/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso=
github.com/carlmjohnson/requests v0.24.2/go.mod h1:duYA/jDnyZ6f3xbcF5PpZ9N8clgopubP2nK5i6MVMhU=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-kratos/kratos/v2 v2.8.2 h1:EsEA7AmPQ2YQQ0FZrDWO2HgBNqeWM8z/mWKzS5UkQaQ=
github.com/go-kratos/kratos/v2 v2.8.2/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -32,6 +32,10 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@ -48,6 +52,8 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 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/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
@ -69,7 +75,8 @@ google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -2,9 +2,8 @@ package internal
import ( import (
"context" "context"
"fmt" "encoding/json"
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/carlmjohnson/requests"
"plugins/alipay_redpack/internal/po" "plugins/alipay_redpack/internal/po"
"plugins/utils/alipay" "plugins/utils/alipay"
) )
@ -32,24 +31,32 @@ func (s *AlipayRedPackService) Order(ctx context.Context, request *proto.OrderRe
if err != nil { if err != nil {
return nil, err return nil, err
} }
poReq, err := orderReq(request.Order, request.Product) poReq, err := orderReq(request.Order, request.Product)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorParamFail(err.Error())
} }
param, err := c.paramReq(poReq, orderMethod) param, err := c.paramReq(poReq, orderMethod)
if err != nil { if err != nil {
return nil, err return nil, err
} }
uv, err := req(c, param) uv, err := req(c, param)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var response *po.OrderResp bodyBytes, _, err := Post(ctx, uv)
if err = requests.URL(baseUri).Post().Params(uv).ToJSON(&response).Fetch(ctx); err != nil { if err != nil {
return nil, err return nil, err
} }
var response *po.OrderResp
if err = json.Unmarshal(bodyBytes, &response); err != nil {
return nil, proto.ErrorResponseFail(err.Error())
}
return orderResp(request, response), nil return orderResp(request, response), nil
} }
@ -58,22 +65,25 @@ func (s *AlipayRedPackService) Query(ctx context.Context, request *proto.QueryRe
if err != nil { if err != nil {
return nil, err return nil, err
} }
poReq, err := queryReq(request.Order)
if err != nil { param, err := c.paramReq(queryReq(request.Order), queryMethod)
return nil, err
}
param, err := c.paramReq(poReq, queryMethod)
if err != nil { if err != nil {
return nil, err return nil, err
} }
uv, err := req(c, param) uv, err := req(c, param)
if err != nil { if err != nil {
return nil, err return nil, err
} }
bodyBytes, _, err := Post(ctx, uv)
if err != nil {
return nil, err
}
var response po.QueryResp var response po.QueryResp
if err = requests.URL(baseUri).Post().BodyForm(uv).ToJSON(&response).Fetch(ctx); err != nil { if err = json.Unmarshal(bodyBytes, &response); err != nil {
return nil, fmt.Errorf("请求异常msg:" + err.Error()) return nil, proto.ErrorResponseFail(err.Error())
} }
return queryResp(request, response), nil return queryResp(request, response), nil
@ -84,18 +94,22 @@ func (s *AlipayRedPackService) Notify(_ context.Context, request *proto.NotifyRe
if err != nil { if err != nil {
return nil, err return nil, err
} }
n := notifyReq(request) n := notifyReq(request)
cert, err := alipay.GetCert(c.AppId) cert, err := alipay.GetCert(c.AppId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
b, err := Verify(n, cert.PublicKey) b, err := Verify(n, cert.PublicKey)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorSignFail(err.Error())
} }
if !b { if !b {
return nil, fmt.Errorf("验签失败") return nil, proto.ErrorSignFail("验签失败")
} }
return notifyResp(n), nil
return notifyResp(n)
} }

View File

@ -6,6 +6,7 @@ import (
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"html" "html"
"net/http"
"plugins/alipay_redpack/internal/po" "plugins/alipay_redpack/internal/po"
"plugins/alipay_redpack/internal/vo" "plugins/alipay_redpack/internal/vo"
"plugins/utils/alipay" "plugins/utils/alipay"
@ -18,11 +19,11 @@ type Config struct {
Prk string `validate:"required" json:"prk"` Prk string `validate:"required" json:"prk"`
} }
func (c *Config) Validate() error { func (c *Config) validate() error {
err := validator.New().Struct(c) err := validator.New().Struct(c)
if err != nil { if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("配置有误:" + err.Error()) return proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
} }
} }
return nil return nil
@ -32,9 +33,9 @@ func transConfig(config []byte) (*Config, error) {
var c Config var c Config
err := json.Unmarshal(config, &c) err := json.Unmarshal(config, &c)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorConfigFail(fmt.Sprintf("配置参数解析失败: %v", err))
} }
if err = c.Validate(); err != nil { if err = c.validate(); err != nil {
return nil, err return nil, err
} }
return &c, nil return &c, nil
@ -46,7 +47,7 @@ func (c *Config) paramReq(req po.Req, method string) (*po.Param, error) {
} }
cert, err := alipay.GetCert(c.AppId) cert, err := alipay.GetCert(c.AppId)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorConfigFail(err.Error())
} }
return &po.Param{ return &po.Param{
AlipayRootCertSn: cert.RootCertSN, AlipayRootCertSn: cert.RootCertSN,
@ -122,13 +123,13 @@ func orderResp(request *proto.OrderRequest, resp *po.OrderResp) *proto.OrderResp
} }
} }
func queryReq(in *proto.QueryRequest_Order) (*po.QueryReq, error) { func queryReq(in *proto.QueryRequest_Order) *po.QueryReq {
return &po.QueryReq{ return &po.QueryReq{
OutBizNo: in.OrderNo, OutBizNo: in.OrderNo,
OrderId: in.TradeNo, OrderId: in.TradeNo,
ProductCode: "STD_RED_PACKET", ProductCode: "STD_RED_PACKET",
BizScene: "DIRECT_TRANSFER", BizScene: "DIRECT_TRANSFER",
}, nil }
} }
func queryResp(request *proto.QueryRequest, resp po.QueryResp) *proto.QueryResponse { func queryResp(request *proto.QueryRequest, resp po.QueryResp) *proto.QueryResponse {
@ -151,10 +152,11 @@ func notifyReq(in *proto.NotifyRequest) *po.Notify {
return n return n
} }
func notifyResp(n *po.Notify) *proto.NotifyResponse { func notifyResp(n *po.Notify) (*proto.NotifyResponse, error) {
var b po.NotifyBizContent var b po.NotifyBizContent
_ = json.Unmarshal([]byte(n.BizContent), &b) _ = json.Unmarshal([]byte(n.BizContent), &b)
return &proto.NotifyResponse{
pb := &proto.NotifyResponse{
Result: &proto.Result{ Result: &proto.Result{
Status: b.Status.GetOrderStatus(), Status: b.Status.GetOrderStatus(),
OrderNo: b.OutBizNo, OrderNo: b.OutBizNo,
@ -163,4 +165,15 @@ func notifyResp(n *po.Notify) *proto.NotifyResponse {
}, },
Return: "success", Return: "success",
} }
headers := make(http.Header)
headers.Set("Content-Type", "text/plain")
headersBytes, err := json.Marshal(headers)
if err != nil {
return nil, err
}
pb.Headers = string(headersBytes)
return pb, nil
} }

View File

@ -1,6 +1,7 @@
package internal package internal
import ( import (
"context"
"crypto" "crypto"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
@ -10,9 +11,12 @@ import (
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"gitea.cdlsxd.cn/sdk/plugin/utils" "gitea.cdlsxd.cn/sdk/plugin/utils"
"net/http"
"net/url" "net/url"
"plugins/alipay_redpack/internal/po" "plugins/alipay_redpack/internal/po"
"plugins/utils/request"
"strings" "strings"
) )
@ -31,13 +35,24 @@ func req(config *Config, req *po.Param) (url.Values, error) {
sign, err := Sign(s, []byte(utils.NewPrivate().Build(config.Prk))) sign, err := Sign(s, []byte(utils.NewPrivate().Build(config.Prk)))
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorSignFail(err.Error())
} }
uv.Set("sign", sign) uv.Set("sign", sign)
return uv, nil return uv, nil
} }
func Post(ctx context.Context, uv url.Values) ([]byte, http.Header, error) {
h := http.Header{
"Content-Type": []string{"application/x-www-form-urlencoded"},
}
respHeader, respBody, err := request.Post(ctx, baseUri+"?"+uv.Encode(), nil, request.WithHeaders(h))
if err != nil {
return nil, nil, proto.ErrorRequestFail(err.Error())
}
return respBody, respHeader, nil
}
func Sign(data string, privateKeyPEM []byte) (string, error) { func Sign(data string, privateKeyPEM []byte) (string, error) {
block, _ := pem.Decode(privateKeyPEM) block, _ := pem.Decode(privateKeyPEM)
if block == nil { if block == nil {

View File

@ -5,7 +5,7 @@ go 1.22.2
replace plugins/utils => ../../utils replace plugins/utils => ../../utils
require ( require (
gitea.cdlsxd.cn/sdk/plugin v1.0.6 gitea.cdlsxd.cn/sdk/plugin v1.0.19
github.com/carlmjohnson/requests v0.24.2 github.com/carlmjohnson/requests v0.24.2
github.com/go-playground/validator/v10 v10.22.0 github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1
@ -17,6 +17,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-kratos/kratos/v2 v2.8.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.4 // indirect

View File

@ -1,8 +1,8 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA= gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.6 h1:fcQrgdRT4zVmxqK8rsB4Oo7jnhnXDqsgQ8GagR+DSic= gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.6/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
@ -20,6 +20,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-kratos/kratos/v2 v2.8.2 h1:EsEA7AmPQ2YQQ0FZrDWO2HgBNqeWM8z/mWKzS5UkQaQ=
github.com/go-kratos/kratos/v2 v2.8.2/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -55,6 +57,10 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@ -69,6 +75,8 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 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/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
@ -133,8 +141,9 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -3,6 +3,7 @@ package po
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
@ -20,7 +21,7 @@ func (req *OrderReq) Validate() error {
err := validator.New().Struct(req) err := validator.New().Struct(req)
if err != nil { if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("参数有误:" + err.Error()) return proto.ErrorParamFail(fmt.Sprintf("参数有误: %v", err))
} }
} }
return nil return nil
@ -39,7 +40,7 @@ func (req *QueryReq) Validate() error {
err := validator.New().Struct(req) err := validator.New().Struct(req)
if err != nil { if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("参数有误:" + err.Error()) return proto.ErrorParamFail(fmt.Sprintf("参数有误: %v", err))
} }
} }
return nil return nil
@ -58,7 +59,7 @@ func (req *Notify) Validate() error {
err := validator.New().Struct(req) err := validator.New().Struct(req)
if err != nil { if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("参数有误:" + err.Error()) return proto.ErrorParamFail(fmt.Sprintf("参数有误: %v", err))
} }
} }
return nil return nil

View File

@ -25,5 +25,8 @@ type QueryResp struct {
} }
func (o *QueryResp) GetMsg() string { func (o *QueryResp) GetMsg() string {
if o.Code.IsSuccess() {
return o.Msg
}
return fmt.Sprintf("Msg:[%s],SubMsg:[%s],自定处理msg:[%s]", o.Msg, o.SubMsg, o.SubCode.GetMsg()) return fmt.Sprintf("Msg:[%s],SubMsg:[%s],自定处理msg:[%s]", o.Msg, o.SubMsg, o.SubCode.GetMsg())
} }

View File

@ -1,47 +1,125 @@
package internal package internal
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
sdkutils "gitea.cdlsxd.cn/sdk/plugin/utils"
"github.com/go-playground/validator/v10"
"net/http"
"plugins/union_pay_cpn/internal/po" "plugins/union_pay_cpn/internal/po"
"plugins/union_pay_cpn/internal/vo" "plugins/union_pay_cpn/internal/vo"
"plugins/utils/request"
"plugins/utils/union_pay" "plugins/utils/union_pay"
"strings" "strings"
"time"
) )
type Config struct { type Config struct {
AppId string `json:"app_id"` AppId string `validate:"required" json:"app_id"`
ChNlId string `json:"chnlId"` // 渠道方代码 ChNlId string `validate:"required" json:"chnlId"` // 渠道方代码
IV string `json:"iv"` // 加密密钥 IV string `validate:"required" json:"iv"` // 加密密钥
KEY string `json:"key"` // 加密密钥 KEY string `validate:"required" json:"key"` // 加密密钥
Prk string `json:"prk"` // 私钥 Prk string `validate:"required" json:"prk"` // 私钥
Npk string `json:"npk"` // 回调公钥 Npk string `validate:"required" json:"npk"` // 回调公钥
}
func (c *Config) validate() error {
err := validator.New().Struct(c)
if err != nil {
for _, err = range err.(validator.ValidationErrors) {
return proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
}
}
return nil
} }
func transConfig(config []byte) (*Config, error) { func transConfig(config []byte) (*Config, error) {
var c Config var c Config
err := json.Unmarshal(config, &c) if err := json.Unmarshal(config, &c); err != nil {
if err != nil { return nil, proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
}
if err := c.validate(); err != nil {
return nil, err return nil, err
} }
return &c, nil return &c, nil
} }
func (c *Config) verify(req *po.Notify, notifyBizMethod string) error {
if req.Headers.SignMethod != vo.SignMethod {
return fmt.Errorf("签名方式不匹配")
}
if req.Headers.AppId != c.AppId {
return fmt.Errorf("appId不匹配")
}
if req.Headers.BizMethod != notifyBizMethod {
return fmt.Errorf("业务方法不匹配")
}
rehash := union_pay.Sha(req.Headers.Version, c.AppId, req.Headers.BizMethod, req.GetReId(), string(req.ToJson()))
lowerStr := strings.ToLower(rehash)
if union_pay.Verify(lowerStr, req.Headers.Sign, []byte(sdkutils.NewPublic().Build(c.Npk))) {
return nil
}
return fmt.Errorf("验签失败")
}
func (c *Config) headers(bizMethod string, req po.Req) http.Header {
h := make(http.Header)
h.Add("Content-type", vo.ContentType)
h.Add("version", vo.Version)
h.Add("appType", vo.AppType)
h.Add("signMethod", vo.SignMethod)
h.Add("appId", c.AppId)
h.Add("bizMethod", bizMethod)
h.Add("reqId", req.GetReId())
now := time.Now()
milliseconds := now.Unix()*1000 + int64(now.Nanosecond())/1e6
h.Add("reqTs", fmt.Sprintf("%d", milliseconds))
rehash := union_pay.Sha(vo.Version, c.AppId, bizMethod, req.GetReId(), string(req.ToJson()))
signValue, err := union_pay.Sign(rehash, []byte(sdkutils.NewPrivate().Build(c.Prk)))
if err != nil {
return nil
}
h.Add("sign", signValue)
return h
}
func (c *Config) Request(ctx context.Context, req po.Req, method, bizMethod string) (http.Header, []byte, error) {
respHeader, respBody, err := request.Post(
ctx,
fmt.Sprintf("%s%s", baseUri, method),
req.ToJson(),
request.WithHeaders(c.headers(bizMethod, req)),
request.WithTimeout(15*time.Second),
request.WithStatusCodeFunc(func(code int) bool {
return code == http.StatusOK
}),
)
if err != nil {
return nil, nil, proto.ErrorRequestFail(err.Error())
}
return respHeader, respBody, nil
}
func (c *Config) orderReq(in *proto.OrderRequest) (*po.OrderReq, error) { func (c *Config) orderReq(in *proto.OrderRequest) (*po.OrderReq, error) {
type OrderExtra struct { type OrderExtra struct {
OrderDt string `json:"orderDt"` OrderDt string `json:"orderDt"`
} }
var e OrderExtra var e OrderExtra
err := json.Unmarshal(in.Order.Extra, &e) if err := json.Unmarshal(in.Order.Extra, &e); err != nil {
if err != nil { return nil, fmt.Errorf("订单拓展参数fail: %w", err)
return nil, fmt.Errorf("订单拓展参数 json unmarshal error: %v", err)
} }
mobile, err := union_pay.Encrypt([]byte(in.Order.Account), []byte(c.KEY), []byte(c.IV)) mobile, err := union_pay.Encrypt([]byte(in.Order.Account), []byte(c.KEY), []byte(c.IV))
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &po.OrderReq{ return &po.OrderReq{
Cmd: vo.OrderCmd, Cmd: vo.OrderCmd,
AccessId: vo.AccessId, AccessId: vo.AccessId,
@ -57,7 +135,7 @@ func (c *Config) orderReq(in *proto.OrderRequest) (*po.OrderReq, error) {
}, nil }, nil
} }
func orderResp(request *proto.OrderRequest, resp po.OrderResp) *proto.OrderResponse { func orderResp(request *proto.OrderRequest, resp po.OrderResp) (*proto.OrderResponse, error) {
data, _ := json.Marshal(resp) data, _ := json.Marshal(resp)
result := &proto.Result{ result := &proto.Result{
OrderNo: request.Order.OrderNo, OrderNo: request.Order.OrderNo,
@ -71,22 +149,24 @@ func orderResp(request *proto.OrderRequest, resp po.OrderResp) *proto.OrderRespo
} else { } else {
result.Status = proto.Status_ING result.Status = proto.Status_ING
} }
return &proto.OrderResponse{Result: result} return &proto.OrderResponse{Result: result}, nil
} }
func queryReq(in *proto.QueryRequest, chNlId string) *po.QueryReq { func queryReq(in *proto.QueryRequest, chNlId string) (*po.QueryReq, error) {
type OrderExtra struct { type OrderExtra struct {
OrigDate string `json:"origDate"` OrigDate string `json:"origDate"`
} }
var e OrderExtra var e OrderExtra
_ = json.Unmarshal(in.Order.Extra, &e) if err := json.Unmarshal(in.Order.Extra, &e); err != nil {
return nil, err
}
return &po.QueryReq{ return &po.QueryReq{
ChNlId: chNlId, ChNlId: chNlId,
Cmd: vo.QueryCmd, Cmd: vo.QueryCmd,
OrigQid: in.Order.OrderNo, OrigQid: in.Order.OrderNo,
OrigDate: e.OrigDate, OrigDate: e.OrigDate,
TraceId: in.Order.OrderNo, TraceId: in.Order.OrderNo,
} }, nil
} }
func queryResp(request *proto.QueryRequest, resp po.QueryResp) *proto.QueryResponse { func queryResp(request *proto.QueryRequest, resp po.QueryResp) *proto.QueryResponse {
@ -101,11 +181,15 @@ func queryResp(request *proto.QueryRequest, resp po.QueryResp) *proto.QueryRespo
return &proto.QueryResponse{Result: result} return &proto.QueryResponse{Result: result}
} }
func notifyReq(in *proto.NotifyRequest) *po.Notify { func notifyReq(in *proto.NotifyRequest) (*po.Notify, error) {
var h po.Headers var h po.Headers
_ = json.Unmarshal(in.Headers, &h) if err := json.Unmarshal(in.Headers, &h); err != nil {
return nil, err
}
var body po.Body var body po.Body
_ = json.NewDecoder(strings.NewReader(string(in.Body))).Decode(&body) if err := json.NewDecoder(strings.NewReader(string(in.Body))).Decode(&body); err != nil {
return nil, err
}
body.CouponNum = union_pay.ConvertToInt(body.CouponNum) body.CouponNum = union_pay.ConvertToInt(body.CouponNum)
body.OrderAt = union_pay.ConvertToInt(body.OrderAt) body.OrderAt = union_pay.ConvertToInt(body.OrderAt)
body.DiscountAt = union_pay.ConvertToInt(body.DiscountAt) body.DiscountAt = union_pay.ConvertToInt(body.DiscountAt)
@ -116,11 +200,11 @@ func notifyReq(in *proto.NotifyRequest) *po.Notify {
return &po.Notify{ return &po.Notify{
Headers: &h, Headers: &h,
Body: &body, Body: &body,
} }, nil
} }
func notifyResp(request *proto.NotifyRequest, n *po.Notify) *proto.NotifyResponse { func notifyResp(request *proto.NotifyRequest, n *po.Notify) (*proto.NotifyResponse, error) {
return &proto.NotifyResponse{ pb := &proto.NotifyResponse{
Result: &proto.Result{ Result: &proto.Result{
OrderNo: n.Body.TransSeq, OrderNo: n.Body.TransSeq,
TradeNo: n.Body.CouponCd, TradeNo: n.Body.CouponCd,
@ -130,4 +214,15 @@ func notifyResp(request *proto.NotifyRequest, n *po.Notify) *proto.NotifyRespons
}, },
Return: "success", Return: "success",
} }
headers := make(http.Header)
headers.Set("Content-Type", "text/plain")
headersBytes, err := json.Marshal(headers)
if err != nil {
return nil, err
}
pb.Headers = string(headersBytes)
return pb, err
} }

View File

@ -2,9 +2,8 @@ package internal
import ( import (
"context" "context"
"fmt" "encoding/json"
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/carlmjohnson/requests"
"plugins/union_pay_cpn/internal/po" "plugins/union_pay_cpn/internal/po"
) )
@ -37,56 +36,71 @@ func (p *UnionPayCpnService) Order(ctx context.Context, request *proto.OrderRequ
if err != nil { if err != nil {
return nil, err return nil, err
} }
uv, err := c.orderReq(request) req, err := c.orderReq(request)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorParamFail(err.Error())
} }
if err = uv.Validate(); err != nil { if err = req.Validate(); err != nil {
return nil, err return nil, err
} }
var response po.OrderResp
url := fmt.Sprintf("%s%s", baseUri, orderMethod)
err = requests.URL(url).Headers(headers(c, uv, orderBizMethod)).BodyJSON(uv).ToJSON(&response).Fetch(ctx)
if err != nil {
return nil, fmt.Errorf("请求异常msg:" + err.Error())
}
return orderResp(request, response), nil _, bodyBytes, err := c.Request(ctx, req, orderMethod, orderBizMethod)
if err != nil {
return nil, err
}
var response po.OrderResp
if err = json.Unmarshal(bodyBytes, &response); err != nil {
return nil, proto.ErrorResponseFail(err.Error())
}
return orderResp(request, response)
} }
func (p *UnionPayCpnService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) { func (p *UnionPayCpnService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) {
conf, err := transConfig(request.Config) c, err := transConfig(request.Config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
uv := queryReq(request, conf.ChNlId) req, err := queryReq(request, c.ChNlId)
if err = uv.Validate(); err != nil { if err != nil {
return nil, proto.ErrorParamFail(err.Error())
}
if err = req.Validate(); err != nil {
return nil, err return nil, err
} }
_, bodyBytes, err := c.Request(ctx, req, queryMethod, queryBizMethod)
if err != nil {
return nil, err
}
var response po.QueryResp var response po.QueryResp
url := fmt.Sprintf("%s%s", baseUri, queryMethod) if err = json.Unmarshal(bodyBytes, &response); err != nil {
err = requests.URL(url).Headers(headers(conf, uv, queryBizMethod)).BodyJSON(uv).ToJSON(&response).Fetch(ctx) return nil, proto.ErrorResponseFail(err.Error())
if err != nil {
return nil, fmt.Errorf("请求异常msg:" + err.Error())
} }
return queryResp(request, response), nil return queryResp(request, response), nil
} }
func (p *UnionPayCpnService) Notify(_ context.Context, request *proto.NotifyRequest) (*proto.NotifyResponse, error) { func (p *UnionPayCpnService) Notify(_ context.Context, request *proto.NotifyRequest) (*proto.NotifyResponse, error) {
uv := notifyReq(request) req, err := notifyReq(request)
if err := uv.Validate(); err != nil { if err != nil {
return nil, proto.ErrorParamFail(err.Error())
}
if err = req.Validate(); err != nil {
return nil, err return nil, err
} }
conf, err := transConfig(request.Config) c, err := transConfig(request.Config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = verify(conf, uv, notifyBizMethod); err != nil { if err = c.verify(req, notifyBizMethod); err != nil {
return nil, err return nil, err
} }
return notifyResp(request, uv), nil return notifyResp(request, req)
} }

View File

@ -73,7 +73,7 @@ func TestQuery(t *testing.T) {
t.Errorf("Query() error = %v", err) t.Errorf("Query() error = %v", err)
return return
} }
fmt.Printf("%+v \n", got) t.Logf("%+v \n", got)
assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status)) assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status))
}) })
} }

View File

@ -1,55 +0,0 @@
package internal
import (
"fmt"
sdkutils "gitea.cdlsxd.cn/sdk/plugin/utils"
"net/http"
"plugins/union_pay_cpn/internal/po"
"plugins/union_pay_cpn/internal/vo"
"plugins/utils/union_pay"
"strings"
"time"
)
func headers(config *Config, req po.Req, bizMethod string) map[string][]string {
h := make(http.Header)
h.Add("Content-type", vo.ContentType)
h.Add("version", vo.Version)
h.Add("appType", vo.AppType)
h.Add("signMethod", vo.SignMethod)
h.Add("appId", config.AppId)
h.Add("bizMethod", bizMethod)
h.Add("reqId", req.GetReId())
now := time.Now()
milliseconds := now.Unix()*1000 + int64(now.Nanosecond())/1e6
h.Add("reqTs", fmt.Sprintf("%d", milliseconds))
rehash := union_pay.Sha(vo.Version, config.AppId, bizMethod, req.GetReId(), string(req.ToJson()))
signValue, err := union_pay.Sign(rehash, []byte(sdkutils.NewPrivate().Build(config.Prk)))
if err != nil {
return nil
}
h.Add("sign", signValue)
return h
}
func verify(config *Config, req *po.Notify, notifyBizMethod string) error {
if req.Headers.SignMethod != vo.SignMethod {
return fmt.Errorf("签名方式不匹配")
}
if req.Headers.AppId != config.AppId {
return fmt.Errorf("appId不匹配")
}
if req.Headers.BizMethod != notifyBizMethod {
return fmt.Errorf("业务方法不匹配")
}
rehash := union_pay.Sha(req.Headers.Version, config.AppId, req.Headers.BizMethod, req.GetReId(), string(req.ToJson()))
lowerStr := strings.ToLower(rehash)
if union_pay.Verify(lowerStr, req.Headers.Sign, []byte(sdkutils.NewPublic().Build(config.Npk))) {
return nil
}
return fmt.Errorf("验签失败")
}

View File

@ -32,11 +32,8 @@ func (o OperaSt) GetText() string {
} }
func (o OperaSt) GetOrderStatus() proto.Status { func (o OperaSt) GetOrderStatus() proto.Status {
if len(o) == 0 {
return proto.Status_INVALID
}
if resultStatus, ok := queryOrderStatusMap[o]; ok { if resultStatus, ok := queryOrderStatusMap[o]; ok {
return resultStatus return resultStatus
} }
return proto.Status_FAIL return proto.Status_INVALID
} }

View File

@ -5,7 +5,7 @@ go 1.22.2
replace plugins/utils => ../../utils replace plugins/utils => ../../utils
require ( require (
gitea.cdlsxd.cn/sdk/plugin v1.0.6 gitea.cdlsxd.cn/sdk/plugin v1.0.19
github.com/carlmjohnson/requests v0.24.2 github.com/carlmjohnson/requests v0.24.2
github.com/go-playground/validator/v10 v10.22.0 github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1
@ -17,6 +17,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-kratos/kratos/v2 v2.8.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.4 // indirect

View File

@ -1,8 +1,8 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA= gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.6 h1:fcQrgdRT4zVmxqK8rsB4Oo7jnhnXDqsgQ8GagR+DSic= gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.6/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
@ -20,6 +20,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-kratos/kratos/v2 v2.8.2 h1:EsEA7AmPQ2YQQ0FZrDWO2HgBNqeWM8z/mWKzS5UkQaQ=
github.com/go-kratos/kratos/v2 v2.8.2/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -55,6 +57,10 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@ -69,6 +75,8 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 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/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
@ -133,8 +141,9 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -26,5 +26,8 @@ type QueryResp struct {
} }
func (o *QueryResp) GetMsg() string { func (o *QueryResp) GetMsg() string {
if o.Code.IsSuccess() {
return o.Msg
}
return fmt.Sprintf("Msg:[%s],SubMsg:[%s],自定处理msg:[%s]", o.Msg, o.SubMsg, o.SubCode.GetMsg()) return fmt.Sprintf("Msg:[%s],SubMsg:[%s],自定处理msg:[%s]", o.Msg, o.SubMsg, o.SubCode.GetMsg())
} }

View File

@ -1,35 +1,95 @@
package internal package internal
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
sdkutils "gitea.cdlsxd.cn/sdk/plugin/utils"
"github.com/go-playground/validator/v10"
"net/http"
"plugins/union_pay_redpack/internal/po" "plugins/union_pay_redpack/internal/po"
"plugins/union_pay_redpack/internal/vo" "plugins/union_pay_redpack/internal/vo"
"plugins/utils/request"
"plugins/utils/union_pay" "plugins/utils/union_pay"
"time"
) )
type Config struct { type Config struct {
AppId string `json:"app_id"` AppId string `validate:"required" json:"app_id"`
ChNlId string `json:"chnlId"` // 渠道方代码 ChNlId string `validate:"required" json:"chnlId"` // 渠道方代码
IV string `json:"iv"` // 加密密钥 IV string `validate:"required" json:"iv"` // 加密密钥
KEY string `json:"key"` // 加密密钥 KEY string `validate:"required" json:"key"` // 加密密钥
Prk string `json:"prk"` // 私钥 Prk string `validate:"required" json:"prk"` // 私钥
Npk string `json:"npk"` // 回调公钥 Npk string `validate:"required" json:"npk"` // 回调公钥
PointId string `json:"point_id"` // 积分ID-积分类别代码41开头的16位数字 PointId string `validate:"required" json:"point_id"` // 积分ID-积分类别代码41开头的16位数字
InsAcctId string `json:"ins_acct_id"` // 机构账户代码 InsAcctId string `validate:"required" json:"ins_acct_id"` // 机构账户代码
}
func (c *Config) validate() error {
err := validator.New().Struct(c)
if err != nil {
for _, err = range err.(validator.ValidationErrors) {
return proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
}
}
return nil
} }
func transConfig(config []byte) (*Config, error) { func transConfig(config []byte) (*Config, error) {
var c Config var c Config
err := json.Unmarshal(config, &c) if err := json.Unmarshal(config, &c); err != nil {
if err != nil { return nil, proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
}
if err := c.validate(); err != nil {
return nil, err return nil, err
} }
return &c, nil return &c, nil
} }
func (c *Config) headers(bizMethod string, req po.Req) http.Header {
h := make(http.Header)
h.Add("Content-type", vo.ContentType)
h.Add("version", vo.Version)
h.Add("appType", vo.AppType)
h.Add("signMethod", vo.SignMethod)
h.Add("appId", c.AppId)
h.Add("bizMethod", bizMethod)
h.Add("reqId", req.GetReId())
now := time.Now()
milliseconds := now.Unix()*1000 + int64(now.Nanosecond())/1e6
h.Add("reqTs", fmt.Sprintf("%d", milliseconds))
rehash := union_pay.Sha(vo.Version, c.AppId, bizMethod, req.GetReId(), string(req.ToJson()))
signValue, err := union_pay.Sign(rehash, []byte(sdkutils.NewPrivate().Build(c.Prk)))
if err != nil {
return nil
}
h.Add("sign", signValue)
return h
}
func (c *Config) Request(ctx context.Context, req po.Req, method, bizMethod string) (http.Header, []byte, error) {
respHeader, respBody, err := request.Post(
ctx,
fmt.Sprintf("%s%s", baseUri, method),
req.ToJson(),
request.WithHeaders(c.headers(bizMethod, req)),
request.WithTimeout(15*time.Second),
request.WithStatusCodeFunc(func(code int) bool {
return code == http.StatusOK
}),
)
if err != nil {
return nil, nil, proto.ErrorRequestFail(err.Error())
}
return respHeader, respBody, nil
}
func (c *Config) orderReq(in *proto.OrderRequest) (*po.OrderReq, error) { func (c *Config) orderReq(in *proto.OrderRequest) (*po.OrderReq, error) {
type OrderExtra struct { type OrderExtra struct {
TransDtTm string `json:"transDtTm"` // 交易日期时间 TransDtTm string `json:"transDtTm"` // 交易日期时间
@ -37,9 +97,8 @@ func (c *Config) orderReq(in *proto.OrderRequest) (*po.OrderReq, error) {
TransDigest string `json:"transDigest"` // 交易摘要 TransDigest string `json:"transDigest"` // 交易摘要
} }
var e OrderExtra var e OrderExtra
err := json.Unmarshal(in.Order.Extra, &e) if err := json.Unmarshal(in.Order.Extra, &e); err != nil {
if err != nil { return nil, fmt.Errorf("order extra fail: %v", err)
return nil, fmt.Errorf("order extra json unmarshal error: %v", err)
} }
mobile, err := union_pay.Encrypt([]byte(in.Order.Account), []byte(c.KEY), []byte(c.IV)) mobile, err := union_pay.Encrypt([]byte(in.Order.Account), []byte(c.KEY), []byte(c.IV))
@ -91,9 +150,8 @@ func (c *Config) queryReq(in *proto.QueryRequest, chNlId string) (*po.QueryReq,
OrigTransDtTm string `json:"origTransDtTm"` // 原交易日期时间 OrigTransDtTm string `json:"origTransDtTm"` // 原交易日期时间
} }
var e OrderExtra var e OrderExtra
err := json.Unmarshal(in.Order.Extra, &e) if err := json.Unmarshal(in.Order.Extra, &e); err != nil {
if err != nil { return nil, fmt.Errorf("order extra fail: %v", err)
return nil, fmt.Errorf("order extra json unmarshal error: %v", err)
} }
mobile, err := union_pay.Encrypt([]byte(in.Order.Account), []byte(c.KEY), []byte(c.IV)) mobile, err := union_pay.Encrypt([]byte(in.Order.Account), []byte(c.KEY), []byte(c.IV))
if err != nil { if err != nil {

View File

@ -2,12 +2,9 @@ package internal
import ( import (
"context" "context"
"fmt" "encoding/json"
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/carlmjohnson/requests"
"net/http"
"plugins/union_pay_redpack/internal/po" "plugins/union_pay_redpack/internal/po"
"time"
) )
// 插件通信信息,若不对应则会报错panic // 插件通信信息,若不对应则会报错panic
@ -37,17 +34,22 @@ func (p *UnionPayCpnService) Order(ctx context.Context, request *proto.OrderRequ
if err != nil { if err != nil {
return nil, err return nil, err
} }
uv, err := c.orderReq(request) req, err := c.orderReq(request)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = uv.Validate(); err != nil { if err = req.Validate(); err != nil {
return nil, err return nil, err
} }
_, bodyBytes, err := c.Request(ctx, req, orderMethod, orderBizMethod)
if err != nil {
return nil, err
}
var response po.OrderResp var response po.OrderResp
err = requests.URL(baseUri + orderMethod).Headers(headers(c, uv, orderBizMethod)).Post().BodyJSON(uv).ToJSON(&response).Fetch(ctx) if err = json.Unmarshal(bodyBytes, &response); err != nil {
if err != nil { return nil, proto.ErrorResponseFail(err.Error())
return nil, fmt.Errorf("请求异常msg:" + err.Error())
} }
return orderResp(request, response), nil return orderResp(request, response), nil
@ -58,20 +60,22 @@ func (p *UnionPayCpnService) Query(ctx context.Context, request *proto.QueryRequ
if err != nil { if err != nil {
return nil, err return nil, err
} }
uv, err := c.queryReq(request, c.ChNlId) req, err := c.queryReq(request, c.ChNlId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = uv.Validate(); err != nil { if err = req.Validate(); err != nil {
return nil, err return nil, err
} }
var response po.QueryResp
h := new(http.Client) _, bodyBytes, err := c.Request(ctx, req, queryMethod, queryBizMethod)
h.Timeout = 20 * time.Second
err = requests.URL(baseUri + queryMethod).Client(h).Headers(headers(c, uv, queryBizMethod)).BodyJSON(uv).ToJSON(&response).Fetch(ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("请求异常msg:" + err.Error()) return nil, err
}
var response po.QueryResp
if err = json.Unmarshal(bodyBytes, &response); err != nil {
return nil, proto.ErrorResponseFail(err.Error())
} }
return queryResp(request, response), nil return queryResp(request, response), nil

View File

@ -74,8 +74,6 @@ func TestOrder(t *testing.T) {
t.Errorf("Order() error = %v", err) t.Errorf("Order() error = %v", err)
return return
} }
fmt.Printf("request order:%+v \n", request.Order)
fmt.Printf("request product:%+v \n", request.Product)
fmt.Printf("got:%+v \n", got) fmt.Printf("got:%+v \n", got)
assert.Equal(t, int(proto.Status_ING), int(got.Result.Status)) assert.Equal(t, int(proto.Status_ING), int(got.Result.Status))
}) })

View File

@ -1,36 +0,0 @@
package internal
import (
"fmt"
sdkutils "gitea.cdlsxd.cn/sdk/plugin/utils"
"net/http"
"plugins/union_pay_redpack/internal/po"
"plugins/union_pay_redpack/internal/vo"
"plugins/utils/union_pay"
"time"
)
func headers(config *Config, req po.Req, bizMethod string) map[string][]string {
h := make(http.Header)
h.Add("Content-type", vo.ContentType)
h.Add("version", vo.Version)
h.Add("appType", vo.AppType)
h.Add("signMethod", vo.SignMethod)
h.Add("appId", config.AppId)
h.Add("bizMethod", bizMethod)
h.Add("reqId", req.GetReId())
now := time.Now()
milliseconds := now.Unix()*1000 + int64(now.Nanosecond())/1e6
h.Add("reqTs", fmt.Sprintf("%d", milliseconds))
rehash := union_pay.Sha(vo.Version, config.AppId, bizMethod, req.GetReId(), string(req.ToJson()))
signValue, err := union_pay.Sign(rehash, []byte(sdkutils.NewPrivate().Build(config.Prk)))
if err != nil {
return nil
}
h.Add("sign", signValue)
return h
}

View File

@ -5,7 +5,7 @@ go 1.22.2
replace plugins/utils => ../../utils replace plugins/utils => ../../utils
require ( require (
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca gitea.cdlsxd.cn/sdk/plugin v1.0.17
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
github.com/wechatpay-apiv3/wechatpay-go v0.2.18 github.com/wechatpay-apiv3/wechatpay-go v0.2.18
@ -16,6 +16,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-kratos/kratos/v2 v2.8.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-playground/validator/v10 v10.22.0 // indirect

View File

@ -1,5 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA= gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
@ -11,6 +11,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-kratos/kratos/v2 v2.8.2 h1:EsEA7AmPQ2YQQ0FZrDWO2HgBNqeWM8z/mWKzS5UkQaQ=
github.com/go-kratos/kratos/v2 v2.8.2/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -31,6 +33,10 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@ -44,6 +50,8 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@ -71,8 +79,9 @@ google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -6,7 +6,6 @@ import (
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/services/cashcoupons" "github.com/wechatpay-apiv3/wechatpay-go/services/cashcoupons"
"go/types"
"plugins/utils/wechat" "plugins/utils/wechat"
"plugins/wechat_cpn/internal/vo" "plugins/wechat_cpn/internal/vo"
) )
@ -15,7 +14,7 @@ func transConfig(config []byte) (*wechat.Server, error) {
var c wechat.Server var c wechat.Server
err := json.Unmarshal(config, &c) err := json.Unmarshal(config, &c)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorConfigFail(err.Error())
} }
if err = c.Validate(); err != nil { if err = c.Validate(); err != nil {
return nil, err return nil, err
@ -89,10 +88,6 @@ func queryResp(request *proto.QueryRequest, resp *cashcoupons.Coupon) *proto.Que
} }
} }
func notifyReq(in *proto.NotifyRequest) *types.Nil {
return nil
}
func notifyResp() *proto.NotifyResponse { func notifyResp() *proto.NotifyResponse {
return &proto.NotifyResponse{ return &proto.NotifyResponse{
Result: &proto.Result{ Result: &proto.Result{

View File

@ -9,6 +9,7 @@ import (
) )
// 插件通信信息,若不对应则会报错panic // 插件通信信息,若不对应则会报错panic
// 微信立减金文档地址: https://pay.weixin.qq.com/doc/v3/merchant/4012463767
const ( const (
Tag = "wechat_cpn" Tag = "wechat_cpn"
Version = 1 Version = 1
@ -23,41 +24,54 @@ func (p *WeChatCpnService) Order(ctx context.Context, request *proto.OrderReques
if err != nil { if err != nil {
return nil, err return nil, err
} }
req, err := orderReq(request.GetOrder(), request.GetProduct()) req, err := orderReq(request.GetOrder(), request.GetProduct())
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorParamFail(err.Error())
} }
svc, err := srv(ctx, config) svc, err := srv(ctx, config)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorRequestFail(err.Error())
} }
resp, result, err := svc.SendCoupon(ctx, req) resp, result, err := svc.SendCoupon(ctx, req)
if err != nil { if err != nil {
return nil, fmt.Errorf("微信返回错误 %v", p.err(ctx, err)) return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误:%s", p.err(ctx, err)))
} }
if result.Response.StatusCode != vo.CodeSuccess.Value() { if result.Response.StatusCode != vo.CodeSuccess.Value() {
return nil, fmt.Errorf("微信返回错误 StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status) return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status))
} }
return orderResp(request.GetOrder(), *resp.CouponId), nil return orderResp(request.GetOrder(), *resp.CouponId), nil
} }
func (p *WeChatCpnService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) { func (p *WeChatCpnService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) {
config, err := transConfig(request.Config) config, err := transConfig(request.Config)
if err != nil {
return nil, err
}
svc, err := srv(ctx, config) svc, err := srv(ctx, config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
req, err := queryReq(request.GetOrder()) req, err := queryReq(request.GetOrder())
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp, result, err := svc.QueryCoupon(ctx, *req) resp, result, err := svc.QueryCoupon(ctx, *req)
if err != nil { if err != nil {
return nil, p.err(ctx, err) return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误:%s", p.err(ctx, err)))
} }
if result.Response.StatusCode != vo.CodeSuccess.Value() { if result.Response.StatusCode != vo.CodeSuccess.Value() {
return nil, fmt.Errorf("微信返回错误 StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status) return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status))
} }
return queryResp(request, resp), nil return queryResp(request, resp), nil
} }
@ -66,21 +80,27 @@ func (p *WeChatCpnService) Notify(ctx context.Context, request *proto.NotifyRequ
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = verify(ctx, config); err != nil { if err = verify(ctx, config); err != nil {
return nil, err return nil, err
} }
return notifyResp(), nil return notifyResp(), nil
} }
func (p *WeChatCpnService) err(_ context.Context, err error) error { func (p *WeChatCpnService) err(_ context.Context, err error) error {
errStr := err.Error() errStr := err.Error()
startIndex := strings.Index(errStr, "Message: ") startIndex := strings.Index(errStr, "Message: ")
if startIndex == -1 { if startIndex == -1 {
return err return err
} }
endIndex := strings.Index(errStr[startIndex:], "\n") endIndex := strings.Index(errStr[startIndex:], "\n")
if endIndex == -1 { if endIndex == -1 {
return err return err
} }
return fmt.Errorf(errStr[startIndex+len("Message: ") : startIndex+endIndex]) return fmt.Errorf(errStr[startIndex+len("Message: ") : startIndex+endIndex])
} }

View File

@ -5,7 +5,7 @@ go 1.22.2
replace plugins/utils => ../../utils replace plugins/utils => ../../utils
require ( require (
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca gitea.cdlsxd.cn/sdk/plugin v1.0.17
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
github.com/wechatpay-apiv3/wechatpay-go v0.2.18 github.com/wechatpay-apiv3/wechatpay-go v0.2.18
@ -16,6 +16,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-kratos/kratos/v2 v2.8.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-playground/validator/v10 v10.22.0 // indirect

View File

@ -1,5 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA= gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
@ -11,6 +11,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-kratos/kratos/v2 v2.8.2 h1:EsEA7AmPQ2YQQ0FZrDWO2HgBNqeWM8z/mWKzS5UkQaQ=
github.com/go-kratos/kratos/v2 v2.8.2/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -31,6 +33,10 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@ -44,6 +50,8 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@ -71,8 +79,9 @@ google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -14,7 +14,7 @@ func transConfig(config []byte) (*wechat.Server, error) {
var c wechat.Server var c wechat.Server
err := json.Unmarshal(config, &c) err := json.Unmarshal(config, &c)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorConfigFail(err.Error())
} }
if err = c.Validate(); err != nil { if err = c.Validate(); err != nil {
return nil, err return nil, err

View File

@ -24,43 +24,49 @@ func (p *WeChatRedPackService) Order(ctx context.Context, request *proto.OrderRe
if err != nil { if err != nil {
return nil, err return nil, err
} }
req, err := orderReq(request.GetOrder(), request.GetProduct()) req, err := orderReq(request.GetOrder(), request.GetProduct())
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorParamFail(err.Error())
} }
svc, err := transferBatchApiService(ctx, config) svc, err := transferBatchApiService(ctx, config)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorRequestFail(err.Error())
} }
resp, result, err := svc.InitiateBatchTransfer(ctx, req) resp, result, err := svc.InitiateBatchTransfer(ctx, req)
if err != nil { if err != nil {
return nil, p.err(ctx, err) return nil, proto.ErrorRequestFail("微信返回错误:" + p.err(ctx, err).Error())
} }
if result.Response.StatusCode != vo.CodeSuccess.Value() { if result.Response.StatusCode != vo.CodeSuccess.Value() {
return nil, fmt.Errorf("微信返回错误 Response StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status) return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status))
} }
return orderResp(request.GetOrder(), *resp.BatchId), nil return orderResp(request.GetOrder(), *resp.BatchId), nil
} }
func (p *WeChatRedPackService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) { func (p *WeChatRedPackService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) {
req, err := queryReq(request.GetOrder())
if err != nil {
return nil, err
}
config, err := transConfig(request.Config) config, err := transConfig(request.Config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
req, err := queryReq(request.GetOrder())
if err != nil {
return nil, proto.ErrorParamFail(err.Error())
}
svc, err := transferDetailApiService(ctx, config) svc, err := transferDetailApiService(ctx, config)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorRequestFail(err.Error())
} }
resp, result, err := svc.GetTransferDetailByOutNo(ctx, *req) resp, result, err := svc.GetTransferDetailByOutNo(ctx, *req)
if err != nil { if err != nil {
return nil, p.err(ctx, err) return nil, proto.ErrorRequestFail("微信返回错误:" + p.err(ctx, err).Error())
} }
if result.Response.StatusCode != vo.CodeSuccess.Value() { if result.Response.StatusCode != vo.CodeSuccess.Value() {
return nil, fmt.Errorf("微信返回错误 Response StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status) return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status))
} }
return queryResp(request, resp), nil return queryResp(request, resp), nil
} }

View File

@ -3,7 +3,7 @@ module plugins/zltx
go 1.22.2 go 1.22.2
require ( require (
gitea.cdlsxd.cn/sdk/plugin v1.0.6 gitea.cdlsxd.cn/sdk/plugin v1.0.15
github.com/carlmjohnson/requests v0.24.2 github.com/carlmjohnson/requests v0.24.2
github.com/go-playground/validator/v10 v10.22.0 github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1

View File

@ -2,6 +2,8 @@ gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8h
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0=
gitea.cdlsxd.cn/sdk/plugin v1.0.6 h1:fcQrgdRT4zVmxqK8rsB4Oo7jnhnXDqsgQ8GagR+DSic= gitea.cdlsxd.cn/sdk/plugin v1.0.6 h1:fcQrgdRT4zVmxqK8rsB4Oo7jnhnXDqsgQ8GagR+DSic=
gitea.cdlsxd.cn/sdk/plugin v1.0.6/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.6/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0=
gitea.cdlsxd.cn/sdk/plugin v1.0.15 h1:IcfTDd9K4QWX80gQuYurCavdsPyxi5tM5sW3MRGWdh8=
gitea.cdlsxd.cn/sdk/plugin v1.0.15/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso= github.com/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso=

View File

@ -3,7 +3,7 @@ module plugins/zltx_card
go 1.22.2 go 1.22.2
require ( require (
gitea.cdlsxd.cn/sdk/plugin v1.0.6 gitea.cdlsxd.cn/sdk/plugin v1.0.15
github.com/carlmjohnson/requests v0.24.2 github.com/carlmjohnson/requests v0.24.2
github.com/go-playground/validator/v10 v10.22.0 github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1

View File

@ -2,6 +2,8 @@ gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8h
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0=
gitea.cdlsxd.cn/sdk/plugin v1.0.6 h1:fcQrgdRT4zVmxqK8rsB4Oo7jnhnXDqsgQ8GagR+DSic= gitea.cdlsxd.cn/sdk/plugin v1.0.6 h1:fcQrgdRT4zVmxqK8rsB4Oo7jnhnXDqsgQ8GagR+DSic=
gitea.cdlsxd.cn/sdk/plugin v1.0.6/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.6/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0=
gitea.cdlsxd.cn/sdk/plugin v1.0.15 h1:IcfTDd9K4QWX80gQuYurCavdsPyxi5tM5sW3MRGWdh8=
gitea.cdlsxd.cn/sdk/plugin v1.0.15/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso= github.com/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso=

View File

@ -3,7 +3,7 @@ module plugins/zltx_card_v1
go 1.22.2 go 1.22.2
require ( require (
gitea.cdlsxd.cn/sdk/plugin v1.0.14 gitea.cdlsxd.cn/sdk/plugin v1.0.19
github.com/go-playground/validator/v10 v10.22.0 github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
@ -13,6 +13,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-kratos/kratos/v2 v2.8.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.4 // indirect

View File

@ -1,9 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.12 h1:gA7zRagOro38rbRVIfFgGRuGOr+Wig8EjeqQkYedFXc= gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.12/go.mod h1:FLuWLP2QP2aBzI2HCdZ7tvl1ieMuMOpTWvItmNGCeGA= gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.13 h1:v9YUJci9Npb6svojARQkkbWpdsm74/X9g/uAECtrCJg=
gitea.cdlsxd.cn/sdk/plugin v1.0.13/go.mod h1:FLuWLP2QP2aBzI2HCdZ7tvl1ieMuMOpTWvItmNGCeGA=
gitea.cdlsxd.cn/sdk/plugin v1.0.14 h1:nBV4AJYdFTiwOdIwhfKuhHg60DCcHOZDFW5/W42bqGM=
gitea.cdlsxd.cn/sdk/plugin v1.0.14/go.mod h1:FLuWLP2QP2aBzI2HCdZ7tvl1ieMuMOpTWvItmNGCeGA=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -12,6 +8,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-kratos/kratos/v2 v2.8.2 h1:EsEA7AmPQ2YQQ0FZrDWO2HgBNqeWM8z/mWKzS5UkQaQ=
github.com/go-kratos/kratos/v2 v2.8.2/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -32,6 +30,10 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@ -45,6 +47,8 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 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/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
@ -64,7 +68,8 @@ google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -7,6 +7,7 @@ import (
"gitea.cdlsxd.cn/sdk/plugin/dctw/v1/core" "gitea.cdlsxd.cn/sdk/plugin/dctw/v1/core"
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"net/http"
) )
type Config struct { type Config struct {
@ -21,7 +22,7 @@ func (c *Config) validate() error {
err := validator.New().Struct(c) err := validator.New().Struct(c)
if err != nil { if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("配置参数有误:" + err.Error()) return proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
} }
} }
return nil return nil
@ -31,7 +32,7 @@ func transConfig(config []byte) (*Config, error) {
var c Config var c Config
err := json.Unmarshal(config, &c) err := json.Unmarshal(config, &c)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorConfigFail(fmt.Sprintf("配置参数解析失败: %v", err))
} }
if err = c.validate(); err != nil { if err = c.validate(); err != nil {
return nil, err return nil, err
@ -54,6 +55,13 @@ func (c *Config) dctW() (*card.Card, error) {
return &card.Card{DctWServer: server}, nil return &card.Card{DctWServer: server}, nil
} }
func Result(message string) *proto.Result {
return &proto.Result{
Status: proto.Status_ING,
Message: fmt.Sprintf("需人工排查处理:%s", message),
}
}
func (c *Config) orderReq(in *proto.OrderRequest) *card.Order { func (c *Config) orderReq(in *proto.OrderRequest) *card.Order {
return &card.Order{ return &card.Order{
Number: in.Order.Quantity, Number: in.Order.Quantity,
@ -117,5 +125,14 @@ func notifyResp(resp *card.Notify, cardCode *card.CardCode) (*proto.NotifyRespon
}, },
Return: "success", Return: "success",
} }
responseHeaders := make(http.Header)
responseHeaders.Set("Content-Type", "text/plain")
responseHeadersBytes, err := json.Marshal(responseHeaders)
if err != nil {
return nil, err
}
pb.Headers = string(responseHeadersBytes)
return pb, nil return pb, nil
} }

View File

@ -20,7 +20,21 @@ const (
type ZLTXCardV1Service struct{} type ZLTXCardV1Service struct{}
func (p *ZLTXCardV1Service) Order(ctx context.Context, request *proto.OrderRequest) (*proto.OrderResponse, error) { func (p *ZLTXCardV1Service) Order(ctx context.Context, request *proto.OrderRequest) (resp2 *proto.OrderResponse, respErr error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
// 继续执行
}
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
}
}()
c, err := transConfig(request.Config) c, err := transConfig(request.Config)
if err != nil { if err != nil {
return nil, err return nil, err
@ -33,10 +47,13 @@ func (p *ZLTXCardV1Service) Order(ctx context.Context, request *proto.OrderReque
resp, err := dctW.Order(ctx, c.orderReq(request)) resp, err := dctW.Order(ctx, c.orderReq(request))
if err != nil { if err != nil {
if proto.IsResponseFail(err) {
return &proto.OrderResponse{Result: Result(err.Error())}, nil
}
return nil, err return nil, err
} }
if !resp.GetCode().IsSuccess() { if !resp.GetCode().IsSuccess() {
return nil, fmt.Errorf(resp.Message) return nil, proto.ErrorRequestFail(resp.Message)
} }
return orderResp(request, resp), nil return orderResp(request, resp), nil
@ -58,13 +75,27 @@ func (p *ZLTXCardV1Service) Query(ctx context.Context, request *proto.QueryReque
return nil, err return nil, err
} }
if !resp.GetCode().IsSuccess() { if !resp.GetCode().IsSuccess() {
return nil, fmt.Errorf(resp.Message) return nil, proto.ErrorRequestFail(resp.Message)
} }
return queryResp(request, resp, cardCode) return queryResp(request, resp, cardCode)
} }
func (p *ZLTXCardV1Service) Notify(ctx context.Context, request *proto.NotifyRequest) (*proto.NotifyResponse, error) { func (p *ZLTXCardV1Service) Notify(ctx context.Context, request *proto.NotifyRequest) (resp2 *proto.NotifyResponse, respErr error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
// 继续执行
}
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
}
}()
c, err := transConfig(request.Config) c, err := transConfig(request.Config)
if err != nil { if err != nil {
return nil, err return nil, err
@ -72,7 +103,7 @@ func (p *ZLTXCardV1Service) Notify(ctx context.Context, request *proto.NotifyReq
httpHeaders := make(http.Header) httpHeaders := make(http.Header)
if err = json.Unmarshal(request.Headers, &httpHeaders); err != nil { if err = json.Unmarshal(request.Headers, &httpHeaders); err != nil {
return nil, fmt.Errorf("headers Unmarshal err [%v]", err) return nil, proto.ErrorParamFail(fmt.Sprintf("headers Unmarshal err [%v]", err))
} }
newHeaders := make(http.Header) newHeaders := make(http.Header)
for key, values := range httpHeaders { for key, values := range httpHeaders {

View File

@ -9,23 +9,23 @@ import (
"testing" "testing"
) )
var zltx = &ZLTXCardV1Service{} var cardService = &ZLTXCardV1Service{}
func config() []byte { func config() []byte {
//c := &Config{
// AppId: "1",
// AppKey: "1e2bf7a04b8b1e6be5dc78d04e8639c9",
// BaseUri: "http://test.openapi.1688sup.cn",
// NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
// MerchantId: 23329,
//}
c := &Config{ c := &Config{
AppId: "101", AppId: "1",
AppKey: "95E7EC7D4A394FF8D11788E5E436DE99", AppKey: "1e2bf7a04b8b1e6be5dc78d04e8639c9",
BaseUri: "https://openapi.1688sup.com", BaseUri: "http://test.openapi.1688sup.cn",
NotifyUrl: "https://market.86698.cn/v1/order/direct/notify", NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
MerchantId: 25715, MerchantId: 23329,
} }
//c := &Config{
// AppId: "101",
// AppKey: "95E7EC7D4A394FF8D11788E5E436DE99",
// BaseUri: "https://openapi.1688sup.com",
// NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
// MerchantId: 25715,
//}
marshal, _ := json.Marshal(c) marshal, _ := json.Marshal(c)
return marshal return marshal
} }
@ -42,7 +42,7 @@ func TestOrder(t *testing.T) {
request := &proto.OrderRequest{ request := &proto.OrderRequest{
Config: config(), Config: config(),
Order: &proto.OrderRequest_Order{ Order: &proto.OrderRequest_Order{
OrderNo: "test_plugin_zltx_v1_card_2", OrderNo: "test_plugin_zltx_v1_card_3",
Account: "", Account: "",
Quantity: 1, Quantity: 1,
Extra: nil, Extra: nil,
@ -54,7 +54,7 @@ func TestOrder(t *testing.T) {
} }
t.Run("TestOrder", func(t *testing.T) { t.Run("TestOrder", func(t *testing.T) {
got, err := zltx.Order(context.Background(), request) got, err := cardService.Order(context.Background(), request)
if err != nil { if err != nil {
t.Errorf("Order() error = %v", err) t.Errorf("Order() error = %v", err)
return return
@ -68,14 +68,14 @@ func TestQuery(t *testing.T) {
request := &proto.QueryRequest{ request := &proto.QueryRequest{
Config: config(), Config: config(),
Order: &proto.QueryRequest_Order{ Order: &proto.QueryRequest_Order{
OrderNo: "test_plugin_zltx_v1_card_2", OrderNo: "test_plugin_zltx_v1_card_3",
TradeNo: "", TradeNo: "",
Account: "", Account: "",
Extra: nil, Extra: nil,
}, },
} }
t.Run("TestQuery", func(t *testing.T) { t.Run("TestQuery", func(t *testing.T) {
got, err := zltx.Query(context.Background(), request) got, err := cardService.Query(context.Background(), request)
if err != nil { if err != nil {
t.Errorf("Query() error = %v", err) t.Errorf("Query() error = %v", err)
return return
@ -89,11 +89,12 @@ func TestNotify(t *testing.T) {
in := &proto.NotifyRequest{ in := &proto.NotifyRequest{
Config: config(), Config: config(),
Queries: nil, Queries: nil,
Headers: []byte(`{"Accept-Encoding":["gzip, deflate, br"],"Authorization":["MD5 appid=101,sign=6ECA9F00E426FBE0137ACFA2920D058D"],"Connection":["close"],"Content-Length":["140"],"Content-Type":["application/json"],"Cookie":[""],"User-Agent":["GuzzleHttp/6.5.5 curl/7.69.1 PHP/7.2.34"],"X-Remoteaddr":["172.21.0.1"]}`), Headers: []byte(`{"Authorization":["MD5 appid=1,sign=A419BC9E70FA82CC07030A041A4DEEC1"]}`),
Body: []byte(`{"merchantId":25715,"outTradeNo":"202411261524470700010001","tradeNo":"715948765692968961","status":"01","cardCode":"AlT5ZLb4VwYbKqTudDcyR4WZzrOLFtMUD00HNNvBFs0="}`), Body: []byte(`{"merchantId":23369,"outTradeNo":"202501101143088400010016","tradeNo":"732200443106705409","status":"01","cardCode":"R7UVRxu5Zi8SockCksuZ3w=="}`),
} }
t.Run("TestNotify", func(t *testing.T) { t.Run("TestNotify", func(t *testing.T) {
got, err := zltx.Notify(context.Background(), in) got, err := cardService.Notify(context.Background(), in)
if !assert.Nil(t, err) { if !assert.Nil(t, err) {
t.Errorf("Notify() error = %v", err) t.Errorf("Notify() error = %v", err)
return return

View File

@ -3,16 +3,17 @@ module plugins/zltx_v1
go 1.22.2 go 1.22.2
require ( require (
gitea.cdlsxd.cn/sdk/plugin v1.0.14 gitea.cdlsxd.cn/sdk/plugin v1.0.20
github.com/go-playground/validator/v10 v10.22.0 github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.10.0
) )
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-kratos/kratos/v2 v2.8.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.4 // indirect

View File

@ -1,11 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.11 h1:NMMgw2p7ZF7EbWjkSO7ttM62BLhsG0bGmPdGGS1gpJc= gitea.cdlsxd.cn/sdk/plugin v1.0.20 h1:oAcqfHiOHoa+f9w6BPbvY9EZ0pwQ1mo3dD+YJD8OpYo=
gitea.cdlsxd.cn/sdk/plugin v1.0.11/go.mod h1:FLuWLP2QP2aBzI2HCdZ7tvl1ieMuMOpTWvItmNGCeGA= gitea.cdlsxd.cn/sdk/plugin v1.0.20/go.mod h1:W2zpoqi70a9X7n3WCLcZ0sjxXTPgYhiJW36FO+qKlb0=
gitea.cdlsxd.cn/sdk/plugin v1.0.12 h1:gA7zRagOro38rbRVIfFgGRuGOr+Wig8EjeqQkYedFXc=
gitea.cdlsxd.cn/sdk/plugin v1.0.12/go.mod h1:FLuWLP2QP2aBzI2HCdZ7tvl1ieMuMOpTWvItmNGCeGA=
gitea.cdlsxd.cn/sdk/plugin v1.0.13 h1:v9YUJci9Npb6svojARQkkbWpdsm74/X9g/uAECtrCJg=
gitea.cdlsxd.cn/sdk/plugin v1.0.13/go.mod h1:FLuWLP2QP2aBzI2HCdZ7tvl1ieMuMOpTWvItmNGCeGA=
gitea.cdlsxd.cn/sdk/plugin v1.0.14 h1:nBV4AJYdFTiwOdIwhfKuhHg60DCcHOZDFW5/W42bqGM=
gitea.cdlsxd.cn/sdk/plugin v1.0.14/go.mod h1:FLuWLP2QP2aBzI2HCdZ7tvl1ieMuMOpTWvItmNGCeGA=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -14,6 +8,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-kratos/kratos/v2 v2.8.2 h1:EsEA7AmPQ2YQQ0FZrDWO2HgBNqeWM8z/mWKzS5UkQaQ=
github.com/go-kratos/kratos/v2 v2.8.2/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -34,6 +30,10 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@ -47,9 +47,11 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
@ -66,7 +68,8 @@ google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -8,6 +8,7 @@ import (
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"gitea.cdlsxd.cn/sdk/plugin/utils" "gitea.cdlsxd.cn/sdk/plugin/utils"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"net/http"
"regexp" "regexp"
) )
@ -20,10 +21,9 @@ type Config struct {
} }
func (c *Config) validate() error { func (c *Config) validate() error {
err := validator.New().Struct(c) if err := validator.New().Struct(c); err != nil {
if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("配置参数有误:" + err.Error()) return proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
} }
} }
return nil return nil
@ -31,13 +31,15 @@ func (c *Config) validate() error {
func transConfig(config []byte) (*Config, error) { func transConfig(config []byte) (*Config, error) {
var c Config var c Config
err := json.Unmarshal(config, &c)
if err != nil { if err := json.Unmarshal(config, &c); err != nil {
return nil, err return nil, proto.ErrorSignFail(fmt.Sprintf("配置参数解析失败: %v,参数:%s", err, string(config)))
} }
if err = c.validate(); err != nil {
if err := c.validate(); err != nil {
return nil, err return nil, err
} }
return &c, nil return &c, nil
} }
@ -52,6 +54,13 @@ func (c *Config) server() (*core.DctWServer, error) {
) )
} }
func Result(message string) *proto.Result {
return &proto.Result{
Status: proto.Status_ING,
Message: fmt.Sprintf("需人工排查处理:%s", message),
}
}
func (c *Config) orderReq(in *proto.OrderRequest) (*direct.Order, error) { func (c *Config) orderReq(in *proto.OrderRequest) (*direct.Order, error) {
// 账号类型(1:手机号 2:QQ号 其他0) // 账号类型(1:手机号 2:QQ号 其他0)
accountType := int8(0) accountType := int8(0)
@ -61,13 +70,14 @@ func (c *Config) orderReq(in *proto.OrderRequest) (*direct.Order, error) {
qqPattern := `^[1-9][0-9]{4,11}$` qqPattern := `^[1-9][0-9]{4,11}$`
qqRegex, err := regexp.Compile(qqPattern) qqRegex, err := regexp.Compile(qqPattern)
if err != nil { if err != nil {
return nil, fmt.Errorf("正则表达式编译失败: %v", err) return nil, proto.ErrorParamFail(fmt.Sprintf("正则表达式编译失败: %v", err))
} }
if qqRegex.MatchString(in.Order.Account) { if qqRegex.MatchString(in.Order.Account) {
accountType = 2 accountType = 2
} }
} }
return &direct.Order{
d := &direct.Order{
Number: in.Order.Quantity, Number: in.Order.Quantity,
MerchantId: c.MerchantId, MerchantId: c.MerchantId,
OutTradeNo: in.Order.OrderNo, OutTradeNo: in.Order.OrderNo,
@ -76,7 +86,12 @@ func (c *Config) orderReq(in *proto.OrderRequest) (*direct.Order, error) {
RechargeAccount: in.Order.Account, RechargeAccount: in.Order.Account,
NotifyUrl: c.NotifyUrl, NotifyUrl: c.NotifyUrl,
Version: "1.0", Version: "1.0",
}, nil }
if in.Order.Extra != nil {
d.ExtendParameter = string(in.Order.Extra)
}
return d, nil
} }
func orderResp(request *proto.OrderRequest, resp *direct.OrderResp) *proto.OrderResponse { func orderResp(request *proto.OrderRequest, resp *direct.OrderResp) *proto.OrderResponse {
@ -101,8 +116,12 @@ func (c *Config) queryReq(in *proto.QueryRequest) *direct.Query {
} }
func queryResp(request *proto.QueryRequest, resp *direct.QueryResp) (*proto.QueryResponse, error) { func queryResp(request *proto.QueryRequest, resp *direct.QueryResp) (*proto.QueryResponse, error) {
data, _ := json.Marshal(resp) data, err := json.Marshal(resp)
pb := &proto.QueryResponse{ if err != nil {
return nil, err
}
return &proto.QueryResponse{
Result: &proto.Result{ Result: &proto.Result{
Status: resp.Status.GetOrderStatus(), Status: resp.Status.GetOrderStatus(),
OrderNo: request.Order.OrderNo, OrderNo: request.Order.OrderNo,
@ -111,12 +130,15 @@ func queryResp(request *proto.QueryRequest, resp *direct.QueryResp) (*proto.Quer
Data: data, Data: data,
Extra: nil, Extra: nil,
}, },
} }, nil
return pb, nil
} }
func notifyResp(resp *direct.Notify) (*proto.NotifyResponse, error) { func notifyResp(resp *direct.Notify) (*proto.NotifyResponse, error) {
data, _ := json.Marshal(resp) data, err := json.Marshal(resp)
if err != nil {
return nil, err
}
pb := &proto.NotifyResponse{ pb := &proto.NotifyResponse{
Result: &proto.Result{ Result: &proto.Result{
Status: resp.Status.GetOrderStatus(), Status: resp.Status.GetOrderStatus(),
@ -128,5 +150,16 @@ func notifyResp(resp *direct.Notify) (*proto.NotifyResponse, error) {
}, },
Return: "success", Return: "success",
} }
responseHeaders := make(http.Header)
responseHeaders.Set("Content-Type", "text/plain")
responseHeadersBytes, err := json.Marshal(responseHeaders)
if err != nil {
return nil, err
}
pb.Headers = string(responseHeadersBytes)
return pb, nil return pb, nil
} }

View File

@ -36,13 +36,17 @@ func (p *ZLTXV1Service) Order(ctx context.Context, request *proto.OrderRequest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
a := &direct.Direct{DctWServer: server} a := &direct.Direct{DctWServer: server}
resp, err := a.Order(ctx, req) resp, err := a.Order(ctx, req)
if err != nil { if err != nil {
if proto.IsResponseFail(err) {
return &proto.OrderResponse{Result: Result(err.Error())}, nil
}
return nil, err return nil, err
} }
if !resp.GetCode().IsSuccess() { if !resp.GetCode().IsSuccess() {
return nil, fmt.Errorf(resp.Message) return nil, proto.ErrorRequestFail(resp.Message)
} }
return orderResp(request, resp), nil return orderResp(request, resp), nil
@ -65,7 +69,7 @@ func (p *ZLTXV1Service) Query(ctx context.Context, request *proto.QueryRequest)
return nil, err return nil, err
} }
if !resp.GetCode().IsSuccess() { if !resp.GetCode().IsSuccess() {
return nil, fmt.Errorf(resp.Message) return nil, proto.ErrorRequestFail(resp.Message)
} }
return queryResp(request, resp) return queryResp(request, resp)
@ -84,7 +88,7 @@ func (p *ZLTXV1Service) Notify(ctx context.Context, request *proto.NotifyRequest
httpHeaders := make(http.Header) httpHeaders := make(http.Header)
if err = json.Unmarshal(request.Headers, &httpHeaders); err != nil { if err = json.Unmarshal(request.Headers, &httpHeaders); err != nil {
return nil, fmt.Errorf("headers Unmarshal err [%v]", err) return nil, proto.ErrorParamFail(fmt.Sprintf("headers Unmarshal err [%v]", err))
} }
newHeaders := make(http.Header) newHeaders := make(http.Header)
for key, values := range httpHeaders { for key, values := range httpHeaders {

View File

@ -6,26 +6,27 @@ import (
"fmt" "fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"net/http"
"testing" "testing"
) )
var zltx = &ZLTXV1Service{} var srv = &ZLTXV1Service{}
func config() []byte { func config() []byte {
//c := &Config{
// AppId: "1",
// AppKey: "1e2bf7a04b8b1e6be5dc78d04e8639c9",
// BaseUri: "http://test.openapi.1688sup.cn",
// NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
// MerchantId: 25537,
//}
c := &Config{ c := &Config{
AppId: "101", AppId: "1",
AppKey: "5k8bJV6axIukpkwz5vdte8QCw5etlC+txi+Nu69nIhOMN4VhmcNgf/THdllpt0jO", AppKey: "1e2bf7a04b8b1e6be5dc78d04e8639c9",
BaseUri: "https://openapi.1688sup.com", BaseUri: "http://test.openapi.1688sup.cn",
NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify", NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
MerchantId: 25537, MerchantId: 23369, // 23329
} }
//c := &Config{
// AppId: "101",
// AppKey: "95E7EC7D4A394FF8D11788E5E436DE99",
// BaseUri: "https://openapi.1688sup.com",
// NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
// MerchantId: 25715,
//}
marshal, _ := json.Marshal(c) marshal, _ := json.Marshal(c)
return marshal return marshal
} }
@ -39,22 +40,28 @@ func TestConfig(t *testing.T) {
} }
func TestOrder(t *testing.T) { func TestOrder(t *testing.T) {
//d := []byte(`{"jdSmsCode":"123456"}`)
//s := base64.StdEncoding.EncodeToString(d)
//t.Logf("%s\n", s)
request := &proto.OrderRequest{ request := &proto.OrderRequest{
Config: config(), Config: config(),
Order: &proto.OrderRequest_Order{ Order: &proto.OrderRequest_Order{
OrderNo: "test_plugin_zltx_v1_direct_1", OrderNo: "202501131732090710010002",
Account: "583989020@qq.com", Account: "18666173766",
Quantity: 1, Quantity: 1,
Extra: nil, //Extra: []byte(`{"jdCode":"123456"}`), // 京东e卡官方拓展参数
Extra: []byte(`{"jdSmsCode":"123456"}`), // 京东e卡专票拓展参数
}, },
Product: &proto.OrderRequest_Product{ Product: &proto.OrderRequest_Product{
ProductNo: "101", ProductNo: "360", // 101 2255 360
Extra: []byte(`{}`), Extra: []byte(`{}`),
}, },
} }
//t.Logf("%s\n", request.String())
//return
t.Run("TestOrder", func(t *testing.T) { t.Run("TestOrder", func(t *testing.T) {
got, err := zltx.Order(context.Background(), request) got, err := srv.Order(context.Background(), request)
if err != nil { if err != nil {
t.Errorf("Order() error = %v", err) t.Errorf("Order() error = %v", err)
return return
@ -65,8 +72,9 @@ func TestOrder(t *testing.T) {
} }
func TestQuery(t *testing.T) { func TestQuery(t *testing.T) {
c := config()
request := &proto.QueryRequest{ request := &proto.QueryRequest{
Config: config(), Config: c,
Order: &proto.QueryRequest_Order{ Order: &proto.QueryRequest_Order{
OrderNo: "test_plugin_zltx_v1_direct_1", OrderNo: "test_plugin_zltx_v1_direct_1",
TradeNo: "", TradeNo: "",
@ -74,8 +82,9 @@ func TestQuery(t *testing.T) {
Extra: nil, Extra: nil,
}, },
} }
t.Logf("%+v\n", c)
t.Run("TestQuery", func(t *testing.T) { t.Run("TestQuery", func(t *testing.T) {
got, err := zltx.Query(context.Background(), request) got, err := srv.Query(context.Background(), request)
if err != nil { if err != nil {
t.Errorf("Query() error = %v", err) t.Errorf("Query() error = %v", err)
return return
@ -89,15 +98,26 @@ func TestNotify(t *testing.T) {
in := &proto.NotifyRequest{ in := &proto.NotifyRequest{
Config: config(), Config: config(),
Queries: nil, Queries: nil,
Headers: []byte(`{"Accept-Encoding":["gzip, deflate, br"],"Authorization":["MD5 appid=1,sign=642F82644ABB88E73C04F7881B93E6FA"],"Connection":["close"],"Content-Length":["102"],"Content-Type":["application/json"],"Cookie":[""],"User-Agent":["GuzzleHttp/6.5.5 curl/7.69.1 PHP/7.2.34"],"X-Remoteaddr":["172.21.0.1"]}`), Headers: []byte(`{"Authorization":["MD5 appid=1,sign=A419BC9E70FA82CC07030A041A4DEEC1"]}`),
Body: []byte(`{"merchantId":"25537","outTradeNo":"test_zltx_direct_2","status":"03","rechargeAccount":"18666666666"}`), Body: []byte(`{"merchantId":23369,"outTradeNo":"202501101143088400010016","tradeNo":"732200443106705409","status":"01","cardCode":"R7UVRxu5Zi8SockCksuZ3w=="}`),
} }
t.Run("TestNotify", func(t *testing.T) { t.Run("TestNotify", func(t *testing.T) {
got, err := zltx.Notify(context.Background(), in) got, err := srv.Notify(context.Background(), in)
if !assert.Nil(t, err) { if !assert.Nil(t, err) {
t.Errorf("Notify() error = %v", err) t.Errorf("Notify() error = %v", err)
return return
} }
responseHeaders := make(http.Header)
err = json.Unmarshal([]byte(got.Headers), &responseHeaders)
if err != nil {
t.Error(err)
return
}
for s, strings := range responseHeaders {
t.Logf("%s: %+v", s, strings)
}
fmt.Printf("%+v\n", got) fmt.Printf("%+v\n", got)
assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status)) assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status))
}) })

View File

@ -5,12 +5,12 @@ go 1.22.2
replace plugins/utils => ../../utils replace plugins/utils => ../../utils
require ( require (
gitea.cdlsxd.cn/sdk/plugin v1.0.6 gitea.cdlsxd.cn/sdk/plugin v1.0.18
gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v0.0.0-20240919023950-493c464e0ed7 gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v1.0.3
github.com/carlmjohnson/requests v0.24.2
github.com/go-playground/validator/v10 v10.22.0 github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1 github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
google.golang.org/grpc v1.64.0
plugins/utils v0.0.0-00010101000000-000000000000 plugins/utils v0.0.0-00010101000000-000000000000
) )
@ -18,6 +18,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-kratos/kratos/v2 v2.8.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.4 // indirect
@ -38,7 +39,6 @@ require (
golang.org/x/sys v0.22.0 // indirect golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect golang.org/x/text v0.16.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
google.golang.org/grpc v1.64.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

View File

@ -1,19 +1,21 @@
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA= gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.6 h1:fcQrgdRT4zVmxqK8rsB4Oo7jnhnXDqsgQ8GagR+DSic= gitea.cdlsxd.cn/sdk/plugin v1.0.18 h1:YgVJmCSSEu8JAniXlT1rI+h0w3EEGDRWLFqjk/5xBQY=
gitea.cdlsxd.cn/sdk/plugin v1.0.6/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.18/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v0.0.0-20240919023950-493c464e0ed7 h1:2wOzkUfS17P6U/i6CWFjLyXrdLMnW3osk897ZfOUCxY= gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v0.0.0-20240919023950-493c464e0ed7 h1:2wOzkUfS17P6U/i6CWFjLyXrdLMnW3osk897ZfOUCxY=
gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v0.0.0-20240919023950-493c464e0ed7/go.mod h1:aS6ecVHvGLGzYYFIhxBrRWmq69ifo6pt1G92QblSdQQ= gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v0.0.0-20240919023950-493c464e0ed7/go.mod h1:aS6ecVHvGLGzYYFIhxBrRWmq69ifo6pt1G92QblSdQQ=
gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v1.0.3 h1:vzHsHkJwFvobFxVlHQM8lEZY4h07TqR6cakjTqDHCQQ=
gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v1.0.3/go.mod h1:aS6ecVHvGLGzYYFIhxBrRWmq69ifo6pt1G92QblSdQQ=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso=
github.com/carlmjohnson/requests v0.24.2/go.mod h1:duYA/jDnyZ6f3xbcF5PpZ9N8clgopubP2nK5i6MVMhU=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-kratos/kratos/v2 v2.8.2 h1:EsEA7AmPQ2YQQ0FZrDWO2HgBNqeWM8z/mWKzS5UkQaQ=
github.com/go-kratos/kratos/v2 v2.8.2/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -38,6 +40,10 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5i
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE= github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@ -55,6 +61,8 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 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/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
@ -74,7 +82,8 @@ google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -2,23 +2,27 @@ package internal
import ( import (
"encoding/json" "encoding/json"
"fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/api" "gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/api"
"gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/notify" "gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/notify"
"gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/sdk" "gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/sdk"
"github.com/go-playground/validator/v10"
"net/http"
"plugins/zltxv2/internal/vo" "plugins/zltxv2/internal/vo"
) )
type Config struct { type Config struct {
AppId string `json:"app_id"` AppId string `json:"app_id" validate:"required"`
AppKey string `json:"app_key"` AppKey string `json:"app_key" validate:"required"`
BaseUri string `json:"base_uri"` BaseUri string `json:"base_uri" validate:"required"`
NotifyUrl string `json:"notify_url"` NotifyUrl string `json:"notify_url"`
} }
type Card struct { type Card struct {
Number string `json:"number"` Number string `json:"number"`
Password string `json:"password"` Password string `json:"password"`
Deadline string `json:"deadline"`
} }
func (c *Card) ToJson() []byte { func (c *Card) ToJson() []byte {
@ -26,22 +30,43 @@ func (c *Card) ToJson() []byte {
return bytes return bytes
} }
func (c *Config) validate() error {
if err := validator.New().Struct(c); err != nil {
for _, err = range err.(validator.ValidationErrors) {
return proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
}
}
return nil
}
func transConfig(config []byte) (*Config, error) { func transConfig(config []byte) (*Config, error) {
var c Config var c Config
err := json.Unmarshal(config, &c)
if err != nil { if err := json.Unmarshal(config, &c); err != nil {
return nil, proto.ErrorConfigFail(err.Error())
}
if err := c.validate(); err != nil {
return nil, err return nil, err
} }
return &c, nil return &c, nil
} }
func (c *Config) client() (*sdk.Client, error) { func (c *Config) client() (*sdk.Client, error) {
scheme := getScheme(c.BaseUri) scheme := getScheme(c.BaseUri)
domain, err := getDomain(c.BaseUri, scheme) domain, err := getDomain(c.BaseUri, scheme)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorConfigFail(err.Error())
} }
return sdk.NewClientWithAccessKey(c.AppKey, scheme, domain)
cl, err := sdk.NewClientWithAccessKey(c.AppKey, scheme, domain)
if err != nil {
return nil, proto.ErrorConfigFail(err.Error())
}
return cl, nil
} }
func (c *Config) orderReq(in *proto.OrderRequest) *api.OrderCreateReq { func (c *Config) orderReq(in *proto.OrderRequest) *api.OrderCreateReq {
@ -81,8 +106,9 @@ func (c *Config) queryReq(in *proto.QueryRequest) *api.OrderQueryReq {
func queryResp(appKey string, request *proto.QueryRequest, resp *api.OrderQueryResp) (*proto.QueryResponse, error) { func queryResp(appKey string, request *proto.QueryRequest, resp *api.OrderQueryResp) (*proto.QueryResponse, error) {
data, err := json.Marshal(resp) data, err := json.Marshal(resp)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorResponseFail(err.Error())
} }
status := vo.OrderStatus(resp.TradeStatus) status := vo.OrderStatus(resp.TradeStatus)
pb := &proto.QueryResponse{ pb := &proto.QueryResponse{
Result: &proto.Result{ Result: &proto.Result{
@ -94,6 +120,7 @@ func queryResp(appKey string, request *proto.QueryRequest, resp *api.OrderQueryR
Extra: nil, Extra: nil,
}, },
} }
if len(resp.Cards) > 0 { if len(resp.Cards) > 0 {
c, err := getQueryCard(appKey, &resp.Cards[0]) c, err := getQueryCard(appKey, &resp.Cards[0])
if err != nil { if err != nil {
@ -101,28 +128,34 @@ func queryResp(appKey string, request *proto.QueryRequest, resp *api.OrderQueryR
} }
pb.Result.Extra = c.ToJson() pb.Result.Extra = c.ToJson()
} }
return pb, nil return pb, nil
} }
func getQueryCard(appKey string, card *api.Cards) (*Card, error) { func getQueryCard(appKey string, card *api.Cards) (*Card, error) {
car := &Card{} car := &Card{
Deadline: card.Deadline,
}
t := vo.CardType(card.CardType) t := vo.CardType(card.CardType)
if t.IsPwdNo() { if t.IsPwdNo() {
pwd, err := decryptAES(card.Pwd, appKey) pwd, err := decryptAES(card.Pwd, appKey)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorResponseFail(err.Error())
} }
no, err := decryptAES(card.No, appKey) no, err := decryptAES(card.No, appKey)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorResponseFail(err.Error())
} }
car.Password = pwd car.Password = pwd
car.Number = no car.Number = no
} else if t.IsPwd() { } else if t.IsPwd() {
pwd, err := decryptAES(card.Pwd, appKey) pwd, err := decryptAES(card.Pwd, appKey)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorResponseFail(err.Error())
} }
car.Password = pwd car.Password = pwd
} else if t.IsUrl() { } else if t.IsUrl() {
// 无 // 无
@ -133,8 +166,9 @@ func getQueryCard(appKey string, card *api.Cards) (*Card, error) {
func notifyResp(appKey string, resp *notify.OrderReq) (*proto.NotifyResponse, error) { func notifyResp(appKey string, resp *notify.OrderReq) (*proto.NotifyResponse, error) {
data, err := json.Marshal(resp) data, err := json.Marshal(resp)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorResponseFail(err.Error())
} }
status := vo.OrderStatus(resp.TradeStatus) status := vo.OrderStatus(resp.TradeStatus)
pb := &proto.NotifyResponse{ pb := &proto.NotifyResponse{
Result: &proto.Result{ Result: &proto.Result{
@ -145,13 +179,26 @@ func notifyResp(appKey string, resp *notify.OrderReq) (*proto.NotifyResponse, er
Data: data, Data: data,
Extra: nil, Extra: nil,
}, },
Return: "SUCCESS", Return: `{"code": "SUCCESS"}`,
} }
responseHeaders := make(http.Header)
responseHeaders.Set("Content-Type", "application/json")
responseHeadersBytes, err := json.Marshal(responseHeaders)
if err != nil {
return nil, err
}
pb.Headers = string(responseHeadersBytes)
b, err := getNotifyCard(appKey, resp.Cards) b, err := getNotifyCard(appKey, resp.Cards)
if err != nil { if err != nil {
return nil, err return nil, err
} }
pb.Result.Extra = b pb.Result.Extra = b
return pb, nil return pb, nil
} }
@ -159,28 +206,45 @@ func getNotifyCard(appKey string, cards []notify.Cards) ([]byte, error) {
if len(cards) == 0 { if len(cards) == 0 {
return nil, nil return nil, nil
} }
card := cards[0] card := cards[0]
car := &Card{} car := &Card{
Deadline: card.Deadline,
}
t := vo.CardType(card.CardType) t := vo.CardType(card.CardType)
if t.IsPwdNo() { if t.IsPwdNo() {
pwd, err := decryptAES(card.Pwd, appKey) pwd, err := decryptAES(card.Pwd, appKey)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorResponseFail(err.Error())
} }
no, err := decryptAES(card.No, appKey) no, err := decryptAES(card.No, appKey)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorResponseFail(err.Error())
} }
car.Password = pwd car.Password = pwd
car.Number = no car.Number = no
} else if t.IsPwd() { } else if t.IsPwd() {
pwd, err := decryptAES(card.Pwd, appKey) pwd, err := decryptAES(card.Pwd, appKey)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorResponseFail(err.Error())
} }
car.Password = pwd car.Password = pwd
} else if t.IsUrl() { } else if t.IsUrl() {
// 无
if len(card.Url) == 0 {
return nil, proto.ErrorResponseFail("url is empty")
}
pwd, err := decryptAES(card.Url, appKey)
if err != nil {
return nil, proto.ErrorResponseFail(err.Error())
}
car.Password = pwd
} }
return car.ToJson(), nil return car.ToJson(), nil
} }

View File

@ -15,6 +15,8 @@ func (o AccountType) AccountType(account string) AccountType {
return AccountTypeDefault return AccountTypeDefault
} else if helper.IsPhoneNumber(account) { } else if helper.IsPhoneNumber(account) {
return AccountTypePhone return AccountTypePhone
} else if helper.IsValidQQ(account) {
return AccountTypeQQ
} }
return AccountTypeDefault return AccountTypeDefault
} }

View File

@ -10,7 +10,6 @@ import (
"gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/notify" "gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/notify"
"io" "io"
"net/http" "net/http"
"strings"
) )
// 插件通信信息,若不对应则会报错panic // 插件通信信息,若不对应则会报错panic
@ -28,16 +27,19 @@ func (p *ZLTXV2Service) Order(ctx context.Context, request *proto.OrderRequest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
client, err := c.client() client, err := c.client()
if err != nil { if err != nil {
return nil, err return nil, err
} }
response, errResp, err := api.OrderCreate(ctx, client, c.AppId, c.orderReq(request)) response, errResp, err := api.OrderCreate(ctx, client, c.AppId, c.orderReq(request))
if err != nil { if err != nil {
return nil, fmt.Errorf("请求异常[%v]", err) return nil, proto.ErrorRequestFail(fmt.Sprintf("请求异常[%v]", err))
} }
if errResp != nil { if errResp != nil {
return nil, fmt.Errorf("请求错误[code:%d]-[reason:%s]-[msg:%s]", errResp.Code, errResp.Reason, errResp.Message) return nil, proto.ErrorRequestFail(fmt.Sprintf("请求错误[code:%d]-[reason:%s]-[msg:%s]", errResp.Code, errResp.Reason, errResp.Message))
} }
return orderResp(request, response), nil return orderResp(request, response), nil
@ -48,6 +50,7 @@ func (p *ZLTXV2Service) Query(ctx context.Context, request *proto.QueryRequest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
client, err := c.client() client, err := c.client()
if err != nil { if err != nil {
return nil, err return nil, err
@ -55,39 +58,35 @@ func (p *ZLTXV2Service) Query(ctx context.Context, request *proto.QueryRequest)
response, errResp, err := api.OrderQuery(ctx, client, c.AppId, c.queryReq(request)) response, errResp, err := api.OrderQuery(ctx, client, c.AppId, c.queryReq(request))
if err != nil { if err != nil {
return nil, fmt.Errorf("请求异常[%v]", err) return nil, proto.ErrorRequestFail(fmt.Sprintf("请求异常[%v]", err))
} }
if errResp != nil { if errResp != nil {
return nil, fmt.Errorf("请求错误[code:%d]-[reason:%s]-[msg:%s]", errResp.Code, errResp.Reason, errResp.Message) return nil, proto.ErrorRequestFail(fmt.Sprintf("请求错误[code:%d]-[reason:%s]-[msg:%s]", errResp.Code, errResp.Reason, errResp.Message))
} }
return queryResp(c.AppKey, request, response) return queryResp(c.AppKey, request, response)
} }
func (p *ZLTXV2Service) Notify(_ context.Context, request *proto.NotifyRequest) (*proto.NotifyResponse, error) { func (p *ZLTXV2Service) Notify(_ context.Context, request *proto.NotifyRequest) (*proto.NotifyResponse, error) {
req := &http.Request{
Header: nil,
Body: nil,
}
httpHeaders := make(http.Header) httpHeaders := make(http.Header)
if err := json.Unmarshal(request.Headers, &httpHeaders); err != nil { if err := json.Unmarshal(request.Headers, &httpHeaders); err != nil {
return nil, fmt.Errorf("headers Unmarshal err [%v]", err) return nil, proto.ErrorParamFail(fmt.Sprintf("headers Unmarshal err [%v]", err))
} }
newHeaders := make(http.Header)
for key, values := range httpHeaders { req := &http.Request{
newKey := strings.ToTitle(strings.ToLower(key)) Header: httpHeaders,
newHeaders[newKey] = values Body: io.NopCloser(bytes.NewBuffer(request.Body)),
} }
req.Header = newHeaders
req.Body = io.NopCloser(bytes.NewBuffer(request.Body))
c, err := transConfig(request.Config) c, err := transConfig(request.Config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
n, err := notify.NewNotify(c.AppId, c.AppKey).ParseAndVerify(req) n, err := notify.NewNotify(c.AppId, c.AppKey).ParseAndVerify(req)
if err != nil { if err != nil {
return nil, err return nil, proto.ErrorSignFail(err.Error())
} }
return notifyResp(c.AppKey, n) return notifyResp(c.AppKey, n)

View File

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto" "gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"google.golang.org/grpc/metadata" "net/http"
"testing" "testing"
) )
@ -14,12 +14,12 @@ var zltx = &ZLTXV2Service{}
func config() []byte { func config() []byte {
c := &Config{ c := &Config{
AppId: "23329", AppId: "25891",
AppKey: "8db16e8cc8363ed4eb4c14f9520bcc32", AppKey: "83cc38e09560417ad7ea0feaaae9d171",
BaseUri: "http://211.137.105.198:17100", BaseUri: "http://211.137.105.198:17100",
//NotifyUrl: "https://utils.85938.cn/utils/v1/wechat/notify", NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
NotifyUrl: "http://120.55.12.245:8098/v1/order/direct/notify",
} }
//{"app_id":"25891","app_key":"83cc38e09560417ad7ea0feaaae9d171","merchant_id":25891}
marshal, _ := json.Marshal(c) marshal, _ := json.Marshal(c)
return marshal return marshal
} }
@ -36,7 +36,7 @@ func TestOrder(t *testing.T) {
request := &proto.OrderRequest{ request := &proto.OrderRequest{
Config: config(), Config: config(),
Order: &proto.OrderRequest_Order{ Order: &proto.OrderRequest_Order{
OrderNo: "test_zltx_v2_6", OrderNo: "test_zltx_v2_7",
Account: "18666173766", Account: "18666173766",
Quantity: 1, Quantity: 1,
Extra: nil, Extra: nil,
@ -62,8 +62,8 @@ func TestQuery(t *testing.T) {
request := &proto.QueryRequest{ request := &proto.QueryRequest{
Config: config(), Config: config(),
Order: &proto.QueryRequest_Order{ Order: &proto.QueryRequest_Order{
OrderNo: "test_zltx_v2_3", OrderNo: "test_zltx_v2_7",
TradeNo: "", TradeNo: "", // 731095414466813953
Account: "", Account: "",
Extra: nil, Extra: nil,
}, },
@ -80,42 +80,30 @@ func TestQuery(t *testing.T) {
} }
func TestNotify(t *testing.T) { func TestNotify(t *testing.T) {
jsonData := []byte(`{ bodyBytes := []byte(`{"tradeStatus":"SUCCESS","orderNo":"C2169720720874659840","tradeStateDesc":"成功","cards":[{"no":"RpHWw3cEhiRW764pFoKVHKRypwZg8Txf0YAW8dE+F7lsrkoUKaAlkYL549lRWp+Q","pwd":"","url":"hei8pdKAWO7aiFHPmtZWg1iTupwk3oXV8QH7IVBtUpoPhFt6wksIiN034wbbe9sOo8Wpl7iOXUVSd50mJdwDknUi8BpitNpODfjjiTt7vTk=","deadline":"2025-09-30 00:00:00","cardType":3}],"mchId":25891,"outTradeNo":"202504031355308910010048","rechargeAccount":"","attach":"","unitPrice":27}`)
"tradeStatus": "SUCCESS", headerBytes := []byte(`{"Accept-Encoding":["gzip"],"Authorization":["a4decf2803323a023d187578f85f4d21"],"Connection":["close"],"Content-Length":["442"],"Content-Type":["application/json"],"Lsxd-Api-Proxy":["v2"],"Lsxd-From-System":["card"],"Lsxd-Signature":["bc0eb734101796c5bd1fe72472b406a4"],"Lsxd-Timestamp":["1743659731"],"User-Agent":["Go-http-client/1.1"],"X-Envoy-Attempt-Count":["1"],"X-Forwarded-Client-Cert":["By=spiffe://cluster.local/ns/gopro/sa/default;Hash=4798784d2ecd4218a4b71b4d08737f9714e2dbd508446d916b2999fd22d5811c;Subject=\"\";URI=spiffe://cluster.local/ns/card/sa/default"],"X-Forwarded-For":["112.124.3.46"],"X-Forwarded-Proto":["http"],"X-Real-Ip":["112.124.3.46"],"X-Remoteaddr":["172.18.0.1"],"X-Request-Id":["eab52927-95c8-4e64-9f5c-8a5f2aa339c1"]}`)
"orderNo": "C2081410801687044096",
"tradeStateDesc": "成功",
"cards": [
{"no":"*","pwd":"*","deadline":"2024-07-03 23:59:59","cardType":1}
],
"mchId": 23329,
"outTradeNo": "20240802212326527830",
"rechargeAccount": "17384082748",
"unitPrice":102.5
}`)
md := metadata.New(map[string]string{
"Authorization": "292e21f3683219369cf68dede0d45730",
"Content-Type": "application/json",
})
ctx := metadata.NewIncomingContext(context.Background(), md)
headerData, ok := metadata.FromIncomingContext(ctx)
if !ok {
t.Error("无法获取 Header 数据")
return
}
HeaderBytes, _ := json.Marshal(headerData)
in := &proto.NotifyRequest{ in := &proto.NotifyRequest{
Config: config(), Config: config(),
Queries: nil, Queries: nil,
Headers: HeaderBytes, Headers: headerBytes,
Body: jsonData, Body: bodyBytes,
} }
t.Run("TestNotify", func(t *testing.T) { t.Run("TestNotify", func(t *testing.T) {
got, err := zltx.Notify(ctx, in) got, err := zltx.Notify(context.Background(), in)
if !assert.Nil(t, err) { if !assert.Nil(t, err) {
t.Errorf("Notify() error = %v", err) t.Errorf("Notify() error = %v", err)
return return
} }
fmt.Printf("%s \n", got.String())
responseHeaders := make(http.Header)
_ = json.Unmarshal([]byte(got.Headers), &responseHeaders)
for s, strings := range responseHeaders {
t.Logf("%s: %v", s, strings)
}
t.Logf("%s \n", got.String())
assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status)) assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status))
}) })
} }

View File

@ -44,34 +44,41 @@ func GetCert(appId string) (*CertConfig, error) {
if c != nil { if c != nil {
return c, nil return c, nil
} }
dir, err := os.Getwd() dir, err := os.Getwd()
if err != nil { if err != nil {
return nil, fmt.Errorf("get current dir error: %v", err) return nil, fmt.Errorf("get current dir error: %v", err)
} }
filePath := fmt.Sprintf("%s/%s/%s/%s", dir, "cert", "alipay", appId) filePath := fmt.Sprintf("%s/%s/%s/%s", dir, "cert", "alipay", appId)
if !helper.FileExists(filePath) { if !helper.FileExists(filePath) {
return nil, fmt.Errorf("appId[%s]支付宝密钥文件信息不存在,请联系技术人员处理", appId) return nil, fmt.Errorf("appId[%s][%s]支付宝密钥文件信息不存在,请联系技术人员处理", appId, filePath)
} }
mchCertPath := fmt.Sprintf("%s/%s_%s.crt", filePath, "appCertPublicKey", appId) mchCertPath := fmt.Sprintf("%s/%s_%s.crt", filePath, "appCertPublicKey", appId)
mchCertSN, err := getMchCertSN(mchCertPath) mchCertSN, err := getMchCertSN(mchCertPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("get mchCertSN error: %v", err) return nil, fmt.Errorf("get mchCertSN error: %v", err)
} }
rootCertPath := fmt.Sprintf("%s/%s", filePath, "alipayRootCert.crt") rootCertPath := fmt.Sprintf("%s/%s", filePath, "alipayRootCert.crt")
rootCertSN, err := getRootCertSN(rootCertPath) rootCertSN, err := getRootCertSN(rootCertPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("get rootCertSN error: %v", err) return nil, fmt.Errorf("get rootCertSN error: %v", err)
} }
publicKeyPath := fmt.Sprintf("%s/%s", filePath, "alipayCertPublicKey_RSA2.crt") publicKeyPath := fmt.Sprintf("%s/%s", filePath, "alipayCertPublicKey_RSA2.crt")
publicKey, err := getPublicKey(publicKeyPath) publicKey, err := getPublicKey(publicKeyPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("get publicKey error: %v", err) return nil, fmt.Errorf("get publicKey error: %v", err)
} }
c = &CertConfig{ c = &CertConfig{
MchCertSN: mchCertSN, MchCertSN: mchCertSN,
RootCertSN: rootCertSN, RootCertSN: rootCertSN,
PublicKey: publicKey, PublicKey: publicKey,
} }
setCertConfig(appId, c) setCertConfig(appId, c)
return c, nil return c, nil
} }

View File

@ -3,7 +3,7 @@ module plugins/utils
go 1.22.2 go 1.22.2
require ( require (
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240830100334-2e99a5df732b gitea.cdlsxd.cn/sdk/plugin v1.0.17
github.com/go-playground/validator/v10 v10.22.0 github.com/go-playground/validator/v10 v10.22.0
github.com/tjfoc/gmsm v1.4.1 github.com/tjfoc/gmsm v1.4.1
github.com/wechatpay-apiv3/wechatpay-go v0.2.18 github.com/wechatpay-apiv3/wechatpay-go v0.2.18

View File

@ -1,6 +1,6 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240830100334-2e99a5df732b h1:x8Gf1EJ6oLHEIgK/SilgMZ5EDgcEknef9zhGrFvXXMg= gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240830100334-2e99a5df732b/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=

View File

@ -33,7 +33,8 @@ func IsEmail(email string) bool {
// IsValidQQ 检查给定的字符串是否为有效的 QQ 号 // IsValidQQ 检查给定的字符串是否为有效的 QQ 号
func IsValidQQ(qq string) bool { func IsValidQQ(qq string) bool {
// QQ号正则表达式5到11位数字且开头不为0的情况 // QQ号正则表达式5到11位数字且开头不为0的情况,
re := regexp.MustCompile(`^(?!0)[0-9]{5,11}$`) regex := `^[1-9][0-9]{4,11}$`
return re.MatchString(qq) //re := regexp.MustCompile(`^[1-9]\d{4,10}$`)
return regexp.MustCompile(regex).MatchString(qq)
} }

View File

@ -7,3 +7,9 @@ func TestToChinese(t *testing.T) {
got := ToChinese(arg) got := ToChinese(arg)
t.Log(got) t.Log(got)
} }
func TestAccountType(t *testing.T) {
arg := "3122222222"
got := IsValidQQ(arg)
t.Log(got)
}

View File

@ -9,30 +9,90 @@ import (
"time" "time"
) )
func Request(_ context.Context, method, url string, body []byte) ([]byte, http.Header, error) { type Options struct {
req, err := http.NewRequest(method, url, bytes.NewBuffer(body)) Headers http.Header
if err != nil {
return nil, nil, err StatusCodeFunc func(int) bool
}
Timeout time.Duration
}
func NewOptions(options ...Option) *Options {
o := &Options{
Headers: http.Header{
"Content-Type": []string{"application/json"},
},
StatusCodeFunc: func(code int) bool {
return code == http.StatusOK
},
httpClient := &http.Client{
Timeout: 15 * time.Second, Timeout: 15 * time.Second,
} }
for _, option := range options {
option(o)
}
return o
}
type Option func(*Options)
func WithTimeout(timeout time.Duration) Option {
return func(options *Options) {
options.Timeout = timeout
}
}
func WithHeaders(headers http.Header) Option {
return func(options *Options) {
options.Headers = headers
}
}
func WithStatusCodeFunc(statusCodeFunc func(int) bool) Option {
return func(options *Options) {
options.StatusCodeFunc = statusCodeFunc
}
}
func Post(ctx context.Context, url string, body []byte, options ...Option) (http.Header, []byte, error) {
return Request(ctx, http.MethodPost, url, body, NewOptions(options...))
}
func Get(ctx context.Context, url string, options ...Option) (http.Header, []byte, error) {
return Request(ctx, http.MethodGet, url, nil, NewOptions(options...))
}
func Put(ctx context.Context, url string, body []byte, options ...Option) (http.Header, []byte, error) {
return Request(ctx, http.MethodPut, url, body, NewOptions(options...))
}
func Request(_ context.Context, method, url string, body []byte, o *Options) (http.Header, []byte, error) {
req, err := http.NewRequest(method, url, bytes.NewBuffer(body))
if err != nil {
return nil, nil, fmt.Errorf("创建HTTP请求失败: %w", err)
}
req.Header = o.Headers
httpClient := &http.Client{
Timeout: o.Timeout,
}
resp, err := httpClient.Do(req) resp, err := httpClient.Do(req)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, fmt.Errorf("发送HTTP请求失败: %w", err)
} }
defer resp.Body.Close() defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body) bodyBytes, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, fmt.Errorf("读取响应体失败: %w", err)
} }
if resp.StatusCode != http.StatusOK { if !o.StatusCodeFunc(resp.StatusCode) {
return nil, nil, fmt.Errorf("请求异常:%s", resp.Status) return nil, nil, fmt.Errorf("请求异常:%s", resp.Status)
} }
return bodyBytes, resp.Header, nil return resp.Header, bodyBytes, nil
} }

View File

@ -0,0 +1,66 @@
package request
import (
"context"
"net/http"
"net/url"
"testing"
"time"
)
func Test_Get(t *testing.T) {
uri := "https://gateway.dev.cdlsxd.cn/adminyx/admin/v1/key_batch/list"
uv := url.Values{}
uv.Set("page", "1")
uv.Set("limit", "2")
h := http.Header{
"Content-Type": []string{"application/x-www-form-urlencoded"},
}
respHeader, respBody, err := Get(context.Background(), uri+"?"+uv.Encode(), WithHeaders(h))
if err != nil {
t.Error(err)
return
}
t.Logf("响应体:", string(respBody))
t.Logf("响应头:", respHeader)
}
func Test_RequestHeaders(t *testing.T) {
uri := "http://example.com/api"
body := []byte("request body")
h := http.Header{
"Content-Type": []string{"application/json"},
"Authorization": []string{"Bearer token"},
}
respHeader, respBody, err := Post(context.Background(), uri, body, WithTimeout(10*time.Second), WithHeaders(h))
if err != nil {
t.Error(err)
return
}
t.Logf("响应体:", string(respBody))
t.Logf("响应头:", respHeader)
}
func Test_RequestStatusCode(t *testing.T) {
uri := "http://example.com/api/update"
body := []byte("update data")
isSuccess := func(code int) bool {
return code == http.StatusOK || code == http.StatusCreated
}
respHeader, respBody, err := Put(context.Background(), uri, body, WithStatusCodeFunc(isSuccess))
if err != nil {
t.Error(err)
return
}
t.Logf("响应体:", string(respBody))
t.Logf("响应头:", respHeader)
}

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"crypto/x509" "crypto/x509"
"fmt" "fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/core/option" "github.com/wechatpay-apiv3/wechatpay-go/core/option"
@ -21,7 +22,7 @@ func (c *Server) Validate() error {
err := validator.New().Struct(c) err := validator.New().Struct(c)
if err != nil { if err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return fmt.Errorf("配置有误:" + err.Error()) return proto.ErrorConfigFail("配置有误:" + err.Error())
} }
} }
return nil return nil
@ -30,23 +31,27 @@ func (c *Server) Validate() error {
func newClient(ctx context.Context, c *Server) (*core.Client, error) { func newClient(ctx context.Context, c *Server) (*core.Client, error) {
dir, err := os.Getwd() dir, err := os.Getwd()
if err != nil { if err != nil {
return nil, fmt.Errorf("MchID[%s] get current dir error:%v", c.MchID, err) return nil, proto.ErrorConfigFail(fmt.Sprintf("MchID[%s] get current dir error:%v", c.MchID, err))
} }
filePath := fmt.Sprintf("%s/%s/%s/%s", dir, "cert", "wechat", c.MchID) filePath := fmt.Sprintf("%s/%s/%s/%s", dir, "cert", "wechat", c.MchID)
if !putils.FileExists(filePath) { if !putils.FileExists(filePath) {
return nil, fmt.Errorf("MchID[%s]微信密钥证书信息不存在,请联系技术人员处理", c.MchID) return nil, proto.ErrorConfigFail(fmt.Sprintf("MchID[%s]微信密钥证书信息不存在,请联系技术人员处理", c.MchID))
} }
// 商户相关配置,商户API私钥 // 商户相关配置,商户API私钥
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(fmt.Sprintf("%s/%s", filePath, "wechat_private_key.pem")) mchPrivateKey, err := utils.LoadPrivateKeyWithPath(fmt.Sprintf("%s/%s", filePath, "wechat_private_key.pem"))
if err != nil { if err != nil {
return nil, fmt.Errorf("MchID[%s] load merchant private key error:%v", c.MchID, err) return nil, proto.ErrorConfigFail(fmt.Sprintf("MchID[%s] load merchant private key error:%v", c.MchID, err))
} }
var client *core.Client var client *core.Client
// 微信支付平台配置 // 微信支付平台配置
wechatPayCertificate, err := utils.LoadCertificateWithPath(fmt.Sprintf("%s/%s", filePath, "wechat_cert.pem")) wechatPayCertificate, err := utils.LoadCertificateWithPath(fmt.Sprintf("%s/%s", filePath, "wechat_cert.pem"))
if err != nil { if err != nil {
return nil, fmt.Errorf("平台证书有误:%v", err) return nil, proto.ErrorConfigFail(fmt.Sprintf("平台证书有误:%v", err))
} }
client, err = core.NewClient( client, err = core.NewClient(
ctx, ctx,
option.WithMerchantCredential( option.WithMerchantCredential(
@ -57,7 +62,8 @@ func newClient(ctx context.Context, c *Server) (*core.Client, error) {
option.WithWechatPayCertificate([]*x509.Certificate{wechatPayCertificate}), option.WithWechatPayCertificate([]*x509.Certificate{wechatPayCertificate}),
) )
if err != nil { if err != nil {
return nil, fmt.Errorf("创建 Client 失败:%v", err) return nil, proto.ErrorConfigFail(fmt.Sprintf("创建 Client 失败:%v", err))
} }
return client, nil return client, nil
} }

View File

@ -2,6 +2,7 @@ package wechat
import ( import (
"context" "context"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/core/auth" "github.com/wechatpay-apiv3/wechatpay-go/core/auth"
"github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers" "github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
@ -25,21 +26,30 @@ func init() {
func GetClient(ctx context.Context, c *Server) (*core.Client, error) { func GetClient(ctx context.Context, c *Server) (*core.Client, error) {
instance.mutex.Lock() instance.mutex.Lock()
defer instance.mutex.Unlock() defer instance.mutex.Unlock()
if instance.clients[c.MchID] != nil { if instance.clients[c.MchID] != nil {
return instance.clients[c.MchID], nil return instance.clients[c.MchID], nil
} }
var err error var err error
instance.once.Do(func() { instance.once.Do(func() {
instance.clients[c.MchID], err = newClient(ctx, c) instance.clients[c.MchID], err = newClient(ctx, c)
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
return instance.clients[c.MchID], nil return instance.clients[c.MchID], nil
} }
func (s *Server) Verify(ctx context.Context, message, signature string) error { func (s *Server) Verify(ctx context.Context, message, signature string) error {
var verifier auth.Verifier var verifier auth.Verifier
verifier = verifiers.NewSHA256WithRSAVerifier(nil) verifier = verifiers.NewSHA256WithRSAVerifier(nil)
return verifier.Verify(ctx, s.MchCertificateSerialNumber, message, signature)
if err := verifier.Verify(ctx, s.MchCertificateSerialNumber, message, signature); err != nil {
return proto.ErrorSignFail(err.Error())
}
return nil
} }