package payCenter import ( "crypto/md5" "crypto/subtle" "encoding/hex" "errors" "net/url" "strconv" "strings" "time" ) // Conf 与 girl 的 newPayCenter 配置保持一致,App 和 Web 各自加载本进程配置。 type Conf struct { AppName string `yaml:"appName"` CallbackUrl string `yaml:"callbackUrl"` ApiUrl string `yaml:"apiUrl"` MercID string `yaml:"mercID"` MercSecret string `yaml:"mercSecret"` } var payCenterConf Conf func Init(c Conf) { c.ApiUrl = strings.TrimRight(strings.TrimSpace(c.ApiUrl), "/") c.CallbackUrl = strings.TrimRight(strings.TrimSpace(c.CallbackUrl), "/") payCenterConf = c } // validateConfig 仅在支付请求时校验,配置暂未填写不影响其他业务启动。 func validateConfig(requireCallback bool) error { if payCenterConf.MercID == "" || payCenterConf.MercSecret == "" || !validHTTPURL(payCenterConf.ApiUrl) { return errors.New("新支付中心配置不完整:请配置 newPayCenter.apiUrl、mercID、mercSecret") } if requireCallback && (payCenterConf.AppName == "" || !validHTTPURL(payCenterConf.CallbackUrl)) { return errors.New("新支付中心配置不完整:请配置 newPayCenter.appName、callbackUrl") } return nil } func validHTTPURL(value string) bool { u, err := url.Parse(value) return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != "" && u.User == nil && u.RawQuery == "" && u.Fragment == "" } func Generate13DigitString() string { return strconv.FormatInt(time.Now().UnixMilli(), 10) } func md5Sign(value string) string { hash := md5.Sum([]byte(value)) return hex.EncodeToString(hash[:]) } func VerifySign(sign, value string) bool { return subtle.ConstantTimeCompare([]byte(md5Sign(value)), []byte(sign)) == 1 } func RChgIDDisassemble(transNo string) string { parts := strings.Split(transNo, "-") return parts[len(parts)-1] }