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 }