plugins/utils/weixin/instance.go

64 lines
1.6 KiB
Go

package weixin
import (
"context"
"fmt"
"github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
"github.com/wechatpay-apiv3/wechatpay-go/utils"
"sync"
)
type Config struct {
MchID string `json:"mch_id"`
MchCertificateSerialNumber string `json:"mch_certificate_serial_number"`
MchAPIv3Key string `json:"mch_ap_iv_3_key"`
PrivateKey string `json:"private_key"`
PrivateKeyPath string `json:"private_key_path"`
}
type manager struct {
once sync.Once
mutex sync.RWMutex
clients map[string]*core.Client
}
var instance manager
func init() {
instance = manager{
clients: make(map[string]*core.Client),
}
}
func New(ctx context.Context, c *Config) (*core.Client, error) {
instance.mutex.Lock()
defer instance.mutex.Unlock()
if instance.clients[c.MchID] != nil {
return instance.clients[c.MchID], nil
}
var err error
instance.once.Do(func() {
instance.clients[c.MchID], err = client(ctx, c)
})
if err != nil {
return nil, err
}
return instance.clients[c.MchID], nil
}
func client(ctx context.Context, c *Config) (*core.Client, error) {
mchPrivateKey, err := utils.LoadPrivateKey(c.PrivateKey)
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),
}
cl, err := core.NewClient(ctx, opts...)
if err != nil {
return nil, fmt.Errorf("MchID[%s] new wechat pay client err:%v", c.MchID, err)
}
return cl, nil
}