Files
2026-09-11 16:08:17 +08:00

70 lines
1.5 KiB
Go

package pay
import (
"context"
"crypto/rsa"
"fmt"
"net/http"
"time"
)
const defaultHost = "https://api.mch.weixin.qq.com"
type Client struct {
AppID string
MchID string
CertificateSerialNo string
PrivateKey *rsa.PrivateKey
platformCerts map[string]*rsa.PublicKey
platformSerial string
APIv3Key string
NotifyURL string
Host string
httpClient *http.Client
}
func NewClient(cfg Config) (*Client, error) {
privateKey, err := loadPrivateKey(cfg.PrivateKeyPath)
if err != nil {
return nil, err
}
if cfg.APIv3Key == "" {
return nil, fmt.Errorf("apiv3 key is required")
}
c := &Client{
AppID: cfg.AppID,
MchID: cfg.MchID,
CertificateSerialNo: cfg.CertificateSerialNo,
PrivateKey: privateKey,
APIv3Key: cfg.APIv3Key,
NotifyURL: cfg.NotifyURL,
Host: defaultHost,
httpClient: &http.Client{Timeout: 30 * time.Second},
}
if cfg.PlatformCertPath != "" {
serial, publicKey, err := loadPlatformCertificate(cfg.PlatformCertPath)
if err != nil {
return nil, err
}
c.addPlatformCert(serial, publicKey)
c.platformSerial = serial
}
if err := c.refreshPlatformCertificates(context.Background()); err != nil {
if len(c.platformCerts) == 0 {
return nil, fmt.Errorf("load platform certificates: %w", err)
}
}
if c.platformSerial == "" {
for serial := range c.platformCerts {
c.platformSerial = serial
break
}
}
return c, nil
}