This commit is contained in:
ziming 2026-04-15 15:21:28 +08:00
parent 8c42dc8ec5
commit 24c1c9c2a3
76 changed files with 1632 additions and 312 deletions

View File

@ -1,27 +0,0 @@
.PHONY: tidy
tidy:
find . -type d -depth 1 -print | xargs -L 1 bash -c 'cd $$0 && pwd && go get -u gitea.cdlsxd.cn/sdk/plugin && go mod tidy'
.PHONY: build
build:
cd ${name} && go build -o ../../pkg/${name}.so .
.PHONY: zltx
zltx:
make build name=zltx
.PHONY: union_pay_cpn
union_pay_cpn:
make build name=union_pay_cpn
.PHONY: alipay_cpn
alipay_cpn:
make build name=alipay_cpn
.PHONY: wechat_cpn
wechat_cpn:
make build name=wechat_cpn
.PHONY: all
all:
find . -type d -depth 1 -print | xargs -L 1 bash -c 'cd $$0 && pwd && go build -o ../../pkg/$$0.exe'

View File

@ -5,10 +5,10 @@ go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.19
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
plugins/utils v0.0.0-00010101000000-000000000000
)

View File

@ -1,7 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -52,8 +50,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
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.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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
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/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=

View File

@ -33,7 +33,7 @@ func (s *AlipayCpnService) Order(ctx context.Context, request *proto.OrderReques
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -74,7 +74,7 @@ func (s *AlipayCpnService) Query(ctx context.Context, request *proto.QueryReques
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -115,7 +115,7 @@ func (s *AlipayCpnService) Notify(_ context.Context, request *proto.NotifyReques
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()

View File

@ -12,7 +12,11 @@ import (
var server = &AlipayCpnService{}
func config() []byte {
// fjxw
return []byte(`{"npk": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5sfDbw6kkHXeOSfr7RbrbkV7xHlNE8c5eXNI3ri+UCQLka9aehlnLhI2M1DkzSWFXvHuo5vHlC6set5j25nv+4AKevY1TgAPTMZQjNA3EMXinvBTZVCZnG6Cc3BN5jvAnt31NyTE9JsR5shFL9O6WTFED/WGUaM95kJfVeA1CwWkXUVV2kd1qU5KPAIHKMWsWiu9mSOBVZGd7NWwqfrZq33tiHmqYQ5LkS2JIno3qXukKm/2HIL+Ri1lw7s1c/xE6XalKPiroojK6zLLtrLa3LEGN833NWASrdGi4moYhAPHPZnhwsMr9FfUEsGSvwqdJlAbCtnIdbx3a6mV+sBRxQIDAQAB", "prk": "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC2cF2AxAJP/cQJGPcvzJ5Tt9AQnSzpncTo0sOsge07E9WOi8zIP772lm+ar0cjX9jx8Pf1fJ0hJuzqcsSikC/ZeFWNVmmG4crnwb1NzS/3Ymb22SVKqAjUyjgUkaMQEBRSBAYSTbzwLi9ziggiSvgaIZvUnpQWStcYzhPG91aF2q968vKMd3670b0WwCWSMmWW7dezyqMVikigJCvhSOBfC9A66MciiwtATLpiHBAsRr6IZQ6o9JeH7TPwwLW45QMOXR5VG0xuNj5/8dQmhZGtkckhYEC0v2DrjKkORdfbm4XcvsBsnVhcIVcDu1YkDZHYvhH45r7fUqYfKbgUHH9dAgMBAAECggEBAJUtundxT4bDNYpO3Mk8IvbH5h2/uBrrRDkxJomn0Ckvpb+itvfDkE4oYuf0jVHyrP3hEZCtrfqOzslCwWFAT7Aewq4Iy89cUEND25yDvMYns5QDqYercVU2abcAA3s9+q+51JEg+e7XhTuP0ejgrpEHjFnGtcaoucvxrqBSXXCjJu7l/R/O4gSctTKytTrkZ2vcbaUjVSsDIHE0qtzYinpHlUz8yzxTyhbI2ZHiLiZt3bQVbfPjKiu9H1VLcg4Ty38aP6g1c+nc0aanKiJSjlFWrka2dKB8EySYzt1yqSXHtsFc5BI7lopMTXlQ3f7eZljFt+/QjoGdD3LkRLGsZM0CgYEA74fZQjMeqqGGKxRH1vHkVBQ293VcLZxMh/62VROhWR2JU+UFYmP4zjtu+jnCMAb03kXFoyEJtEShcPoJmW/X5jIR7ukQYYTmlognPOHt4j8n1LP3AxF6m1qhfCPKjX+cbFoYebJtmR4u/pGQQcz6VgsaVTmPLEvBlJaW+C2fBWsCgYEAwvuanPWxHqWhUzGRXQWBOZC4tnS0R43xmnNOPjX0py/X/PwfDvYiMbuV9qRHoHu1dXQ/IfURpOJLp/ibqhTd7TRk6TwVtpnCZ4XJaXZ4wVnIFuH6d78nbEsQODtOwC82OscXvC+foymouM+7HfjXFYh597y+6f3khPQGoTP2+FcCgYBiffWz5tlBSFGm/RvdInHEsNs5PaS9jHtboDzRFtVNk3uYZ5+jKYBxLLchZQaYQQQHMaFmxnr7CQ1pKycvVHHuUcBWALefoco/M5UOz8fFNDrol2eGd3V20/l61iy/qi1j0FgoElpGj8a7Hpe2ttZo8v/M83IPwMbElndVbUzqKQKBgQCSvNlR8JEYWFv9iRs1n1PuJ5zrKw8VnpxJuScUKHTzcU0iBfe1wcRgGyUz1dRV0WPxfceZXZ6msOtxAObdbBDMWBbtdBt/LV4hnIzEgrVEBbZQikZ94ezgUell+DQ+7Ajq2TRimpCQMWTZmPPgDYqImQn5SCGBZWKaMC/hF4NwxwKBgASRF+xP/NUxj3G3TjRHMskFTgtOvzCChZgRXRuvIEd4zEZ1Y29sPSuTHFnJPVPfMDeGmcwPPVDGpMIumRXKJAO6hC9BtnivDnqjtCh16fzoimBeBlaGgg4KWfXT+7BTAPFzlKg4diHoa4Adc4JC+r9Xh++VAMUc3zvH4LWB+Oen", "app_id": "2021004125622196"}`)
// lsxd
//return []byte(`{"npk": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjnsbMbY/KYHhUkVbalbtSMbLFcntTEfqlz+t3bskMUOIvPldsW8U+RQymhjw6AGOQooqMvDqbkWk3kZph9mf56fTbRHYTiyAgNp+yzE9p6DQn3I1k7wT1aaWIX0cn+nJ0n427tYskfDNoG9MojvKLJQjVkU7/CejNy7z9j2BWXU/nPqfavwC/EUQmdx+4aI2IwUX4zOAg5ZbvSbnbBaRVnP9lRVEjMIjfl0LuvBqqvHLEwbQTh2UxlHlK9OWaCQmeD3zPCki7GSugwOXkez61wRIrFluWkpGupcAQRQvjkoxesQQy08ikkEbu5NmiQvybfFny46RBrO3/RnqjKqd/QIDAQAB", "prk": "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDAtMuB1mGgbZOETHRlfYefThBO2HjiNcg0kprSgPGQR3gJC6uZ6x2njBrGfLpGsEHjGNnHIjepvbeulD49Tht71kEtKPfsw0LgSgbLDjpxwADctCgnniGHuGmVOeuhuL8hO6JxNt4s+0xPoigmgHFltTKth0Ddc5kqthKmxLx3PJ/JqrzlsELzVkzC+gR/0+epTBTzLUpYzlRt3WhHmxEm8Y9XUk6C1naNXaQNrbrXFzTwnW9MxVj/yJaCoCVcifoVic14lWw3w0cdZ1yM6kcAA9vYAlhIJYc0eg2pAQt/mg/mdseourpa0O01d+2287vKOnOivK0UGqEYsw7d+Q9PAgMBAAECggEBAJ8WostViNNAowAdfhorP8OsVppA68sUS2vbfCU8fjB2UApnsAsppxmi+JfUcJPa/wnUgjV7ciiXjwR5Lci+qsHZZ4U4xTSZHqS7eFA6NtWhhRSvRlcunM/G1qNzZavlMSTmbny4p0LLU3yKikr+zp8AsA3CEzK/NDumhE9ZK53i5WWGwOLQI4yaQoD8XkbFxkWf0yKZiqxj+5UXNnaawfY45ZgDRVtd02hLJQnEYLS4PAt/tUW2I3M+2CJzVcJysry6fd56ZE8JLPVomS3ckS4MsUJkefBTbcJ/idkC5CvnRFqzLjOIOGjDKZqppfn99osilEIhq+UrdmeVZwQEO8ECgYEA+cDxSUjgOkhcU6QlD23B3dmNDWTmJ25RPD55mrhfa6tjInvSiotBwZxwmYKDmBTq/tprf82OjSlR7dQ7oFPSbtde/8tyc/bL/1Jz9/oMB+R2ZxDN3wzCR+rpK3n9YlDv3sR8bYN9q70buTd85SWBk4sdCBb2ZxdFFbn+vAg0ANMCgYEAxYaam+F5IY1/012Y9rikd8IqfZueLGOWOqBUflfsh+ov7Q+xvnJvzk/BLqHU9GvTVCmFK7II1lEFT5tfv8rc6w0y0OOkytx6Ymj/qfcwd8LffKfpRucQSE5i1WyxOvXBZQUZKQSxP0pWrELu9JCE0PPINz+pcFATdH4HV4WoShUCgYARsaSmf347QtMfrdpeTHVWpUoD7+kKVBt3PCnbV0KTWzILyF/zJsiC0fV8Oq3eAWVgptLE3ChEQfAm/Ek5I5cd+S4myyARrSNotEu4/sMJcBsfVCZxrfK5q5/XT64u3/MOgjcafx1RJHWpWpADn/OdI1bsMsxEI3bmgiXU5nPgtwKBgHz/dl3I7L/H7KlUZNVU+Xdz3zHHxevvRYVqKq4dc+h60cNiGCgeART9MZISBVJ73as37zc8ng0KDqNW/tu/Q9hXbN32ATYDGkumiIwFip1vK8CV/bDJzmsDd9X5x5o5JR6JgGeNuaEEqR6v6MnJntMgQoZ7+fzCH92rV3gSc/IVAoGBAK0LkOgsU0Hd9ac0m4yCNPAqt02kSVaq0Q31pzO06/8hrA3+TkCfevKzt0dAwwEpjWHIfLKvJGriRgQSIh2eYloQueM6j0KwNsSkSAXWVaNlA5Twy3cMyYGUauioewksU3a/zhZf6QVsvqC0E5ETxhw/S22PfDnv+y4HzrudQIGo", "app_id": "2021003168695204"}`)
// fjxw
//c := &Config{
// AppId: "2021004125622196",
// Prk: "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC2cF2AxAJP/cQJGPcvzJ5Tt9AQnSzpncTo0sOsge07E9WOi8zIP772lm+ar0cjX9jx8Pf1fJ0hJuzqcsSikC/ZeFWNVmmG4crnwb1NzS/3Ymb22SVKqAjUyjgUkaMQEBRSBAYSTbzwLi9ziggiSvgaIZvUnpQWStcYzhPG91aF2q968vKMd3670b0WwCWSMmWW7dezyqMVikigJCvhSOBfC9A66MciiwtATLpiHBAsRr6IZQ6o9JeH7TPwwLW45QMOXR5VG0xuNj5/8dQmhZGtkckhYEC0v2DrjKkORdfbm4XcvsBsnVhcIVcDu1YkDZHYvhH45r7fUqYfKbgUHH9dAgMBAAECggEBAJUtundxT4bDNYpO3Mk8IvbH5h2/uBrrRDkxJomn0Ckvpb+itvfDkE4oYuf0jVHyrP3hEZCtrfqOzslCwWFAT7Aewq4Iy89cUEND25yDvMYns5QDqYercVU2abcAA3s9+q+51JEg+e7XhTuP0ejgrpEHjFnGtcaoucvxrqBSXXCjJu7l/R/O4gSctTKytTrkZ2vcbaUjVSsDIHE0qtzYinpHlUz8yzxTyhbI2ZHiLiZt3bQVbfPjKiu9H1VLcg4Ty38aP6g1c+nc0aanKiJSjlFWrka2dKB8EySYzt1yqSXHtsFc5BI7lopMTXlQ3f7eZljFt+/QjoGdD3LkRLGsZM0CgYEA74fZQjMeqqGGKxRH1vHkVBQ293VcLZxMh/62VROhWR2JU+UFYmP4zjtu+jnCMAb03kXFoyEJtEShcPoJmW/X5jIR7ukQYYTmlognPOHt4j8n1LP3AxF6m1qhfCPKjX+cbFoYebJtmR4u/pGQQcz6VgsaVTmPLEvBlJaW+C2fBWsCgYEAwvuanPWxHqWhUzGRXQWBOZC4tnS0R43xmnNOPjX0py/X/PwfDvYiMbuV9qRHoHu1dXQ/IfURpOJLp/ibqhTd7TRk6TwVtpnCZ4XJaXZ4wVnIFuH6d78nbEsQODtOwC82OscXvC+foymouM+7HfjXFYh597y+6f3khPQGoTP2+FcCgYBiffWz5tlBSFGm/RvdInHEsNs5PaS9jHtboDzRFtVNk3uYZ5+jKYBxLLchZQaYQQQHMaFmxnr7CQ1pKycvVHHuUcBWALefoco/M5UOz8fFNDrol2eGd3V20/l61iy/qi1j0FgoElpGj8a7Hpe2ttZo8v/M83IPwMbElndVbUzqKQKBgQCSvNlR8JEYWFv9iRs1n1PuJ5zrKw8VnpxJuScUKHTzcU0iBfe1wcRgGyUz1dRV0WPxfceZXZ6msOtxAObdbBDMWBbtdBt/LV4hnIzEgrVEBbZQikZ94ezgUell+DQ+7Ajq2TRimpCQMWTZmPPgDYqImQn5SCGBZWKaMC/hF4NwxwKBgASRF+xP/NUxj3G3TjRHMskFTgtOvzCChZgRXRuvIEd4zEZ1Y29sPSuTHFnJPVPfMDeGmcwPPVDGpMIumRXKJAO6hC9BtnivDnqjtCh16fzoimBeBlaGgg4KWfXT+7BTAPFzlKg4diHoa4Adc4JC+r9Xh++VAMUc3zvH4LWB+Oen",
@ -59,13 +63,19 @@ func TestQuery(t *testing.T) {
request := &proto.QueryRequest{
Config: config(),
Order: &proto.QueryRequest_Order{
OrderNo: "202507291411243510013587",
TradeNo: "",
Account: "18043057911",
//Extra: []byte(`{"phone_id":"","logon_id":"13691105465","activity_id":"ACT873CCV02108400"}`),
Extra: []byte(`{"phone_id":"","logon_id":"18043057911","activity_id":"ACT673CCV03194025"}`),
OrderNo: "",
TradeNo: "20251221223651ACT04343CCV00699079851",
Account: "043k0Dp2sNW5SuNidc3UjdrfKvnysMYE7AiA0m0lxEdPu8c",
Extra: []byte(`{"phone_id":"","logon_id":"","activity_id":"ACT907CCV03800305"}`),
},
}
// lsxd
//{"extra": "eyJsb2dvbl9pZCI6IjU4Mzk4OTAyMEBxcS5jb20ifQ==", "account": "583989020@qq.com", "order_no": "202512012022000330010220", "quantity": 1}
//{"product": "product_no:\"ACT532CCV02911198\"", "trade_no": "202512012022000330010220"}
// fjxw
//{"extra": "eyJsb2dvbl9pZCI6IjEzNzA2NTE0ODc4In0=", "account": "13706514878", "order_no": "202601050921400620016427", "quantity": 1}
//{"product": "product_no:\"ACT773CCV03855459\"", "trade_no": "202601050921400620016427"}
// Insufficient Permissions IP白名单问题
t.Run("TestQuery", func(t *testing.T) {
got, err := server.Query(context.Background(), request)
if err != nil {

View File

@ -5,10 +5,10 @@ go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.19
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
plugins/utils v0.0.0-00010101000000-000000000000
)

View File

@ -1,7 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -55,8 +53,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
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.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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=

View File

@ -31,7 +31,7 @@ func (s *AlipayRedPackService) Order(ctx context.Context, request *proto.OrderRe
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -65,14 +65,14 @@ func (s *AlipayRedPackService) Order(ctx context.Context, request *proto.OrderRe
return nil, proto.ErrorResponseFail(err.Error())
}
return orderResp(request, response), nil
return orderResp(request, response)
}
func (s *AlipayRedPackService) Query(ctx context.Context, request *proto.QueryRequest) (resp2 *proto.QueryResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -108,7 +108,7 @@ func (s *AlipayRedPackService) Notify(_ context.Context, request *proto.NotifyRe
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()

View File

@ -1,7 +1,6 @@
package po
import (
"fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"plugins/alipay_redpack/internal/vo"
)
@ -43,16 +42,6 @@ type OrderResp struct {
Sign string `json:"sign"`
}
func (o *OrderResp) GetMsg() string {
if o.Response.Code.IsSuccess() {
return o.Response.Msg
}
return fmt.Sprintf(
"code:[%s],msg:[%s],subCode:[%s],subMsg[%s]",
o.Response.Code, o.Response.Msg, o.Response.SubCode, o.Response.SubMsg,
)
}
func (o *OrderResp) GetOrderStatus() proto.Status {
if o.Response.Code.IsSuccess() {
return proto.Status_ING

View File

@ -110,17 +110,22 @@ func orderReq(order *proto.OrderRequest_Order, product *proto.OrderRequest_Produ
}, nil
}
func orderResp(request *proto.OrderRequest, resp *po.OrderResp) *proto.OrderResponse {
func orderResp(request *proto.OrderRequest, resp *po.OrderResp) (*proto.OrderResponse, error) {
if !resp.Response.Code.IsSuccess() {
return nil, proto.ErrorSupplierReturnError(fmt.Sprintf("%s(%s)", resp.Response.SubMsg, resp.Response.SubCode))
}
data, _ := json.Marshal(resp)
return &proto.OrderResponse{
Result: &proto.Result{
Status: resp.GetOrderStatus(),
OrderNo: request.Order.OrderNo,
TradeNo: resp.Response.OrderId,
Message: resp.GetMsg(),
Message: resp.Response.Msg,
Data: data,
},
}
}, nil
}
func queryReq(in *proto.QueryRequest_Order) *po.QueryReq {

View File

@ -0,0 +1,7 @@
package vo
type SubCode string
func (s SubCode) String() string {
return string(s)
}

View File

@ -0,0 +1,39 @@
module plugins/lsxd_wechat_cpn
go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.10.0
plugins/utils v1.0.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // 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/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/hashicorp/go-hclog v0.14.1 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-colorable v0.1.4 // indirect
github.com/mattn/go-isatty v0.0.10 // indirect
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sys v0.22.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/grpc v1.64.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View File

@ -0,0 +1,75 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/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/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
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/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/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/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU=
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI=
github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
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/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/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/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
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/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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
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/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/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
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/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -0,0 +1,128 @@
package internal
import (
"context"
"encoding/json"
"fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"net/http"
)
const (
Tag = "lsxd_wechat_cpn"
Version = 1
CookieKey = "lsxd_wechat_cpn"
CookieValue = "lsxd_wechat_cpn"
)
const (
orderMethod = "/wechat/coupon/issue" // 支持幂等
queryMethod = "/wechat/coupon/query"
configMethod = "/wechat/coupon/config"
)
// LSXDWeChatCpnService
// 钉钉文档 https://alidocs.dingtalk.com/i/nodes/Y1OQX0akWm6LKDO4iOo1xE0QVGlDd3mE?utm_scene=person_space
type LSXDWeChatCpnService struct{}
func (p *LSXDWeChatCpnService) Order(ctx context.Context, request *proto.OrderRequest) (resp2 *proto.OrderResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
config, err := transConfig(request.Config)
if err != nil {
return nil, err
}
bizContent, err := config.orderReq(request.Order, request.Product)
if err != nil {
return nil, err
}
reqBody, err := bizContent.Json()
if err != nil {
return nil, err
}
bodyBytes, _, err := config.Post(ctx, orderMethod, reqBody)
if err != nil {
return nil, err
}
return orderResp(request.GetOrder(), bodyBytes)
}
func (p *LSXDWeChatCpnService) Query(ctx context.Context, request *proto.QueryRequest) (resp2 *proto.QueryResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
config, err := transConfig(request.Config)
if err != nil {
return nil, err
}
bizContent, err := config.queryReq(request.Order)
if err != nil {
return nil, err
}
reqBody, err := bizContent.Json()
if err != nil {
return nil, err
}
bodyBytes, _, err := config.Post(ctx, queryMethod, reqBody)
if err != nil {
return nil, err
}
return queryResp(request, bodyBytes)
}
func (p *LSXDWeChatCpnService) Notify(ctx context.Context, request *proto.NotifyRequest) (resp2 *proto.NotifyResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
config, err := transConfig(request.Config)
if err != nil {
return nil, err
}
var h http.Header
if err = json.Unmarshal(request.Headers, &h); err != nil {
return nil, proto.ErrorParamFail("header参数解析失败:" + err.Error())
}
if err = config.verify(request.Body, h.Get("Verify")); err != nil {
return nil, err
}
return notifyResp(request.Body)
}
func (p *LSXDWeChatCpnService) Label(ctx context.Context, request *proto.QueryRequest) (resp2 string, respErr error) {
config, err := transConfig(request.Config)
if err != nil {
return "", err
}
bodyBytes, _, err := config.Post(ctx, configMethod, []byte(`{}`))
if err != nil {
return "", err
}
return string(bodyBytes), nil
}

View File

@ -0,0 +1,280 @@
package internal
import (
"context"
"encoding/json"
"fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/stretchr/testify/assert"
"net/http"
"plugins/utils/request"
"testing"
)
var server = &LSXDWeChatCpnService{}
func config() []byte {
// 测试环境
c := &Config{
BaseUrl: "https://gateway.dev.cdlsxd.cn",
NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/supplier/notify/54",
SignConfig: SignConfig{
Key: "7f8d9b4a2c1e0f568978675443210987",
IV: "a1b2c3d4e5f60708",
},
VerifyConfig: VerifyConfig{
Key: "87654321abcdef0987654321fedcba09",
IV: "0807060504030201",
},
Source: "test",
Label: "lsxdold",
}
// 预发布环境
//c := &Config{
// BaseUrl: "https://wechat-pre.86698.cn",
// NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/supplier/notify/53",
// SignConfig: SignConfig{
// Key: "3e9c1a7f6b2d4e5089f0c8b7a5d1e243",
// IV: "8f4a2c9d1e6b7053",
// },
// VerifyConfig: VerifyConfig{
// Key: "4f9c2e1b7a6d8053e8a1d0c9b2f37645",
// IV: "1f2e3d4c5b6a7988",
// },
// Source: "ymt",
// Label: "lsxdold",
//}
////生产
//c := &Config{
// BaseUrl: "https://wechat.86698.cn",
// NotifyUrl: "https://market.86698.cn/v1/supplier/notify/45",
// SignConfig: SignConfig{
// Key: "3e9c1a7f6b2d4e5089f0c8b7a5d1e243",
// IV: "8f4a2c9d1e6b7053",
// },
// VerifyConfig: VerifyConfig{
// Key: "4f9c2e1b7a6d8053e8a1d0c9b2f37645",
// IV: "1f2e3d4c5b6a7988",
// },
// Source: "ymt",
// Label: "lsxdold",
//}
marshal, _ := json.Marshal(c)
return marshal
}
func Test_Config(t *testing.T) {
t.Run("Test_Config", func(t *testing.T) {
c := config()
t.Logf("%s\n", string(c))
assert.NotEmpty(t, c)
})
}
func Test_Order(t *testing.T) {
req := &proto.OrderRequest{
Config: config(),
Order: &proto.OrderRequest_Order{
OrderNo: "202411141940575304120011",
Account: "oknbq5kTqBqmzvrRqRoLB8V26DCU",
Extra: []byte(`{"app_id":"wx83fd6da8093f55b7","stock_creator_mchid":"1605446142","stock_creator_name":"wx_蓝色兄弟","ymt_order_no":"123456789","ymt_activity_name":"acName"}`),
},
Product: &proto.OrderRequest_Product{
ProductNo: "21406497",
Extra: []byte(`{}`),
},
}
t.Run("Test_Order", func(t *testing.T) {
got, err := server.Order(context.Background(), req)
if err != nil {
t.Errorf("Order() error = %v", err)
return
}
t.Logf("%+v", got)
assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status))
})
}
func Test_Query(t *testing.T) {
req := &proto.QueryRequest{
Config: config(),
Order: &proto.QueryRequest_Order{
OrderNo: "202601131847108250010003",
TradeNo: "146156565422",
Account: "oknbq5mAjfgPiCJV028g-ZFDx1WU",
Extra: []byte(`{"app_id":"wx83fd6da8093f55b7"}`),
},
}
t.Run("Test_Query", func(t *testing.T) {
got, err := server.Query(context.Background(), req)
if err != nil {
t.Errorf("Query() error = %v", err)
return
}
t.Logf("%+v \n", got)
assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status))
})
}
func Test_Notify(t *testing.T) {
in := &proto.NotifyRequest{
Config: config(),
Queries: []byte(``),
Headers: []byte(`{"Accept-Encoding":["gzip"],"Connection":["close"],"Content-Length":["956"],"Content-Type":["application/json"],"User-Agent":["Go-http-client/1.1"],"Verify":["E8ofjMT6lR/yHYGT6ZS/66W0tTZmg/DeqYuUr7anrwwtKiKwMCHJD3uos1k3rT7DJBnhe9QpIfuBZ62szs56g93LND7W/SldguDIQP8TKAjOrO7jKsfvEm4teTGqi2T97ExHv4H5xcRNsXOUgis2jmUP6uvyx7MsEChpgMAaDTo8KeRAMrew9qjKZb+urfNlSlT9TrJGUQKrI8/kr8h86JXDHCtvhpC3LLLIlS+5wuGGSzOs8Tboy+EBJCsE01S6VjVKqJaGuhJZsRNfkuFvHvJYf285xf5vWuprBdtkONvJJlgTpsxky/vXr+SllLU9oFQUZ+SO6fho3cagDbHF6Jx1SZQZv4U2i96kvH0uL3Wp7gEWy6bpd7EpyEUmJJtH1u63HZOyCDJFLJ/0taFQSqb4nRUPBNdRhgDKtVbg0ds6Sn/1GB2+TEga3xLvruqbPnOP1pRpPeR8c2yv1XlMWPXN46yQ9o24kXnniuD9GKuHqHNn4NR5DhIxLtbxZ75zhiPXGbPPIPLUmvAno1azWX+W9afEHMdHI30oRKVlGGI71o10sFOHLDQ+gzLmurp+DrBByK9o70wGjlBBq2uPapWy1PHKG3k+f7SKgWUyySiMaLHWR6N1GnBtS1uW+QMvds6//8ZPCbAq5BrS4ibxULobmk9nfXEoiAeYVFL66Cv4KJVZLzQGtyaR2N4kjM4BvqLHjJJ2PzXvAfYtixCORviXrjqon6vjz3peLRPyjjiPSIn6mK9z7JFVXRtq25EDWjoSh3OAlUn1Jy0JhFsxfhO07+S8RJJ8+QY4d0igK42bMVek3KAWo6nZebkh1xqdQC7sozRjHNZgee/a9xXO+PNwrf1bxto80N5Ob1KnEB1bC6PRWvyXR8279qnWcI78swbH+Yjbs6j0iHl/KHAMfdrdaDJLKxL4ck4sbyTtCdjaFEHC5ZY3gHuwTY9HC7uvW1spdJECUMIWcM1IwGhpe2EMhQOq1nEoMafCWgS8W43dGMxNE046rMQxmZBU6AHO+7BP3i3w6smH8101mRxfBGdQuZMkOHvnRrIqssT+5Sp7LesGNLyP5AbywhzhKIySOLJSlFodVA7c2uM/+oBdJ/2apSiuijmAD6ZXT/kbxh3FXFywaDQ1Sh6uVY/NmYY5jmI9BSnzFpgccSDH2+1MBmiEit7Vr9JMn1bDMGxA8vbOdKThaiYSbzzGs6tPsWyzHGgo8CtN2oQHINTqW7+g2dcarkP5r170M28tGXX51mIlfG/BOLeDnjkxNMgzPTOL"],"X-Forwarded-For":["39.96.194.80"],"X-Real-Ip":["39.96.194.80"],"X-Remoteaddr":["172.21.0.1"]}`),
Body: []byte(`{"query":{"stock_creator_mchid":"1652465541","stock_id":"21594627","coupon_id":"148861250136","cut_to_message":{},"coupon_name":"微信立减金发放测试","status":"USED","create_time":"2026-01-15T18:23:21+08:00","coupon_type":"NORMAL","available_begin_time":"2026-01-14T00:00:00+08:00","available_end_time":"2026-04-14T23:59:59+08:00","normal_coupon_information":{"coupon_amount":100,"transaction_minimum":101}},"notify":{"stock_creator_mchid":"1652465541","stock_id":"21594627","coupon_id":"148861250136","coupon_name":"微信立减金发放测试","status":"USED","create_time":"2026-01-15T18:23:21+08:00","coupon_type":"NORMAL","available_begin_time":"2026-01-14T00:00:00+08:00","available_end_time":"2026-04-14T23:59:59+08:00","normal_coupon_information":{"coupon_amount":100,"transaction_minimum":101},"consume_information":{"consume_time":"2026-01-15T18:25:22+08:00","consume_mchid":"1532524971","transaction_id":"4200002984202601152635066771"}}}`),
}
t.Run("Test_Notify", func(t *testing.T) {
got, err := server.Notify(context.Background(), in)
if err != nil {
t.Errorf("Notify() error = %v", err)
return
}
t.Logf("TestNotify : %+v \n", got)
assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status))
})
}
func Test_Label(t *testing.T) {
req := &proto.QueryRequest{
Config: config(),
}
t.Run("Test_Label", func(t *testing.T) {
got, err := server.Label(context.Background(), req)
if err != nil {
t.Errorf("Label() error = %v", err)
return
}
fmt.Printf("%+v \n", got)
})
}
func Test_AES256CBCEncrypt(t *testing.T) {
plaintext := `{
"query": {
"stock_creator_mchid": "1715349578",
"stock_id": "21408595",
"coupon_id": "146156565422",
"cut_to_message": {
"single_price_max": 0,
"cut_to_price": 0
},
"coupon_name": "贵州银行1.08",
"status": "USED",
"description": "",
"create_time": "2025-12-27T16:29:00+08:00",
"coupon_type": "NORMAL",
"no_cash": false,
"available_begin_time": "2025-12-27T00:00:00+08:00",
"available_end_time": "2026-01-10T23:59:59+08:00",
"singleitem": false,
"normal_coupon_information": {
"coupon_amount": 108,
"transaction_minimum": 990
},
"out_request_no": "",
"available_balance": 0,
"business_type": "",
"discount_msg": null
},
"notify": {
"stock_creator_mchid": "1652465541",
"stock_id": "20886559",
"coupon_id": "146156565422",
"singleitem_discount_off": null,
"discount_to": null,
"coupon_name": "招商银行1元立减金",
"status": "USED",
"description": "",
"create_time": "2025-10-30T09:50:48+08:00",
"coupon_type": "NORMAL",
"no_cash": false,
"available_begin_time": "2025-11-01T00:00:00+08:00",
"available_end_time": "2025-11-30T23:59:59+08:00",
"singleitem": false,
"normal_coupon_information": {
"coupon_amount": 100,
"transaction_minimum": 1800
},
"consume_information": {
"consume_time": "2025-11-24T00:09:50+08:00",
"consume_mchid": "1515540081",
"transaction_id": "4200002932202511240241356500",
"consume_amount": 0,
"goods_detail": null
},
"business_type": ""
}
}`
sign, err := Sign([]byte(plaintext), []byte(`7f8d9b4a2c1e0f568978675443210987`), []byte(`a1b2c3d4e5f60708`))
if err != nil {
t.Errorf("sign() error = %v", err)
return
}
fmt.Printf("sign : %s \n", sign)
}
func Test_WxNotifyRequest(t *testing.T) {
uri := "https://gateway.dev.cdlsxd.cn/yxh5api/v1/supplier/notify/54"
body := []byte(`{"query":{"status": "SENED", "stock_id": "21594627", "coupon_id": "148733945749", "coupon_name": "微信立减金发放测试", "coupon_type": "NORMAL", "create_time": "2026-01-14T18:06:48+08:00", "cut_to_message": {}, "available_end_time": "2026-04-14T23:59:59+08:00", "stock_creator_mchid": "1652465541", "available_begin_time": "2026-01-14T00:00:00+08:00", "normal_coupon_information": {"coupon_amount": 100, "transaction_minimum": 101}},"notify":{"stock_creator_mchid":"1652465541","stock_id":"21594627","coupon_id":"148861250136","coupon_name":"微信立减金发放测试","status":"USED","create_time":"2026-01-15T18:23:21+08:00","coupon_type":"NORMAL","available_begin_time":"2026-01-14T00:00:00+08:00","available_end_time":"2026-04-14T23:59:59+08:00","normal_coupon_information":{"coupon_amount":100,"transaction_minimum":101},"consume_information":{"consume_time":"2026-01-15T18:25:22+08:00","consume_mchid":"1532524971","transaction_id":"4200002984202601152635066771"}}}`)
c, err := transConfig(config())
if err != nil {
t.Errorf("transConfig() error = %v", err)
return
}
v, err := Sign(body, []byte(c.VerifyConfig.Key), []byte(c.VerifyConfig.IV))
if err != nil {
t.Errorf("Sign() error = %v", err)
return
}
hds := fmt.Sprintf(`{"Content-Type":["application/json"],"Verify":["%s"]}`, v)
var headerMap http.Header
if err = json.Unmarshal([]byte(hds), &headerMap); err != nil {
t.Error(fmt.Sprintf("解析 headers 失败: %v", err))
return
}
ctx := context.Background()
respHeader, respBody, err := request.Post(ctx, uri, body, request.WithHeaders(headerMap))
if err != nil {
t.Errorf("请求失败: [%s]-%v", string(respBody), err)
return
}
t.Logf("响应体:%s", string(respBody))
t.Logf("响应头:%v", respHeader)
}
func Test_NotifyRequest(t *testing.T) {
uri := "https://gateway.dev.cdlsxd.cn/yxh5api/v1/supplier/notify/53"
body := []byte(`{"query":{"stock_creator_mchid":"1652465541","stock_id":"21594627","coupon_id":"148861250136","cut_to_message":{},"coupon_name":"微信立减金发放测试","status":"USED","create_time":"2026-01-15T18:23:21+08:00","coupon_type":"NORMAL","available_begin_time":"2026-01-14T00:00:00+08:00","available_end_time":"2026-04-14T23:59:59+08:00","normal_coupon_information":{"coupon_amount":100,"transaction_minimum":101}},"notify":{"stock_creator_mchid":"1652465541","stock_id":"21594627","coupon_id":"148861250136","coupon_name":"微信立减金发放测试","status":"USED","create_time":"2026-01-15T18:23:21+08:00","coupon_type":"NORMAL","available_begin_time":"2026-01-14T00:00:00+08:00","available_end_time":"2026-04-14T23:59:59+08:00","normal_coupon_information":{"coupon_amount":100,"transaction_minimum":101},"consume_information":{"consume_time":"2026-01-15T18:25:22+08:00","consume_mchid":"1532524971","transaction_id":"4200002984202601152635066771"}}}`)
hds := `{"Accept-Encoding":["gzip"],"Connection":["close"],"Content-Length":["956"],"Content-Type":["application/json"],"User-Agent":["Go-http-client/1.1"],"Verify":["E8ofjMT6lR/yHYGT6ZS/66W0tTZmg/DeqYuUr7anrwwtKiKwMCHJD3uos1k3rT7DJBnhe9QpIfuBZ62szs56g93LND7W/SldguDIQP8TKAjOrO7jKsfvEm4teTGqi2T97ExHv4H5xcRNsXOUgis2jmUP6uvyx7MsEChpgMAaDTo8KeRAMrew9qjKZb+urfNlSlT9TrJGUQKrI8/kr8h86JXDHCtvhpC3LLLIlS+5wuGGSzOs8Tboy+EBJCsE01S6VjVKqJaGuhJZsRNfkuFvHvJYf285xf5vWuprBdtkONvJJlgTpsxky/vXr+SllLU9oFQUZ+SO6fho3cagDbHF6Jx1SZQZv4U2i96kvH0uL3Wp7gEWy6bpd7EpyEUmJJtH1u63HZOyCDJFLJ/0taFQSqb4nRUPBNdRhgDKtVbg0ds6Sn/1GB2+TEga3xLvruqbPnOP1pRpPeR8c2yv1XlMWPXN46yQ9o24kXnniuD9GKuHqHNn4NR5DhIxLtbxZ75zhiPXGbPPIPLUmvAno1azWX+W9afEHMdHI30oRKVlGGI71o10sFOHLDQ+gzLmurp+DrBByK9o70wGjlBBq2uPapWy1PHKG3k+f7SKgWUyySiMaLHWR6N1GnBtS1uW+QMvds6//8ZPCbAq5BrS4ibxULobmk9nfXEoiAeYVFL66Cv4KJVZLzQGtyaR2N4kjM4BvqLHjJJ2PzXvAfYtixCORviXrjqon6vjz3peLRPyjjiPSIn6mK9z7JFVXRtq25EDWjoSh3OAlUn1Jy0JhFsxfhO07+S8RJJ8+QY4d0igK42bMVek3KAWo6nZebkh1xqdQC7sozRjHNZgee/a9xXO+PNwrf1bxto80N5Ob1KnEB1bC6PRWvyXR8279qnWcI78swbH+Yjbs6j0iHl/KHAMfdrdaDJLKxL4ck4sbyTtCdjaFEHC5ZY3gHuwTY9HC7uvW1spdJECUMIWcM1IwGhpe2EMhQOq1nEoMafCWgS8W43dGMxNE046rMQxmZBU6AHO+7BP3i3w6smH8101mRxfBGdQuZMkOHvnRrIqssT+5Sp7LesGNLyP5AbywhzhKIySOLJSlFodVA7c2uM/+oBdJ/2apSiuijmAD6ZXT/kbxh3FXFywaDQ1Sh6uVY/NmYY5jmI9BSnzFpgccSDH2+1MBmiEit7Vr9JMn1bDMGxA8vbOdKThaiYSbzzGs6tPsWyzHGgo8CtN2oQHINTqW7+g2dcarkP5r170M28tGXX51mIlfG/BOLeDnjkxNMgzPTOL"],"X-Forwarded-For":["39.96.194.80"],"X-Real-Ip":["39.96.194.80"],"X-Remoteaddr":["172.21.0.1"]}`
var headerMap http.Header
if err := json.Unmarshal([]byte(hds), &headerMap); err != nil {
t.Error(fmt.Sprintf("解析 headers 失败: %v", err))
return
}
ctx := context.Background()
respHeader, respBody, err := request.Post(ctx, uri, body, request.WithHeaders(headerMap))
if err != nil {
t.Errorf("请求失败: [%s]-%v", string(respBody), err)
return
}
t.Logf("响应体:%s", string(respBody))
t.Logf("响应头:%v", respHeader)
}

View File

@ -0,0 +1,42 @@
package po
import (
"encoding/json"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"plugins/lsxd_wechat_cpn/internal/vo"
)
type Ext struct {
OrderNo string `json:"order_no"`
OrderBelong string `json:"order_belong"`
StockCreatorName string `json:"stock_creator_name"`
}
type OrderReq struct {
Label string `json:"label" validate:"required"`
StockCreatorMchId string `json:"stock_creator_mch_id" validate:"required"`
Appid string `json:"appid" validate:"required"`
OutRequestNo string `json:"out_request_no" validate:"required"`
Openid string `json:"openid" validate:"required"`
StockId string `json:"stock_id" validate:"required"`
CallBack string `json:"call_back" validate:"required"`
Ext *Ext `json:"ext"`
}
func (c *OrderReq) Json() ([]byte, error) {
b, err := json.Marshal(c)
if err != nil {
return nil, proto.ErrorParamFail("order req json Marshal error: %v", err)
}
return b, nil
}
type OrderResp struct {
Code vo.Code `json:"code"`
Message string `json:"message"`
Data struct {
CouponId string `json:"coupon_id"`
} `json:"data,omitempty"`
}

View File

@ -0,0 +1,114 @@
package po
import (
"encoding/json"
"fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/go-playground/validator/v10"
"plugins/lsxd_wechat_cpn/internal/vo"
)
type QueryReq struct {
Label string `json:"label" validate:"required"`
CouponId string `json:"coupon_id" validate:"required"`
Appid string `json:"app_id" validate:"required"`
Openid string `json:"open_id" validate:"required"`
IsNotifyData bool `json:"is_notify_data,omitempty"`
IsForce bool `json:"is_force,omitempty"` // true则绕过缓存直接查询微信服务器
}
func (c *QueryReq) Json() ([]byte, error) {
b, err := json.Marshal(c)
if err != nil {
return nil, proto.ErrorParamFail("query req json Marshal error: %v", err)
}
return b, nil
}
type QueryResp struct {
Code vo.Code `json:"code"`
Message string `json:"message"`
Data Data `json:"data,omitempty"`
}
// Data 根结构体,包含 query 和 notify 两个子对象
type Data struct {
Query *Query `json:"query"`
Notify *Notify `json:"notify,omitempty"`
}
// Query query 子对象结构体
type Query struct {
StockCreatorMchid string `json:"stock_creator_mchid"` // 库存创建商户号
StockId string `json:"stock_id"` // 库存ID
CouponId string `json:"coupon_id" validate:"required"` // 优惠券ID
CutToMessage CutToMessage `json:"cut_to_message"` // 立减到价信息
CouponName string `json:"coupon_name"` // 优惠券名称
Status string `json:"status"` // 状态USED/UNUSED 等)
Description string `json:"description"` // 描述
CreateTime string `json:"create_time"` // 创建时间RFC3339 格式)
CouponType string `json:"coupon_type"` // 优惠券类型NORMAL 等)
NoCash bool `json:"no_cash"` // 是否无现金
AvailableBeginTime string `json:"available_begin_time"` // 可用开始时间
AvailableEndTime string `json:"available_end_time"` // 可用结束时间
Singleitem bool `json:"singleitem"` // 是否单品优惠
NormalCouponInformation NormalCouponInfo `json:"normal_coupon_information"` // 普通优惠券信息
OutRequestNo string `json:"out_request_no"` // 外部请求号
AvailableBalance int `json:"available_balance"` // 可用余额
BusinessType string `json:"business_type"` // 业务类型
DiscountMsg *interface{} `json:"discount_msg"` // 优惠说明null 用指针兼容)
}
// CutToMessage 立减到价信息结构体
type CutToMessage struct {
SinglePriceMax float64 `json:"single_price_max"` // 单品最高价格
CutToPrice float64 `json:"cut_to_price"` // 立减到价
}
// NormalCouponInfo 普通优惠券信息结构体
type NormalCouponInfo struct {
CouponAmount int `json:"coupon_amount"` // 优惠券金额(单位:分)
TransactionMinimum int `json:"transaction_minimum"` // 最低交易金额(单位:分)
}
// Notify notify 子对象结构体
type Notify struct {
StockCreatorMchid string `json:"stock_creator_mchid"` // 库存创建商户号
StockId string `json:"stock_id"` // 库存ID
CouponId string `json:"coupon_id"` // 优惠券ID
SingleitemDiscountOff *interface{} `json:"singleitem_discount_off"` // 单品优惠减免null 用指针兼容)
DiscountTo *interface{} `json:"discount_to"` // 优惠到价null 用指针兼容)
CouponName string `json:"coupon_name"` // 优惠券名称
Status string `json:"status"` // 状态
Description string `json:"description"` // 描述
CreateTime string `json:"create_time"` // 创建时间
CouponType string `json:"coupon_type"` // 优惠券类型
NoCash bool `json:"no_cash"` // 是否无现金
AvailableBeginTime string `json:"available_begin_time"` // 可用开始时间
AvailableEndTime string `json:"available_end_time"` // 可用结束时间
Singleitem bool `json:"singleitem"` // 是否单品优惠
NormalCouponInformation NormalCouponInfo `json:"normal_coupon_information"` // 普通优惠券信息
ConsumeInformation *ConsumeInfo `json:"consume_information"` // 核销信息(可能为空,用指针)
BusinessType string `json:"business_type"` // 业务类型
}
// ConsumeInfo 核销信息结构体
type ConsumeInfo struct {
ConsumeTime string `json:"consume_time"` // 核销时间
ConsumeMchid string `json:"consume_mchid"` // 核销商户号
TransactionId string `json:"transaction_id"` // 交易ID
ConsumeAmount int `json:"consume_amount"` // 核销金额
GoodsDetail *interface{} `json:"goods_detail"` // 商品详情null 用指针兼容)
}
func (req *Data) Validate() error {
err := validator.New().Struct(req)
if err != nil {
for _, err = range err.(validator.ValidationErrors) {
return proto.ErrorParamFail(fmt.Sprintf("参数有误: %v", err))
}
}
return nil
}

View File

@ -0,0 +1,254 @@
package internal
import (
"context"
"encoding/json"
"fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/go-playground/validator/v10"
"net/http"
"plugins/lsxd_wechat_cpn/internal/po"
"plugins/lsxd_wechat_cpn/internal/vo"
"plugins/utils/request"
)
type SignConfig struct {
Key string `validate:"required" json:"key" validate:"required"`
IV string `validate:"required" json:"iv" validate:"required"`
}
type VerifyConfig struct {
Key string `validate:"required" json:"key" validate:"required"`
IV string `validate:"required" json:"iv" validate:"required"`
}
type Config struct {
BaseUrl string `validate:"required" json:"base_url"`
NotifyUrl string `validate:"required" json:"notify_url"`
SignConfig SignConfig `json:"sign_config" validate:"required"`
VerifyConfig VerifyConfig `json:"verify_config" validate:"required"`
Source string `json:"source" validate:"required"` // 来源 ymt
Label string `json:"label" validate:"required"` // 标识 发券商户
}
func (c *Config) Post(ctx context.Context, method string, reqBody []byte) ([]byte, http.Header, error) {
v, err := c.Sign(reqBody)
if err != nil {
return nil, nil, err
}
h := http.Header{
"Content-Type": []string{"application/json"},
"Source": []string{c.Source},
"Verify": []string{v},
}
respHeader, respBody, err := request.Post(ctx, c.BaseUrl+method, reqBody, request.WithHeaders(h), request.WithTimeout(5))
if err != nil {
return nil, nil, proto.ErrorRequestFail(err.Error())
}
return respBody, respHeader, nil
}
func (c *Config) Sign(reqBody []byte) (string, error) {
sign, err := Sign(reqBody, []byte(c.SignConfig.Key), []byte(c.SignConfig.IV))
if err != nil {
return "", proto.ErrorSignFail(err.Error())
}
return sign, nil
}
func (c *Config) verify(reqBody []byte, reqSign string) error {
resSign, err := Sign(reqBody, []byte(c.VerifyConfig.Key), []byte(c.VerifyConfig.IV))
if err != nil {
return proto.ErrorSignFail(err.Error())
}
if resSign != reqSign {
return proto.ErrorSignFail("验签失败")
}
return nil
}
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) {
var c Config
if err := json.Unmarshal(config, &c); err != nil {
return nil, proto.ErrorConfigFail(err.Error())
}
if err := c.validate(); err != nil {
return nil, err
}
return &c, nil
}
func (c *Config) orderReq(order *proto.OrderRequest_Order, product *proto.OrderRequest_Product) (*po.OrderReq, error) {
if order.Extra == nil {
return nil, proto.ErrorParamFail("order拓展参数,不能为空")
}
var extra struct {
AppId string `json:"app_id"`
StockCreatorMchId string `json:"stock_creator_mchid"`
StockCreatorName string `json:"stock_creator_name"`
YmtOrderNo string `json:"ymt_order_no"`
YmtActivityName string `json:"ymt_activity_name"`
}
if err := json.Unmarshal(order.Extra, &extra); err != nil {
return nil, proto.ErrorParamFail("order拓展参数 json unmarshal error: %v", err)
}
ext := &po.Ext{
OrderNo: extra.YmtOrderNo,
OrderBelong: extra.YmtActivityName,
StockCreatorName: extra.StockCreatorName,
}
return &po.OrderReq{
Label: c.Label,
StockCreatorMchId: extra.StockCreatorMchId,
Appid: extra.AppId,
OutRequestNo: order.OrderNo,
Openid: order.Account,
StockId: product.ProductNo,
CallBack: c.NotifyUrl,
Ext: ext,
}, nil
}
func orderResp(order *proto.OrderRequest_Order, bodyBytes []byte) (*proto.OrderResponse, error) {
var resp *po.OrderResp
if err := json.Unmarshal(bodyBytes, &resp); err != nil {
return nil, proto.ErrorResponseFail("order resp json unmarshal error: %v", err)
}
if !resp.Code.IsSuccess() {
return nil, proto.ErrorRequestFail("请求成功返回错误:" + resp.Message)
}
return &proto.OrderResponse{
Result: &proto.Result{
Status: proto.Status_ING,
OrderNo: order.GetOrderNo(),
TradeNo: resp.Data.CouponId,
Message: "成功",
Data: bodyBytes,
Extra: nil,
},
}, nil
}
func (c *Config) queryReq(order *proto.QueryRequest_Order) (*po.QueryReq, error) {
if order.Extra == nil {
return nil, proto.ErrorParamFail("order拓展参数,不能为空")
}
var extra struct {
AppId string `json:"app_id"`
}
if err := json.Unmarshal(order.Extra, &extra); err != nil {
return nil, proto.ErrorRequestFail("order拓展参数 json unmarshal error: %v", err)
}
if extra.AppId == "" {
return nil, proto.ErrorParamFail("appid不能为空")
}
return &po.QueryReq{
Label: c.Label,
CouponId: order.TradeNo,
Appid: extra.AppId,
Openid: order.Account,
IsNotifyData: true,
IsForce: false,
}, nil
}
func queryResp(request *proto.QueryRequest, bodyBytes []byte) (*proto.QueryResponse, error) {
var resp *po.QueryResp
if err := json.Unmarshal(bodyBytes, &resp); err != nil {
return nil, proto.ErrorResponseFail("query resp json unmarshal error: %v", err)
}
if !resp.Code.IsSuccess() {
return nil, proto.ErrorRequestFail("请求成功返回错误:" + resp.Message)
}
status := vo.Status(resp.Data.Query.Status)
return &proto.QueryResponse{
Result: &proto.Result{
Status: status.GetOrderStatus(),
OrderNo: request.Order.GetOrderNo(),
TradeNo: request.Order.TradeNo,
Message: status.GetText(),
Data: bodyBytes,
Extra: nil,
},
}, nil
}
func notifyResp(bodyBytes []byte) (*proto.NotifyResponse, error) {
var resp po.Data
if err := json.Unmarshal(bodyBytes, &resp); err != nil {
return nil, proto.ErrorParamFail("notify data json unmarshal error: %v", err)
}
if resp.Query == nil {
return nil, proto.ErrorParamFail("notify data query is nil")
}
if err := resp.Validate(); err != nil {
return nil, proto.ErrorParamFail("notify data validate error: %v", err)
}
extra := []byte(``)
status := vo.Status(resp.Query.Status).GetOrderStatus()
if status == proto.Status_WRITE_OFF {
if resp.Notify != nil && resp.Notify.ConsumeInformation != nil && resp.Notify.ConsumeInformation.ConsumeTime == "" {
var e struct {
ConsumeTime string `json:"consume_time"`
}
e.ConsumeTime = resp.Notify.ConsumeInformation.ConsumeTime
extra, _ = json.Marshal(e)
}
}
return &proto.NotifyResponse{
Result: &proto.Result{
Status: status,
OrderNo: resp.Query.OutRequestNo,
TradeNo: resp.Query.CouponId,
Message: "",
Data: bodyBytes,
Extra: extra,
},
Return: "SUCCESS",
Headers: `{"Content-Type":["application/json"]}`,
}, nil
}

View File

@ -0,0 +1,52 @@
package internal
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
)
// PKCS7Padding 对数据进行PKCS7填充
func PKCS7Padding(data []byte, blockSize int) []byte {
padding := blockSize - len(data)%blockSize
t := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, t...)
}
// AES256CBCEncrypt 使用AES-256-CBC算法加密数据
func AES256CBCEncrypt(plaintext, key, iv []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// 对明文进行PKCS7填充
padded := PKCS7Padding(plaintext, aes.BlockSize)
// 创建CBC模式的加密器
mode := cipher.NewCBCEncrypter(block, iv)
// 执行加密
ciphertext := make([]byte, len(padded))
mode.CryptBlocks(ciphertext, padded)
return ciphertext, nil
}
// Sign .
func Sign(plaintext, key, iv []byte) (string, error) {
ciphertext, err := AES256CBCEncrypt(plaintext, key, iv)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(ciphertext), nil
}

View File

@ -0,0 +1,16 @@
package vo
type Code string
const (
CodeSuccess Code = "0"
CodeFail Code = "1"
)
func (c Code) Value() string {
return string(c)
}
func (c Code) IsSuccess() bool {
return c == CodeSuccess
}

View File

@ -0,0 +1,52 @@
package vo
import "gitea.cdlsxd.cn/sdk/plugin/proto"
type Status string
const (
StatusAvailable = "SENDED"
StatusUsed = "USED" // 代金券已被用户使用(实扣);
StatusExpired = "EXPIRED" // 代金券因活动过期而失效;
// StatusRevoked 当代金券被商户主动撤销(作废)时,会触发“已失效”状态,用户无法再使用。此情况下,代金券状态不可逆,
// 需重新发放才能再次使用。建议通过查询接口确认代金券状态,并确保在有效期内合理管理券的发放与使用。
StatusRevoked = "REVOKED" // 代金券被商户主动撤销。
StatusRecover = "RECOVER" // 代金券被系统回收,可能因未使用或规则触发;
)
var statusTextMap = map[Status]string{
StatusAvailable: "可用",
StatusUsed: "已实扣(代金券已被用户使用)",
StatusExpired: "已过期(代金券因活动过期而失效)",
StatusRevoked: "已失效(代金券被商户主动撤销)",
StatusRecover: "已回收(代金券被系统回收,可能因未使用或规则触发)",
}
var queryStatusMap = map[Status]proto.Status{
StatusAvailable: proto.Status_SUCCESS,
StatusUsed: proto.Status_WRITE_OFF,
StatusExpired: proto.Status_OVERDUE,
StatusRevoked: proto.Status_REVOKE,
StatusRecover: proto.Status_INVALID,
}
func (o Status) GetText() string {
msg, ok := statusTextMap[o]
if !ok {
return ""
}
return msg
}
func (o Status) GetOrderStatus() proto.Status {
if o == "" {
return proto.Status_INVALID
}
if resultStatus, ok := queryStatusMap[o]; ok {
return resultStatus
}
return proto.Status_FAIL
}

View File

@ -0,0 +1,15 @@
package main
import (
"gitea.cdlsxd.cn/sdk/plugin/shared"
"github.com/hashicorp/go-plugin"
"plugins/lsxd_wechat_cpn/internal"
)
func main() {
plugin.Serve(&plugin.ServeConfig{
HandshakeConfig: shared.HandshakeConfig(internal.Version, internal.CookieKey, internal.CookieValue),
Plugins: shared.PluginSet(shared.NewPlugin(&internal.LSXDWeChatCpnService{}, internal.Tag)),
GRPCServer: plugin.DefaultGRPCServer,
})
}

View File

@ -5,10 +5,10 @@ go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.19
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
plugins/utils v0.0.0-00010101000000-000000000000
)

View File

@ -1,7 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -55,8 +53,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
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.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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=

View File

@ -3,6 +3,7 @@ package po
import (
"fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"plugins/qixing_alipay_redpack/internal/vo"
)
type OrderReq struct {
@ -61,6 +62,11 @@ func (o *OrderResp) GetMsg() string {
return fmt.Sprintf("code:[%v],msg:[%s]", o.Code, o.Msg)
}
func (o *OrderResp) IsInsufficientBudget() bool {
code := vo.Code(fmt.Sprintf("%v", o.Code))
return code.IsInsufficientBudget()
}
func (o *OrderResp) GetOrderStatus() proto.Status {
if o.IsSuccess() {
return proto.Status_ING

View File

@ -39,8 +39,13 @@ func (o *QueryResp) IsSuccess() bool {
}
func (o *QueryResp) GetMsg() string {
code := vo.Code(fmt.Sprintf("%v", o.Code))
return fmt.Sprintf("code[%s],msg[%s],text[%s]", code, o.Msg, code.GetText())
t := code.GetText()
if t == "" {
t = o.Msg
}
return fmt.Sprintf("[%s]-[%s]", code, t)
}
func (o *QueryResp) GetOrderStatus() proto.Status {

View File

@ -57,7 +57,7 @@ func (s *RedPackService) Order(ctx context.Context, request *proto.OrderRequest)
return nil, proto.ErrorResponseFail(err.Error())
}
return orderResp(request, response, bodyBytes), nil
return orderResp(request, response, bodyBytes)
}
func (s *RedPackService) Query(ctx context.Context, request *proto.QueryRequest) (resp2 *proto.QueryResponse, respErr error) {

View File

@ -79,7 +79,13 @@ func (c *Config) orderReq(order *proto.OrderRequest_Order, product *proto.OrderR
}, nil
}
func orderResp(request *proto.OrderRequest, resp *po.OrderResp, bodyBytes []byte) *proto.OrderResponse {
func orderResp(request *proto.OrderRequest, resp *po.OrderResp, bodyBytes []byte) (*proto.OrderResponse, error) {
//if !resp.IsSuccess() {
// if resp.IsInsufficientBudget() {
// //return nil, proto.ErrorInsufficientBudget(resp.GetMsg())
// }
//}
return &proto.OrderResponse{
Result: &proto.Result{
Status: resp.GetOrderStatus(),
@ -88,7 +94,7 @@ func orderResp(request *proto.OrderRequest, resp *po.OrderResp, bodyBytes []byte
Message: resp.GetMsg(),
Data: bodyBytes,
},
}
}, nil
}
func (c *Config) queryReq(in *proto.QueryRequest_Order) *po.QueryReq {

View File

@ -21,3 +21,7 @@ func (o Code) GetText() string {
}
return msg
}
func (o Code) IsInsufficientBudget() bool {
return o == "100011"
}

View File

@ -5,10 +5,10 @@ go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.19
gitea.cdlsxd.cn/sdk/plugin v1.0.26
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
plugins/utils v0.0.0-00010101000000-000000000000
)

View File

@ -1,7 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.26 h1:n0HZNqftz7egsZp9QaNC0bhQTHXjr+71q7lNdUCQemc=
gitea.cdlsxd.cn/sdk/plugin v1.0.26/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -55,8 +53,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
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.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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=

View File

@ -41,7 +41,10 @@ func (o *OrderResp) GetMsg() string {
if o.IsSuccess() {
return o.Msg
}
return fmt.Sprintf("code:[%v],msg:[%s]", o.Code, o.Msg)
if o.Msg == "" {
return fmt.Sprintf("code:[%v],msg:[%s]", o.Code, "上游返回错误")
}
return o.Msg
}
func (o *OrderResp) GetOrderStatus() proto.Status {

View File

@ -28,7 +28,7 @@ func (s *QiXingWechatRedPackService) Order(ctx context.Context, request *proto.O
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -65,7 +65,7 @@ func (s *QiXingWechatRedPackService) Query(ctx context.Context, request *proto.Q
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -101,7 +101,7 @@ func (s *QiXingWechatRedPackService) Balance(ctx context.Context, request *proto
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -123,7 +123,7 @@ func (s *QiXingWechatRedPackService) Notify(_ context.Context, request *proto.No
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()

View File

@ -19,9 +19,10 @@ func config() []byte {
Mode: "wechat_redpack_mode",
NchName: "启星微信红包",
AppKey: "ZU2Y2HHQK00N5TP4",
BatchId: "20062389",
BatchId: "20062389", // 对应启星的微信商户号1730083226
BasUrl: "https://cdc.myviding.com/cdc-api/api/external/red-packet",
NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/supplier/notify/51",
//NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/supplier/notify/51", // 测试环境
NotifyUrl: "https://market.86698.cn/v1/supplier/notify/51", // 生产环境
Official: Official{
Name: "福建兴旺网络科技有限公司",
AppId: "wxe3bd59243545fa8a",
@ -33,7 +34,7 @@ func config() []byte {
Name: "兴旺专属fl官",
AppId: "wx075c784fe71d4d04",
AppSecret: "5612971815ad7bf731bfec6b993b4128",
EnvVersion: "trial", // envVersion 正式版为"release",体验版为"trial",开发版为"develop",仅在微信外打开时生效。
EnvVersion: "release", // envVersion 正式版为"release",体验版为"trial",开发版为"develop",仅在微信外打开时生效。
},
}
marshal, _ := json.Marshal(c)

View File

@ -29,7 +29,7 @@ type Config struct {
Mode vo.Mode `validate:"required" json:"mode"` // 商户名称
NchName string `validate:"required" json:"mch_name"` // 商户名称
AppKey string `validate:"required" json:"app_key"` // appKey密钥
BatchId string `validate:"required" json:"batch_id"` // 批次账号
BatchId string `validate:"required" json:"batch_id"` // 批次账号,密钥跟批次号一对一关系
BasUrl string `validate:"required" json:"base_url"` // 请求地址
NotifyUrl string `validate:"required" json:"notify_url"` // 回调地址
Official Official `validate:"required" json:"official"` // 公众号信息

View File

@ -5,11 +5,10 @@ go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.19
github.com/carlmjohnson/requests v0.24.2
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
plugins/utils v0.0.0-00010101000000-000000000000
)

View File

@ -1,13 +1,9 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@ -78,8 +74,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
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.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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

View File

@ -5,11 +5,10 @@ go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.19
github.com/carlmjohnson/requests v0.24.2
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
plugins/utils v0.0.0-00010101000000-000000000000
)

View File

@ -1,13 +1,9 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@ -78,8 +74,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
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.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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

View File

@ -5,9 +5,9 @@ go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.17
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
github.com/wechatpay-apiv3/wechatpay-go v0.2.18
plugins/utils v1.0.0
)

View File

@ -1,5 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
@ -59,8 +59,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/wechatpay-apiv3/wechatpay-go v0.2.18 h1:vj5tvSmnEIz3ZsnFNNUzg+3Z46xgNMJbrO4aD4wP15w=
github.com/wechatpay-apiv3/wechatpay-go v0.2.18/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=

View File

@ -10,29 +10,59 @@ import (
"plugins/wechat_cpn/internal/vo"
)
func transConfig(config []byte) (*wechat.Server, error) {
var c wechat.Server
err := json.Unmarshal(config, &c)
if err != nil {
return nil, proto.ErrorConfigFail(err.Error())
}
if err = c.Validate(); err != nil {
return nil, err
}
return &c, nil
}
func orderReq(order *proto.OrderRequest_Order, product *proto.OrderRequest_Product) (cashcoupons.SendCouponRequest, error) {
type Extra struct {
Appid string `json:"app_id"`
StockCreatorMchId string `json:"stock_creator_mchid"`
}
func transConfig(config []byte) (*wechat.Server, error) {
var c wechat.Server
if err := json.Unmarshal(config, &c); err != nil {
return nil, proto.ErrorConfigFail(err.Error())
}
if err := c.Validate(); err != nil {
return nil, err
}
return &c, nil
}
func orderReq(order *proto.OrderRequest_Order, product *proto.OrderRequest_Product) (cashcoupons.SendCouponRequest, error) {
if order.Extra == nil {
return cashcoupons.SendCouponRequest{}, fmt.Errorf("order拓展参数不能为空")
}
var extra Extra
if order.Extra != nil {
if err := json.Unmarshal(order.Extra, &extra); err != nil {
return cashcoupons.SendCouponRequest{}, fmt.Errorf("order拓展参数 json unmarshal error: %v", err)
}
}
if extra.Appid == "" {
return cashcoupons.SendCouponRequest{}, fmt.Errorf("order拓展参数 app_id 不能为空")
}
if extra.StockCreatorMchId == "" {
return cashcoupons.SendCouponRequest{}, fmt.Errorf("order拓展参数 stock_creator_mchid 不能为空")
}
if product.ProductNo == "" {
return cashcoupons.SendCouponRequest{}, fmt.Errorf("product产品编号不能为空")
}
if order.Account == "" {
return cashcoupons.SendCouponRequest{}, fmt.Errorf("order用户账号不能为空")
}
if order.OrderNo == "" {
return cashcoupons.SendCouponRequest{}, fmt.Errorf("order订单编号不能为空")
}
return cashcoupons.SendCouponRequest{
Openid: core.String(order.Account),
StockId: core.String(product.ProductNo),

View File

@ -8,18 +8,29 @@ const (
QueryStatusAvailable = "SENDED"
QueryStatusUsed = "USED"
QueryStatusExpired = "EXPIRED"
// StatusRevoked 当代金券被商户主动撤销(作废)时,会触发“已失效”状态,用户无法再使用。此情况下,代金券状态不可逆,
// 需重新发放才能再次使用。建议通过查询接口确认代金券状态,并确保在有效期内合理管理券的发放与使用。
StatusRevoked = "REVOKED" // 代金券被商户主动撤销。
StatusRecover = "RECOVER" // 代金券被系统回收,可能因未使用或规则触发
)
var queryStatusTextMap = map[QueryStatus]string{
QueryStatusAvailable: "可用",
QueryStatusUsed: "已实扣",
QueryStatusExpired: "已过期",
StatusRevoked: "已失效(代金券被商户主动撤销)",
StatusRecover: "已回收(代金券被系统回收,可能因未使用或规则触发)",
}
var queryStatusMap = map[QueryStatus]proto.Status{
QueryStatusAvailable: proto.Status_SUCCESS,
QueryStatusUsed: proto.Status_WRITE_OFF,
QueryStatusExpired: proto.Status_OVERDUE,
StatusRevoked: proto.Status_REVOKE,
StatusRecover: proto.Status_INVALID,
}
func (o QueryStatus) GetText() string {

View File

@ -23,7 +23,7 @@ func (p *WeChatCpnService) Order(ctx context.Context, request *proto.OrderReques
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("插件panic: %v", err))
}
}()
@ -47,8 +47,19 @@ func (p *WeChatCpnService) Order(ctx context.Context, request *proto.OrderReques
return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误:%s", p.err(ctx, err)))
}
if result == nil {
return nil, proto.ErrorRequestFail("微信返回错误:result为空")
}
if result.Response == nil {
return nil, proto.ErrorRequestFail("微信返回错误:result.Response为空")
}
if result.Response.StatusCode != vo.CodeSuccess.Value() {
return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status))
return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误:[%d-%s]", result.Response.StatusCode, result.Response.Status))
}
if resp == nil {
return nil, proto.ErrorRequestFail("微信返回错误:resp为空")
}
return orderResp(request.GetOrder(), *resp.CouponId), nil
@ -58,7 +69,7 @@ func (p *WeChatCpnService) Query(ctx context.Context, request *proto.QueryReques
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("插件panic: %v", err))
}
}()
@ -93,7 +104,7 @@ func (p *WeChatCpnService) Notify(ctx context.Context, request *proto.NotifyRequ
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("插件panic: %v", err))
}
}()

View File

@ -15,7 +15,7 @@ var server = &WeChatCpnService{}
func config() []byte {
c := &wechat.Server{
MchID: "1605446142", // 证书所属商户
MchCertificateSerialNumber: "4D081089DEB385316CBDCB55C070287E4920AC76",
MchCertificateSerialNumber: "4D081089DEB385316CBDCB55C070287E4920AC766",
}
marshal, _ := json.Marshal(c)
return marshal
@ -53,6 +53,24 @@ func TestOrder(t *testing.T) {
})
}
func Test_Order(t *testing.T) {
var request *proto.OrderRequest
err := json.Unmarshal([]byte(`{"tag": "wechat_cpn", "order": {"extra": "", "account": "oO3vO5K2nE131-9uMoeYymLhlbYk", "order_no": "YMT202602041507084910010016", "quantity": 1}, "product": {"product_no": "21605443"}, "config": "{\"mch_id\": \"1605446142\", \"mch_certificate_serial_number\": \"46B64A9AF817BCE0425AB2ED003E7FC3C3DC48D9\"}"}`), &request)
if err != nil {
t.Errorf("json.Unmarshal() error = %v", err)
return
}
t.Run("Test_Order", func(t *testing.T) {
got, err := server.Order(context.Background(), request)
if err != nil {
t.Errorf("Order() error = %v", err)
return
}
fmt.Printf("%+v", got)
assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status))
})
}
func TestQuery(t *testing.T) {
request := &proto.QueryRequest{
Config: config(),

View File

@ -5,9 +5,9 @@ go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.17
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
github.com/wechatpay-apiv3/wechatpay-go v0.2.18
plugins/utils v1.0.0
)

View File

@ -1,5 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
@ -59,8 +59,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/wechatpay-apiv3/wechatpay-go v0.2.18 h1:vj5tvSmnEIz3ZsnFNNUzg+3Z46xgNMJbrO4aD4wP15w=
github.com/wechatpay-apiv3/wechatpay-go v0.2.18/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=

View File

@ -23,7 +23,7 @@ func (p *WeChatRedPackService) Order(ctx context.Context, request *proto.OrderRe
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -44,7 +44,7 @@ func (p *WeChatRedPackService) Order(ctx context.Context, request *proto.OrderRe
resp, result, err := svc.InitiateBatchTransfer(ctx, req)
if err != nil {
return nil, proto.ErrorRequestFail("微信返回错误:" + p.err(ctx, err).Error())
return nil, proto.ErrorRequestFail("微信返回错误:" + p.err(err).Error())
}
if result.Response.StatusCode != vo.CodeSuccess.Value() {
return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status))
@ -56,7 +56,7 @@ func (p *WeChatRedPackService) Query(ctx context.Context, request *proto.QueryRe
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -77,7 +77,7 @@ func (p *WeChatRedPackService) Query(ctx context.Context, request *proto.QueryRe
resp, result, err := svc.GetTransferDetailByOutNo(ctx, *req)
if err != nil {
return nil, proto.ErrorRequestFail("微信返回错误:" + p.err(ctx, err).Error())
return nil, proto.ErrorRequestFail("微信返回错误:" + p.err(err).Error())
}
if result.Response.StatusCode != vo.CodeSuccess.Value() {
return nil, proto.ErrorRequestFail(fmt.Sprintf("微信返回错误StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status))
@ -89,15 +89,18 @@ func (p *WeChatRedPackService) Notify(_ context.Context, _ *proto.NotifyRequest)
return notifyResp(), nil
}
func (p *WeChatRedPackService) err(_ context.Context, err error) error {
func (p *WeChatRedPackService) err(err error) error {
errStr := err.Error()
startIndex := strings.Index(errStr, "Message: ")
if startIndex == -1 {
return err
}
endIndex := strings.Index(errStr[startIndex:], "\n")
if endIndex == -1 {
return err
}
return fmt.Errorf(errStr[startIndex+len("Message: ") : startIndex+endIndex])
}

View File

@ -5,7 +5,7 @@ go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.17
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/wechatpay-apiv3/wechatpay-go v0.2.18
@ -26,7 +26,6 @@ require (
github.com/mattn/go-isatty v0.0.10 // indirect
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/stretchr/testify v1.9.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sys v0.22.0 // indirect

View File

@ -1,5 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
@ -53,8 +53,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/wechatpay-apiv3/wechatpay-go v0.2.18 h1:vj5tvSmnEIz3ZsnFNNUzg+3Z46xgNMJbrO4aD4wP15w=
github.com/wechatpay-apiv3/wechatpay-go v0.2.18/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=

View File

@ -24,7 +24,7 @@ func (p *WeChatRedPackService) Order(ctx context.Context, request *proto.OrderRe
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -55,7 +55,7 @@ func (p *WeChatRedPackService) Query(ctx context.Context, request *proto.QueryRe
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -86,7 +86,7 @@ func (p *WeChatRedPackService) Notify(ctx context.Context, request *proto.Notify
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -121,7 +121,7 @@ func (p *WeChatRedPackService) err(err error) error {
return err3
}
return fmt.Errorf("请求微信API错误: %s", apiErr.Message)
return proto.ErrorSupplierReturnError("请求微信API错误: %s", apiErr.Message)
}
return proto.ErrorRequestFail("请求微信返回错误:%v", err)

View File

@ -3,17 +3,18 @@ module plugins/zltx
go 1.22.2
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.15
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/carlmjohnson/requests v0.24.2
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // 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/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect

View File

@ -1,9 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA=
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/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=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso=
@ -14,6 +10,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
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/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/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -34,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/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
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/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@ -47,9 +49,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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.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.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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
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/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
@ -66,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/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
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 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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -3,17 +3,18 @@ module plugins/zltx_card
go 1.22.2
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.15
gitea.cdlsxd.cn/sdk/plugin v1.0.27
github.com/carlmjohnson/requests v0.24.2
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // 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/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect

View File

@ -1,9 +1,5 @@
gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA=
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/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=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso=
@ -14,6 +10,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
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/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/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -34,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/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
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/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@ -47,9 +49,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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.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.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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
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/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
@ -66,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/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
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 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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -3,7 +3,7 @@ module plugins/zltx_card_v1
go 1.22.2
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.25
gitea.cdlsxd.cn/sdk/plugin v1.0.29
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.10.0

View File

@ -1,5 +1,9 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.25 h1:z7AnsIUiakqbcTg9/RAxicCLT4Y5NkayA1jLT+Ptw58=
gitea.cdlsxd.cn/sdk/plugin v1.0.25/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
gitea.cdlsxd.cn/sdk/plugin v1.0.28 h1:D73owLaPfI/LL4MEnzPKjZKURZyBpOVzyfvW9Fd3v6k=
gitea.cdlsxd.cn/sdk/plugin v1.0.28/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
gitea.cdlsxd.cn/sdk/plugin v1.0.29 h1:d8uY/MQQjoq6sHQA37WMwAoD+vr8emNORIwYbVMm/wQ=
gitea.cdlsxd.cn/sdk/plugin v1.0.29/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

View File

@ -69,22 +69,46 @@ func (c *Config) orderReq(in *proto.OrderRequest) *card.Order {
OutTradeNo: in.Order.OrderNo,
ProductId: in.Product.ProductNo,
Mobile: in.Order.Account,
NotifyUrl: c.NotifyUrl,
NotifyUrl: c.NotifyUrl + "_" + fmt.Sprintf("%d", c.MerchantId),
Version: "1.0",
}
}
func orderResp(request *proto.OrderRequest, resp *card.OrderResp) *proto.OrderResponse {
data, _ := json.Marshal(resp)
return &proto.OrderResponse{
var speErrCodeMap = map[string]proto.Status{
//"1012": proto.Status_INVALID,
"1999": proto.Status_INVALID,
}
func orderResp(request *proto.OrderRequest, req *card.Order, resp *card.OrderResp) *proto.OrderResponse {
thirdRequest, _ := req.Json()
thirdResponse, _ := json.Marshal(resp)
response := &proto.OrderResponse{
Result: &proto.Result{
Status: proto.Status_ING,
OrderNo: request.Order.OrderNo,
TradeNo: resp.TradeNo,
Message: resp.Message,
Data: data,
Data: nil,
Extra: nil,
},
Idempotent: false,
ThirdRequest: string(thirdRequest),
ThirdResponse: string(thirdResponse),
}
if ec, ok := speErrCodeMap[string(resp.GetCode())]; ok {
response.Result.Status = ec
} else {
if !resp.GetCode().IsSuccess() {
response.Result.Status = proto.Status_FAIL
} else {
response.Result.Status = proto.Status_ING
}
}
return response
}
func (c *Config) queryReq(in *proto.QueryRequest) *card.Query {
@ -95,8 +119,11 @@ func (c *Config) queryReq(in *proto.QueryRequest) *card.Query {
}
}
func queryResp(request *proto.QueryRequest, resp *card.QueryResp, cardCode *card.CardCode) (*proto.QueryResponse, error) {
data, _ := json.Marshal(resp)
func queryResp(request *proto.QueryRequest, req *card.Query, resp *card.QueryResp, cardCode *card.CardCode) (*proto.QueryResponse, error) {
thirdRequest, _ := req.Json()
thirdResponse, _ := json.Marshal(resp)
extra, _ := cardCode.Json()
pb := &proto.QueryResponse{
Result: &proto.Result{
@ -104,14 +131,17 @@ func queryResp(request *proto.QueryRequest, resp *card.QueryResp, cardCode *card
OrderNo: request.Order.OrderNo,
TradeNo: request.Order.TradeNo,
Message: resp.Message,
Data: data,
Data: thirdResponse,
Extra: extra,
},
ThirdRequest: string(thirdRequest),
ThirdResponse: string(thirdResponse),
}
return pb, nil
}
func notifyResp(resp *card.Notify, cardCode *card.CardCode) (*proto.NotifyResponse, error) {
data, _ := json.Marshal(resp)
extra, _ := cardCode.Json()
pb := &proto.NotifyResponse{

View File

@ -31,7 +31,7 @@ func (p *ZLTXCardV1Service) Order(ctx context.Context, request *proto.OrderReque
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -45,25 +45,21 @@ func (p *ZLTXCardV1Service) Order(ctx context.Context, request *proto.OrderReque
return nil, err
}
resp, err := dctW.Order(ctx, c.orderReq(request))
req := c.orderReq(request)
resp, err := dctW.Order(ctx, req)
if err != nil {
if proto.IsResponseFail(err) {
return &proto.OrderResponse{Result: Result(err.Error())}, nil
}
return nil, err
}
if !resp.GetCode().IsSuccess() {
return nil, proto.ErrorRequestFail(resp.Message)
}
return orderResp(request, resp), nil
return orderResp(request, req, resp), nil
}
func (p *ZLTXCardV1Service) Query(ctx context.Context, request *proto.QueryRequest) (resp2 *proto.QueryResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -77,15 +73,18 @@ func (p *ZLTXCardV1Service) Query(ctx context.Context, request *proto.QueryReque
return nil, err
}
resp, cardCode, err := dctW.Query(ctx, c.queryReq(request))
req := c.queryReq(request)
resp, cardCode, err := dctW.Query(ctx, req)
if err != nil {
return nil, err
}
if !resp.GetCode().IsSuccess() {
return nil, proto.ErrorRequestFail(resp.Message)
}
return queryResp(request, resp, cardCode)
return queryResp(request, req, resp, cardCode)
}
func (p *ZLTXCardV1Service) Notify(ctx context.Context, request *proto.NotifyRequest) (resp2 *proto.NotifyResponse, respErr error) {
@ -99,7 +98,7 @@ func (p *ZLTXCardV1Service) Notify(ctx context.Context, request *proto.NotifyReq
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()

View File

@ -3,7 +3,7 @@ module plugins/zltx_v1
go 1.22.2
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.20
gitea.cdlsxd.cn/sdk/plugin v1.0.29
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.10.0

View File

@ -1,5 +1,9 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.20 h1:oAcqfHiOHoa+f9w6BPbvY9EZ0pwQ1mo3dD+YJD8OpYo=
gitea.cdlsxd.cn/sdk/plugin v1.0.20/go.mod h1:W2zpoqi70a9X7n3WCLcZ0sjxXTPgYhiJW36FO+qKlb0=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
gitea.cdlsxd.cn/sdk/plugin v1.0.28 h1:D73owLaPfI/LL4MEnzPKjZKURZyBpOVzyfvW9Fd3v6k=
gitea.cdlsxd.cn/sdk/plugin v1.0.28/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
gitea.cdlsxd.cn/sdk/plugin v1.0.29 h1:d8uY/MQQjoq6sHQA37WMwAoD+vr8emNORIwYbVMm/wQ=
gitea.cdlsxd.cn/sdk/plugin v1.0.29/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

View File

@ -54,13 +54,6 @@ 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) {
// 账号类型(1:手机号 2:QQ号 其他0)
accountType := int8(0)
@ -84,7 +77,7 @@ func (c *Config) orderReq(in *proto.OrderRequest) (*direct.Order, error) {
ProductId: in.Product.ProductNo,
AccountType: accountType,
RechargeAccount: in.Order.Account,
NotifyUrl: c.NotifyUrl,
NotifyUrl: c.NotifyUrl + "_" + fmt.Sprintf("%d", c.MerchantId),
Version: "1.0",
}
if in.Order.Extra != nil {
@ -94,17 +87,41 @@ func (c *Config) orderReq(in *proto.OrderRequest) (*direct.Order, error) {
return d, nil
}
func orderResp(request *proto.OrderRequest, resp *direct.OrderResp) *proto.OrderResponse {
data, _ := json.Marshal(resp)
return &proto.OrderResponse{
var speErrCodeMap = map[string]proto.Status{
//"1012": proto.Status_INVALID,
"1999": proto.Status_INVALID,
}
func orderResp(request *proto.OrderRequest, req *direct.Order, resp *direct.OrderResp) *proto.OrderResponse {
thirdResponse, _ := json.Marshal(resp)
thirdRequest, _ := req.Json()
response := &proto.OrderResponse{
Result: &proto.Result{
Status: proto.Status_ING,
OrderNo: request.Order.OrderNo,
TradeNo: resp.TradeNo,
Message: resp.Message,
Data: data,
Data: nil,
Extra: nil,
},
Idempotent: false,
ThirdRequest: string(thirdRequest),
ThirdResponse: string(thirdResponse),
}
if ec, ok := speErrCodeMap[string(resp.GetCode())]; ok {
response.Result.Status = ec
} else {
if !resp.GetCode().IsSuccess() {
response.Result.Status = proto.Status_FAIL
} else {
response.Result.Status = proto.Status_ING
}
}
return response
}
func (c *Config) queryReq(in *proto.QueryRequest) *direct.Query {
@ -115,29 +132,28 @@ func (c *Config) queryReq(in *proto.QueryRequest) *direct.Query {
}
}
func queryResp(request *proto.QueryRequest, resp *direct.QueryResp) (*proto.QueryResponse, error) {
data, err := json.Marshal(resp)
if err != nil {
return nil, err
}
func queryResp(request *proto.QueryRequest, req *direct.Query, resp *direct.QueryResp) (*proto.QueryResponse, error) {
return &proto.QueryResponse{
thirdRequest, _ := req.Json()
thirdResponse, _ := json.Marshal(resp)
response := &proto.QueryResponse{
Result: &proto.Result{
Status: resp.Status.GetOrderStatus(),
OrderNo: request.Order.OrderNo,
TradeNo: request.Order.TradeNo,
Message: resp.Message,
Data: data,
Data: nil,
Extra: nil,
},
}, nil
ThirdRequest: string(thirdRequest),
ThirdResponse: string(thirdResponse),
}
return response, nil
}
func notifyResp(resp *direct.Notify) (*proto.NotifyResponse, error) {
data, err := json.Marshal(resp)
if err != nil {
return nil, err
}
pb := &proto.NotifyResponse{
Result: &proto.Result{
@ -145,7 +161,7 @@ func notifyResp(resp *direct.Notify) (*proto.NotifyResponse, error) {
OrderNo: resp.OutTradeNo,
TradeNo: resp.TradeNo,
Message: resp.Status.GetOrderStatusText(),
Data: data,
Data: nil,
Extra: nil,
},
Return: "success",

View File

@ -21,11 +21,13 @@ const (
type ZLTXV1Service struct{}
// Order .
// https://tvd8jq9lqkp.feishu.cn/wiki/PQZjwxTO4ihlfwk427Uc4Vhnnce?fromScene=spaceOverview
func (p *ZLTXV1Service) Order(ctx context.Context, request *proto.OrderRequest) (resp2 *proto.OrderResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -45,25 +47,20 @@ func (p *ZLTXV1Service) Order(ctx context.Context, request *proto.OrderRequest)
}
a := &direct.Direct{DctWServer: server}
resp, err := a.Order(ctx, req)
if err != nil {
if proto.IsResponseFail(err) {
return &proto.OrderResponse{Result: Result(err.Error())}, nil
}
return nil, err
}
if !resp.GetCode().IsSuccess() {
return nil, proto.ErrorRequestFail(resp.Message)
}
return orderResp(request, resp), nil
return orderResp(request, req, resp), nil
}
func (p *ZLTXV1Service) Query(ctx context.Context, request *proto.QueryRequest) (resp2 *proto.QueryResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -72,28 +69,32 @@ func (p *ZLTXV1Service) Query(ctx context.Context, request *proto.QueryRequest)
return nil, err
}
req := c.queryReq(request)
server, err := c.server()
if err != nil {
return nil, err
}
a := &direct.Direct{DctWServer: server}
resp, err := a.Query(ctx, c.queryReq(request))
resp, err := a.Query(ctx, req)
if err != nil {
return nil, err
}
if !resp.GetCode().IsSuccess() {
return nil, proto.ErrorRequestFail(resp.Message)
}
return queryResp(request, resp)
return queryResp(request, req, resp)
}
func (p *ZLTXV1Service) Notify(ctx context.Context, request *proto.NotifyRequest) (resp2 *proto.NotifyResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()

View File

@ -5,11 +5,11 @@ go 1.22.2
replace plugins/utils => ../../utils
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.18
gitea.cdlsxd.cn/sdk/plugin v1.0.28
gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v1.0.3
github.com/go-playground/validator/v10 v10.22.0
github.com/hashicorp/go-plugin v1.6.1
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
plugins/utils v0.0.0-00010101000000-000000000000
)

View File

@ -1,5 +1,7 @@
gitea.cdlsxd.cn/sdk/plugin v1.0.18 h1:YgVJmCSSEu8JAniXlT1rI+h0w3EEGDRWLFqjk/5xBQY=
gitea.cdlsxd.cn/sdk/plugin v1.0.18/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.27 h1:ocp+3n8qLlPm+yI0VpMXFWfC8gsdDrKxEowuD58T6CE=
gitea.cdlsxd.cn/sdk/plugin v1.0.27/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
gitea.cdlsxd.cn/sdk/plugin v1.0.28 h1:D73owLaPfI/LL4MEnzPKjZKURZyBpOVzyfvW9Fd3v6k=
gitea.cdlsxd.cn/sdk/plugin v1.0.28/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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=
@ -60,8 +62,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
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.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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
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/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=

View File

@ -76,7 +76,7 @@ func (c *Config) orderReq(in *proto.OrderRequest) *api.OrderCreateReq {
OutTradeNo: in.Order.OrderNo, // 商户侧订单号长度只能是1-64位
ProductId: in.Product.ProductNo, // 产品编码不能为空
Number: int(in.Order.Quantity), // 部分商品存在限购数量,具体可联系商务
NotifyUrl: c.NotifyUrl, // 订单回调通知地址长度不能为空且长度不能超过255
NotifyUrl: c.NotifyUrl + "_" + c.AppId, // 订单回调通知地址长度不能为空且长度不能超过255
Extends: string(in.Order.Extra), // 部分特殊商品需要,具体可联系商务
RechargeAccount: in.Order.Account, // 账号类型:直充类型商品必传,商品为卡密类型时,则表示接收卡密的手机号
AccountType: accountType.AccountType(in.Order.Account).Value(), // 直充类型商品必传 - 1手机号 - 2: QQ 号
@ -87,17 +87,35 @@ func (c *Config) orderReq(in *proto.OrderRequest) *api.OrderCreateReq {
return req
}
func orderResp(request *proto.OrderRequest, resp *api.OrderCreateResp) *proto.OrderResponse {
data, _ := json.Marshal(resp)
return &proto.OrderResponse{
func orderResp(req *api.OrderCreateReq, errResp *api.ErrorResp, resp *api.OrderCreateResp) *proto.OrderResponse {
thirdRequest, _ := json.Marshal(req)
response := &proto.OrderResponse{
Result: &proto.Result{
Status: proto.Status_ING,
OrderNo: request.Order.OrderNo,
TradeNo: resp.OrderNo, // 平台订单号
OrderNo: req.OutTradeNo,
TradeNo: "",
Message: "成功",
Data: data,
Data: nil,
},
Idempotent: false,
ThirdRequest: string(thirdRequest),
ThirdResponse: "",
}
if errResp != nil {
response.Result.Status = proto.Status_FAIL
thirdResponse, _ := json.Marshal(errResp)
response.ThirdResponse = string(thirdResponse)
response.Result.Message = errResp.Message
} else {
thirdResponse, _ := json.Marshal(resp)
response.ThirdResponse = string(thirdResponse)
response.Result.TradeNo = resp.OrderNo
}
return response
}
func (c *Config) queryReq(in *proto.QueryRequest) *api.OrderQueryReq {
@ -106,40 +124,58 @@ func (c *Config) queryReq(in *proto.QueryRequest) *api.OrderQueryReq {
}
}
func queryResp(appKey string, request *proto.QueryRequest, resp *api.OrderQueryResp) (*proto.QueryResponse, error) {
data, err := json.Marshal(resp)
func queryResp(appKey string, req *api.OrderQueryReq, errResp *api.ErrorResp, resp *api.OrderQueryResp) (*proto.QueryResponse, error) {
thirdRequest, _ := json.Marshal(req)
response := &proto.QueryResponse{
Result: &proto.Result{
Status: 0,
OrderNo: req.OutTradeNo,
TradeNo: "",
Message: "",
Data: nil,
Extra: nil,
},
ThirdRequest: string(thirdRequest),
ThirdResponse: "",
}
if errResp != nil {
response.Result.Status = proto.Status_FAIL
thirdResponse, _ := json.Marshal(errResp)
response.ThirdResponse = string(thirdResponse)
response.Result.Message = errResp.Message
} else {
thirdResponse, err := json.Marshal(resp)
if err != nil {
return nil, proto.ErrorResponseFail(err.Error())
}
response.ThirdResponse = string(thirdResponse)
status := vo.OrderStatus(resp.TradeStatus)
pb := &proto.QueryResponse{
Result: &proto.Result{
Status: status.GetOrderStatus(),
OrderNo: request.Order.OrderNo,
TradeNo: resp.OrderNo,
Message: resp.TradeStateDesc,
Data: data,
Extra: nil,
},
}
response.Result.Status = vo.OrderStatus(resp.TradeStatus).GetOrderStatus()
response.Result.Message = resp.TradeStateDesc
response.Result.TradeNo = resp.OrderNo
if len(resp.Cards) > 0 {
c, err := getQueryCard(appKey, &resp.Cards[0])
if err != nil {
return nil, err
}
pb.Result.Extra = c.ToJson()
response.Result.Extra = c.ToJson()
}
}
return pb, nil
return response, nil
}
func getQueryCard(appKey string, card *api.Cards) (*Card, error) {
car := &Card{
Deadline: card.Deadline,
}
t := vo.CardType(card.CardType)
if t.IsPwdNo() {
pwd, err := decryptAES(card.Pwd, appKey)
if err != nil {
@ -163,10 +199,12 @@ func getQueryCard(appKey string, card *api.Cards) (*Card, error) {
} else if t.IsUrl() {
// 无
}
return car, nil
}
func notifyResp(appKey string, resp *notify.OrderReq) (*proto.NotifyResponse, error) {
data, err := json.Marshal(resp)
if err != nil {
return nil, proto.ErrorResponseFail(err.Error())
@ -206,6 +244,7 @@ func notifyResp(appKey string, resp *notify.OrderReq) (*proto.NotifyResponse, er
}
func getNotifyCard(appKey string, cards []notify.Cards) ([]byte, error) {
if len(cards) == 0 {
return nil, nil
}
@ -249,5 +288,6 @@ func getNotifyCard(appKey string, cards []notify.Cards) ([]byte, error) {
car.Password = pwd
}
return car.ToJson(), nil
}

View File

@ -7,7 +7,6 @@ type AccountType int64
const (
AccountTypeDefault AccountType = iota
AccountTypePhone
AccountTypeQQ
)
func (o AccountType) AccountType(account string) AccountType {
@ -15,8 +14,6 @@ func (o AccountType) AccountType(account string) AccountType {
return AccountTypeDefault
} else if helper.IsPhoneNumber(account) {
return AccountTypePhone
} else if helper.IsValidQQ(account) {
return AccountTypeQQ
}
return AccountTypeDefault
}

View File

@ -0,0 +1,12 @@
package vo
type Reason string
const (
PARAM_ERROR Reason = "PARAM_ERROR"
CONCURRENCE_LOCK Reason = "CONCURRENCE_LOCK"
NOT_ALLOW Reason = "NOT_ALLOW"
ORDER_REPEAT Reason = "ORDER_REPEAT"
LOW_UNIT_PRICE Reason = "LOW_UNIT_PRICE"
COMMON Reason = "COMMON"
)

View File

@ -22,11 +22,13 @@ const (
type ZLTXV2Service struct{}
// Order.
// https://tvd8jq9lqkp.feishu.cn/wiki/BdbuwSa1oiYtz3k9hILcMY1xnZe
func (p *ZLTXV2Service) Order(ctx context.Context, request *proto.OrderRequest) (resp2 *proto.OrderResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -40,23 +42,20 @@ func (p *ZLTXV2Service) Order(ctx context.Context, request *proto.OrderRequest)
return nil, err
}
response, errResp, err := api.OrderCreate(ctx, client, c.AppId, c.orderReq(request))
req := c.orderReq(request)
response, errResp, err := api.OrderCreate(ctx, client, c.AppId, req)
if err != nil {
return nil, proto.ErrorRequestFail(fmt.Sprintf("请求异常[%v]", err))
}
if errResp != nil {
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(req, errResp, response), nil
}
func (p *ZLTXV2Service) Query(ctx context.Context, request *proto.QueryRequest) (resp2 *proto.QueryResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()
@ -70,23 +69,20 @@ func (p *ZLTXV2Service) Query(ctx context.Context, request *proto.QueryRequest)
return nil, err
}
response, errResp, err := api.OrderQuery(ctx, client, c.AppId, c.queryReq(request))
req := c.queryReq(request)
response, errResp, err := api.OrderQuery(ctx, client, c.AppId, req)
if err != nil {
return nil, proto.ErrorRequestFail(fmt.Sprintf("请求异常[%v]", err))
}
if errResp != nil {
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, req, errResp, response)
}
func (p *ZLTXV2Service) Notify(_ context.Context, request *proto.NotifyRequest) (resp2 *proto.NotifyResponse, respErr error) {
defer func() {
if err := recover(); err != nil {
respErr = fmt.Errorf("panic: %v", err)
respErr = proto.ErrorPanic(fmt.Sprintf("panic: %v", err))
}
}()

View File

@ -13,16 +13,21 @@ import (
var zltx = &ZLTXV2Service{}
func config() []byte {
c := &Config{
AppId: "25891",
AppKey: "83cc38e09560417ad7ea0feaaae9d171",
//BaseUri: "http://211.137.105.198:17100",
BaseUri: "http://117.175.169.61:17100",
NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
}
//c := &Config{
// AppId: "23369",
// AppKey: "837c7a898810160ce5aab4c42bf22bc4",
// //BaseUri: "http://211.137.105.198:17100",
// BaseUri: "http://117.175.169.61:17100",
// NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
//}
//marshal, _ := json.Marshal(c)
//return marshal
// {\"app_id\":\"23372\",\"app_key\":\"174de174d6bd533b6553dc95606b8359\",\"base_uri\":\"http://117.175.169.61:17100\",\"merchant_id\":23372,\"notify_url\":\"https://gateway.dev.cdlsxd.cn/yxh5api/v1/supplier/callback/44\"}
//{"app_id":"25891","app_key":"83cc38e09560417ad7ea0feaaae9d171","merchant_id":25891}
marshal, _ := json.Marshal(c)
return marshal
return []byte(`{"app_id":"23369","app_key":"837c7a898810160ce5aab4c42bf22bc4","base_uri":"http://117.175.169.61:17100","merchant_id":23369,"notify_url":"https://gateway.dev.cdlsxd.cn/yxh5api/v1/supplier/callback/44"}`)
}
func TestConfig(t *testing.T) {
@ -37,13 +42,13 @@ func TestOrder(t *testing.T) {
request := &proto.OrderRequest{
Config: config(),
Order: &proto.OrderRequest_Order{
OrderNo: "test_zltx_v2_8",
Account: "18666666666",
OrderNo: "202603251007031980010102",
Account: "",
Quantity: 1,
Extra: nil,
},
Product: &proto.OrderRequest_Product{
ProductNo: "106",
ProductNo: "CEMLKRLK9640",
Extra: []byte(`{}`),
},
}

View File

@ -3,7 +3,7 @@ module plugins/utils
go 1.22.2
require (
gitea.cdlsxd.cn/sdk/plugin v1.0.17
gitea.cdlsxd.cn/sdk/plugin v1.0.26
github.com/go-playground/validator/v10 v10.22.0
github.com/tjfoc/gmsm v1.4.1
github.com/wechatpay-apiv3/wechatpay-go v0.2.18
@ -12,10 +12,14 @@ require (
require (
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/universal-translator v0.18.1 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sys v0.22.0 // 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
)

View File

@ -1,6 +1,8 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
gitea.cdlsxd.cn/sdk/plugin v1.0.26 h1:n0HZNqftz7egsZp9QaNC0bhQTHXjr+71q7lNdUCQemc=
gitea.cdlsxd.cn/sdk/plugin v1.0.26/go.mod h1:4fLMp/xB9GEBa3nJi62kXpHh7wnb9Lwjf0I8Vjaasx0=
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/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
@ -15,6 +17,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
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/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/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -38,6 +42,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -96,16 +102,22 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
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/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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=

View File

@ -1,6 +1,9 @@
package helper
import "testing"
import (
"fmt"
"testing"
)
func TestToChinese(t *testing.T) {
arg := "sub_msg"
@ -11,5 +14,17 @@ func TestToChinese(t *testing.T) {
func TestAccountType(t *testing.T) {
arg := "3122222222"
got := IsValidQQ(arg)
accountType()
t.Log(got)
}
func accountType() {
a := "6837370979"
if IsPhoneNumber(a) {
fmt.Println("AccountTypePhone")
} else if IsValidQQ(a) {
fmt.Println("AccountTypeQQ")
} else {
fmt.Println("AccountTypeDefault")
}
}

View File

@ -27,7 +27,7 @@ func NewOptions(options ...Option) *Options {
return code == http.StatusOK
},
Timeout: 15 * time.Second,
Timeout: 10 * time.Second,
}
for _, option := range options {

View File

@ -29,14 +29,17 @@ func (c *Server) Validate() error {
}
func newClient(ctx context.Context, c *Server) (*core.Client, error) {
dir, err := os.Getwd()
if err != nil {
return nil, proto.ErrorConfigFail(fmt.Sprintf("MchID[%s] get current dir error:%v", c.MchID, err))
}
//dir = "../../../"
filePath := fmt.Sprintf("%s/%s/%s/%s", dir, "cert", "wechat", c.MchID)
//fmt.Printf("filePath: %s\n", filePath)
if !putils.FileExists(filePath) {
return nil, proto.ErrorConfigFail(fmt.Sprintf("MchID[%s]微信密钥证书信息不存在,请联系技术人员处理", c.MchID))
return nil, proto.ErrorConfigFail(fmt.Sprintf("[%s-%s]微信密钥证书信息不存在,请联系技术人员处理", c.MchID, filePath))
}
// 商户相关配置,商户API私钥

View File

@ -0,0 +1,38 @@
package wechat
import (
"context"
"testing"
)
func Test_newClient(t *testing.T) {
type args struct {
ctx context.Context
c *Server
}
tests := []struct {
name string
args args
}{
{
"Test_newClient",
args{
context.Background(),
&Server{
MchID: "1629276485", // 1605446142
MchCertificateSerialNumber: "3C7E21B74C04BE6227A690EB44184F219D763F92", // 4D081089DEB385316CBDCB55C070287E4920AC76
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := newClient(tt.args.ctx, tt.args.c)
if err != nil {
t.Errorf("newClient() error = %v", err)
return
}
})
}
}