微信红包 todo 插件加载证书

This commit is contained in:
李子铭 2024-09-02 11:07:01 +08:00
parent 8003c6b67d
commit 740d48d4fe
30 changed files with 168 additions and 128 deletions

View File

@ -48,15 +48,15 @@ alipay_redpack:
make build-mac name=alipay_redpack && \
make build-linux name=alipay_redpack
.PHONY: weixin_cpn
weixin_cpn:
make build-mac name=weixin_cpn && \
make build-linux name=weixin_cpn
.PHONY: wechat_cpn
wechat_cpn:
make build-mac name=wechat_cpn && \
make build-linux name=wechat_cpn
.PHONY: weixin_redpack
weixin_redpack:
make build-mac name=weixin_redpack && \
make build-linux name=weixin_redpack
.PHONY: wechat_redpack
wechat_redpack:
make build-mac name=wechat_redpack && \
make build-linux name=wechat_redpack
.PHONY: all
all: zltx union_pay_cpn union_pay_redpack alipay_cpn alipay_redpack weixin_cpn weixin_redpack
all: zltx union_pay_cpn union_pay_redpack alipay_cpn alipay_redpack wechat_cpn wechat_redpack

View File

@ -3,4 +3,5 @@ package main
// main 这只是一个演示
func main() {
wechatCpn()
//wechatRedPack()
}

View File

