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 }