70 lines
1.5 KiB
Go
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
|
|
}
|