@ -7,19 +7,19 @@ import (
"gitea.cdlsxd.cn/sdk/plugin/manage"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"log"
"plugins/utils/weixin"
"plugins/utils/wechat"
)
var wechatCpnConf = &manage.Config{
Cmd: "pkg/mac/weixin_cpn.so",
Cmd: "pkg/mac/wechat_cpn.so",
Tag: "alipay_redpack",
Version: 1,
CookieKey: "weixin_cpn",
CookieValue: "weixin_cpn",
CookieKey: "wechat_cpn",
CookieValue: "wechat_cpn",
}
func getWechatCpnConf() []byte {
c := &weixin.Server{
c := &wechat.Server{
MchID: "1605446142", // 证书所属商户
MchCertificateSerialNumber: "4D081089DEB385316CBDCB55C070287E4920AC76",
MchAPIv3Key: "ChengDuLanSeXiongDi1234567890123",

50
cmd/wechat_redpack.go Normal file
View File

@ -0,0 +1,50 @@
package main
import (
"context"
"encoding/json"
"gitea.cdlsxd.cn/sdk/plugin/instance"
"gitea.cdlsxd.cn/sdk/plugin/manage"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"log"
"plugins/utils/wechat"
)
var wechatRedPackConf = &manage.Config{
Cmd: "pkg/mac/wechat_redpack.so",
Tag: "wechat_redpack",
Version: 1,
CookieKey: "wechat_redpack",
CookieValue: "wechat_redpack",
}
func getWechatRedPackConf() []byte {
c := &wechat.Server{
MchID: "1629276485",
MchCertificateSerialNumber: "3C7E21B74C04BE6227A690EB44184F219D763F92",
MchAPIv3Key: "ChengDuBale0123456789qwertyuiopa",
}
marshal, _ := json.Marshal(c)
return marshal
}
func wechatRedPack() {
err := manage.Add(wechatRedPackConf)
if err != nil {
log.Fatalln(err)
}
queryRequest := &proto.QueryRequest{
Config: getWechatRedPackConf(),
Order: &proto.QueryRequest_Order{
OrderNo: "",
TradeNo: "69445765514",
Account: "oO3vO5AxRWgTjmMD38FTvnB5Rq6o",
Extra: []byte(`{"app_id":"wx9ed74283ad25bca1"}`),
},
}
resQuery, err := instance.Query(context.Background(), wechatRedPackConf.Tag, queryRequest)
if err != nil {
log.Fatalln(err)
}
log.Printf("Query res:%+v", resQuery)
}

View File

@ -18,9 +18,9 @@ union_pay_cpn:
alipay_cpn:
make build name=alipay_cpn
.PHONY: weixin_cpn
weixin_cpn:
make build name=weixin_cpn
.PHONY: wechat_cpn
wechat_cpn:
make build name=wechat_cpn
.PHONY: all
all:

View File

@ -1,4 +1,4 @@
module plugins/weixin_cpn
module plugins/wechat_cpn
go 1.22.2

View File

@ -7,12 +7,12 @@ import (
"github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/services/cashcoupons"
"go/types"
"plugins/utils/weixin"
"plugins/weixin_cpn/internal/vo"
"plugins/utils/wechat"
"plugins/wechat_cpn/internal/vo"
)
func transConfig(config []byte) (*weixin.Server, error) {
var c weixin.Server
func transConfig(config []byte) (*wechat.Server, error) {
var c wechat.Server
err := json.Unmarshal(config, &c)
if err != nil {
return nil, err

View File

@ -3,11 +3,11 @@ package internal
import (
"context"
"github.com/wechatpay-apiv3/wechatpay-go/services/cashcoupons"
"plugins/utils/weixin"
"plugins/utils/wechat"
)
func srv(ctx context.Context, c *weixin.Server) (*cashcoupons.CouponApiService, error) {
client, err := weixin.GetClient(ctx, c)
func srv(ctx context.Context, c *wechat.Server) (*cashcoupons.CouponApiService, error) {
client, err := wechat.GetClient(ctx, c)
if err != nil {
return nil, err
}
@ -15,7 +15,7 @@ func srv(ctx context.Context, c *weixin.Server) (*cashcoupons.CouponApiService,
return &svc, nil
}
func verify(ctx context.Context, c *weixin.Server) error {
func verify(ctx context.Context, c *wechat.Server) error {
err := c.Verify(ctx, "", "")
if err != nil {
return err

View File

@ -3,20 +3,20 @@ package internal
import (
"context"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"plugins/weixin_cpn/internal/vo"
"plugins/wechat_cpn/internal/vo"
)
// 插件通信信息,若不对应则会报错panic
const (
Tag = "weixin_cpn"
Tag = "wechat_cpn"
Version = 1
CookieKey = "weixin_cpn"
CookieValue = "weixin_cpn"
CookieKey = "wechat_cpn"
CookieValue = "wechat_cpn"
)
type WeiXinCpnService struct{}
type WeChatCpnService struct{}
func (p *WeiXinCpnService) Order(ctx context.Context, request *proto.OrderRequest) (*proto.OrderResponse, error) {
func (p *WeChatCpnService) Order(ctx context.Context, request *proto.OrderRequest) (*proto.OrderResponse, error) {
config, err := transConfig(request.Config)
if err != nil {
return nil, err
@ -39,7 +39,7 @@ func (p *WeiXinCpnService) Order(ctx context.Context, request *proto.OrderReques
return orderResp(request.GetOrder(), *resp.CouponId), nil
}
func (p *WeiXinCpnService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) {
func (p *WeChatCpnService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) {
config, err := transConfig(request.Config)
svc, err := srv(ctx, config)
if err != nil {
@ -59,7 +59,7 @@ func (p *WeiXinCpnService) Query(ctx context.Context, request *proto.QueryReques
return queryResp(request, resp), nil
}
func (p *WeiXinCpnService) Notify(ctx context.Context, request *proto.NotifyRequest) (*proto.NotifyResponse, error) {
func (p *WeChatCpnService) Notify(ctx context.Context, request *proto.NotifyRequest) (*proto.NotifyResponse, error) {
config, err := transConfig(request.Config)
if err != nil {
return nil, err

View File

@ -6,14 +6,14 @@ import (
"fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/stretchr/testify/assert"
"plugins/utils/weixin"
"plugins/utils/wechat"
"testing"
)
var server = &WeiXinCpnService{}
var server = &WeChatCpnService{}
func config() []byte {
c := &weixin.Server{
c := &wechat.Server{
MchID: "1605446142", // 证书所属商户
MchCertificateSerialNumber: "4D081089DEB385316CBDCB55C070287E4920AC76",
MchAPIv3Key: "ChengDuLanSeXiongDi1234567890123",

View File

@ -3,13 +3,13 @@ package main
import (
"gitea.cdlsxd.cn/sdk/plugin/shared"
"github.com/hashicorp/go-plugin"
"plugins/weixin_cpn/internal"
"plugins/wechat_cpn/internal"
)
func main() {
plugin.Serve(&plugin.ServeConfig{
HandshakeConfig: shared.HandshakeConfig(internal.Version, internal.CookieKey, internal.CookieValue),
Plugins: shared.PluginSet(shared.NewPlugin(&internal.WeiXinCpnService{}, internal.Tag)),
Plugins: shared.PluginSet(shared.NewPlugin(&internal.WeChatCpnService{}, internal.Tag)),
GRPCServer: plugin.DefaultGRPCServer,
})
}

View File

@ -1,4 +1,4 @@
module plugins/weixin_redpack
module plugins/wechat_redpack
go 1.22.2

View File

@ -6,12 +6,12 @@ import (
"gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/services/transferbatch"
"plugins/utils/weixin"
"plugins/weixin_redpack/internal/vo"
"plugins/utils/wechat"
"plugins/wechat_redpack/internal/vo"
)
func transConfig(config []byte) (*weixin.Server, error) {
var c weixin.Server
func transConfig(config []byte) (*wechat.Server, error) {
var c wechat.Server
err := json.Unmarshal(config, &c)
if err != nil {
return nil, err

View File

@ -0,0 +1,33 @@
package internal
import (
"context"
"github.com/wechatpay-apiv3/wechatpay-go/services/transferbatch"
"plugins/utils/wechat"
)
func transferBatchApiService(ctx context.Context, c *wechat.Server) (*transferbatch.TransferBatchApiService, error) {
client, err := wechat.GetClient(ctx, c)
if err != nil {
return nil, err
}
svc := transferbatch.TransferBatchApiService{Client: client}
return &svc, nil
}
func transferDetailApiService(ctx context.Context, c *wechat.Server) (*transferbatch.TransferDetailApiService, error) {
client, err := wechat.GetClient(ctx, c)
if err != nil {
return nil, err
}
svc := transferbatch.TransferDetailApiService{Client: client}
return &svc, nil
}
func verify(ctx context.Context, c *wechat.Server) error {
err := c.Verify(ctx, "", "")
if err != nil {
return err
}
return nil
}

View File

@ -3,20 +3,20 @@ package internal
import (
"context"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"plugins/weixin_redpack/internal/vo"
"plugins/wechat_redpack/internal/vo"
)
// 插件通信信息,若不对应则会报错panic
const (
Tag = "weixin_redpack"
Tag = "wechat_redpack"
Version = 1
CookieKey = "weixin_redpack"
CookieValue = "weixin_redpack"
CookieKey = "wechat_redpack"
CookieValue = "wechat_redpack"
)
type WeiXinRedPackService struct{}
type WeChatRedPackService struct{}
func (p *WeiXinRedPackService) Order(ctx context.Context, request *proto.OrderRequest) (*proto.OrderResponse, error) {
func (p *WeChatRedPackService) Order(ctx context.Context, request *proto.OrderRequest) (*proto.OrderResponse, error) {
config, err := transConfig(request.Config)
if err != nil {
return nil, err
@ -39,7 +39,7 @@ func (p *WeiXinRedPackService) Order(ctx context.Context, request *proto.OrderRe
return orderResp(request.GetOrder(), *resp.BatchId), nil
}
func (p *WeiXinRedPackService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) {
func (p *WeChatRedPackService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) {
req, err := queryReq(request.GetOrder())
if err != nil {
return nil, err
@ -62,6 +62,6 @@ func (p *WeiXinRedPackService) Query(ctx context.Context, request *proto.QueryRe
return queryResp(request, resp), nil
}
func (p *WeiXinRedPackService) Notify(_ context.Context, _ *proto.NotifyRequest) (*proto.NotifyResponse, error) {
func (p *WeChatRedPackService) Notify(_ context.Context, _ *proto.NotifyRequest) (*proto.NotifyResponse, error) {
return notifyResp(), nil
}

View File

@ -6,19 +6,17 @@ import (
"fmt"
"gitea.cdlsxd.cn/sdk/plugin/proto"
"github.com/stretchr/testify/assert"
"plugins/utils/weixin"
"plugins/utils/wechat"
"testing"
)
var server = &WeiXinRedPackService{}
var server = &WeChatRedPackService{}
func config() []byte {
c := &weixin.Server{
c := &wechat.Server{
MchID: "1629276485",
MchCertificateSerialNumber: "3C7E21B74C04BE6227A690EB44184F219D763F92",
MchAPIv3Key: "ChengDuBale0123456789qwertyuiopa",
// 商户API私钥
PrivateKeyPath: "/Users/lsxd/code/php/yxxt/market/config/wechatcash/apiclient_key.pem",
}
marshal, _ := json.Marshal(c)
return marshal

View File

@ -3,13 +3,13 @@ package main
import (
"gitea.cdlsxd.cn/sdk/plugin/shared"
"github.com/hashicorp/go-plugin"
"plugins/weixin_redpack/internal"
"plugins/wechat_redpack/internal"
)
func main() {
plugin.Serve(&plugin.ServeConfig{
HandshakeConfig: shared.HandshakeConfig(internal.Version, internal.CookieKey, internal.CookieValue),
Plugins: shared.PluginSet(shared.NewPlugin(&internal.WeiXinRedPackService{}, internal.Tag)),
Plugins: shared.PluginSet(shared.NewPlugin(&internal.WeChatRedPackService{}, internal.Tag)),
GRPCServer: plugin.DefaultGRPCServer,
})
}

View File

@ -1,53 +0,0 @@
package internal
import (
"context"
"crypto/x509"
"fmt"
"github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
"github.com/wechatpay-apiv3/wechatpay-go/services/transferbatch"
"github.com/wechatpay-apiv3/wechatpay-go/utils"
"plugins/utils/weixin"
)
func transferBatchApiService(ctx context.Context, c *weixin.Server) (*transferbatch.TransferBatchApiService, error) {
client, err := weixin.GetClient(ctx, c)
if err != nil {
return nil, err
}
svc := transferbatch.TransferBatchApiService{Client: client}
return &svc, nil
}
func transferDetailApiService(ctx context.Context, c *weixin.Server) (*transferbatch.TransferDetailApiService, error) {
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(c.PrivateKeyPath)
if err != nil {
return nil, fmt.Errorf("MchID[%s] load merchant private key error:%v", c.MchID, err)
}
opts := []core.ClientOption{
option.WithWechatPayAutoAuthCipher(c.MchID, c.MchCertificateSerialNumber, mchPrivateKey, c.MchAPIv3Key),
}
if c.CertificatePath != "" {
payCert, err := utils.LoadCertificateWithPath(c.CertificatePath)
if err != nil {
return nil, fmt.Errorf("MchID[%s] load pay certificate error:%v", c.MchID, err)
}
opts = append(opts, option.WithWechatPayCertificate([]*x509.Certificate{payCert}))
}
client, err := core.NewClient(ctx, opts...)
if err != nil {
return nil, fmt.Errorf("MchID[%s] %v", c.MchID, err)
}
svc := transferbatch.TransferDetailApiService{Client: client}
return &svc, nil
}
func verify(ctx context.Context, c *weixin.Server) error {
err := c.Verify(ctx, "", "")
if err != nil {
return err
}
return nil
}

View File

@ -3,6 +3,7 @@ package alipay
import (
"fmt"
"os"
"plugins/utils"
"sync"
)
@ -48,8 +49,8 @@ func GetCert(appId string) (*CertConfig, error) {
return nil, fmt.Errorf("get current dir error: %v", err)
}
filePath := fmt.Sprintf("%s/%s/%s/%s", dir, "cert", "alipay", appId)
if !fileExists(filePath) {
return nil, fmt.Errorf("[%s]授权文件信息不存在,请联系技术人员处理", appId)
if !utils.FileExists(filePath) {
return nil, fmt.Errorf("appId[%s]支付宝密钥文件信息不存在,请联系技术人员处理", appId)
}
mchCertPath := fmt.Sprintf("%s/%s_%s.crt", filePath, "appCertPublicKey", appId)
mchCertSN, err := getMchCertSN(mchCertPath)

View File

@ -7,7 +7,6 @@ import (
"encoding/pem"
"fmt"
"log"
"os"
)
// md5Hash 计算 MD5 哈希值
@ -37,8 +36,3 @@ func getCert(certData []byte) (*x509.Certificate, error) {
return cert, nil
}
func fileExists(filePath string) bool {
_, err := os.Stat(filePath)
return err == nil || os.IsExist(err)
}

10
utils/common.go Normal file
View File

@ -0,0 +1,10 @@
package utils
import (
"os"
)
func FileExists(filePath string) bool {
_, err := os.Stat(filePath)
return err == nil || os.IsExist(err)
}

View File

@ -1,13 +1,13 @@
package weixin
package wechat
import (
"context"
"crypto/x509"
"fmt"
"github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
"github.com/wechatpay-apiv3/wechatpay-go/utils"
"os"
putils "plugins/utils"
)
type Server struct {
@ -22,6 +22,10 @@ func newClient(ctx context.Context, c *Server) (*core.Client, error) {
return nil, fmt.Errorf("MchID[%s] get current dir error:%v", c.MchID, err)
}
filePath := fmt.Sprintf("%s/%s/%s/%s", dir, "cert", "wechat", c.MchID)
if !putils.FileExists(filePath) {
return nil, fmt.Errorf("MchID[%s]微信密钥证书信息不存在,请联系技术人员处理", c.MchID)
}
// 商户相关配置,商户API私钥
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(fmt.Sprintf("%s/%s", filePath, "wechat_private_key.pem"))
if err != nil {
return nil, fmt.Errorf("MchID[%s] load merchant private key error:%v", c.MchID, err)
@ -29,11 +33,13 @@ func newClient(ctx context.Context, c *Server) (*core.Client, error) {
opts := []core.ClientOption{
option.WithWechatPayAutoAuthCipher(c.MchID, c.MchCertificateSerialNumber, mchPrivateKey, c.MchAPIv3Key),
}
payCert, err := utils.LoadCertificateWithPath(fmt.Sprintf("%s/%s", filePath, "wechat_cert.pem"))
if err != nil {
return nil, fmt.Errorf("MchID[%s] load pay certificate error:%v", c.MchID, err)
}
opts = append(opts, option.WithWechatPayCertificate([]*x509.Certificate{payCert}))
// 微信支付平台配置
////payCert, err := utils.LoadCertificateWithPath(fmt.Sprintf("%s/%s", filePath, "wechat_cert.pem"))
//payCert, err := utils.LoadCertificateWithPath(fmt.Sprintf("%s/%s", filePath, "wechatpay_2C10BB073B55C2191DF46CE443DA8B9064AB7F60.pem"))
//if err != nil {
// return nil, fmt.Errorf("MchID[%s] load pay certificate error:%v", c.MchID, err)
//}
//opts = append(opts, option.WithWechatPayCertificate([]*x509.Certificate{payCert}))
client, err := core.NewClient(ctx, opts...)
if err != nil {
return nil, fmt.Errorf("MchID[%s] %v", c.MchID, err)

View File

@ -1,4 +1,4 @@
package weixin
package wechat
import (
"context"