重构代码结构与认证体系,集成异步任务消费者

This commit is contained in:
2025-11-17 18:38:10 +08:00
parent a97c970166
commit a245229bc2
70 changed files with 2000 additions and 2334 deletions

View File

@@ -28,9 +28,9 @@ type SftClient struct {
publicKey *rsa.PublicKey
}
func initSft() {
func initSft() error {
if !env.SftPayEnable {
panic("商福通支付未启用,请检查环境变量 SFTPAY_ENABLE")
return fmt.Errorf("商福通支付未启用,请检查环境变量 SFTPAY_ENABLE")
}
SFTPay = SftClient{
@@ -41,7 +41,7 @@ func initSft() {
// 加载私钥
private, err := base64.StdEncoding.DecodeString(env.SftPayAppPrivateKey)
if err != nil {
panic("解析商福通私钥失败: " + err.Error())
return fmt.Errorf("解析商福通私钥失败: %w", err)
}
var privateKey *rsa.PrivateKey
@@ -49,13 +49,13 @@ func initSft() {
if err != nil {
pkcs8, err := x509.ParsePKCS8PrivateKey(private)
if err != nil {
panic("解析商福通私钥失败: " + err.Error())
return fmt.Errorf("解析商福通私钥失败: %w", err)
}
var ok bool
privateKey, ok = pkcs8.(*rsa.PrivateKey)
if !ok {
panic("解析商福通私钥失败")
return fmt.Errorf("解析商福通私钥失败")
}
}
SFTPay.privateKey = privateKey
@@ -63,35 +63,36 @@ func initSft() {
// 加载公钥
public, err := base64.StdEncoding.DecodeString(env.SftPayPublicKey)
if err != nil {
panic("解析商福通公钥失败: " + err.Error())
return fmt.Errorf("解析商福通公钥失败: %w", err)
}
var publicKey *rsa.PublicKey
pkix, err := x509.ParsePKIXPublicKey(public)
if err != nil {
panic("解析商福通公钥失败: " + err.Error())
return fmt.Errorf("解析商福通公钥失败: %w", err)
}
var ok bool
publicKey, ok = pkix.(*rsa.PublicKey)
if !ok {
panic("解析商福通公钥失败")
return fmt.Errorf("解析商福通公钥失败")
}
SFTPay.publicKey = publicKey
return nil
}
func (s *SftClient) PaymentScanPay(req *PaymentScanPayReq) (*PaymentScanPayResp, error) {
const url = "https://pay.rscygroup.com/api/open/payment/scanpay"
req.ReturnUrl = env.SftReturnUrl
req.NotifyUrl = env.SftNotifyUrl
req.ReturnUrl = u.X(env.SftReturnUrl)
req.NotifyUrl = u.X(env.SftNotifyUrl)
req.RouteNo = u.P(s.routeId)
return call[PaymentScanPayResp](s, url, req)
}
func (s *SftClient) PaymentH5Pay(req *PaymentH5PayReq) (*PaymentH5PayResp, error) {
const url = "https://pay.rscygroup.com/api/open/payment/h5pay"
req.ReturnUrl = env.SftReturnUrl
req.NotifyUrl = env.SftNotifyUrl
req.ReturnUrl = u.X(env.SftReturnUrl)
req.NotifyUrl = u.X(env.SftNotifyUrl)
req.RouteNo = u.P(s.routeId)
return call[PaymentH5PayResp](s, url, req)
}
@@ -256,7 +257,7 @@ func call[T any](s *SftClient, url string, req any) (*T, error) {
encode, err := s.sign(req)
if err != nil {
return nil, fmt.Errorf("加密请求内容失败%w", err)
return nil, fmt.Errorf("加密请求内容失败: %w", err)
}
bytes, err := json.Marshal(encode)
@@ -266,33 +267,33 @@ func call[T any](s *SftClient, url string, req any) (*T, error) {
request, err := http.NewRequest("POST", url, strings.NewReader(string(bytes)))
if err != nil {
return nil, fmt.Errorf("创建请求失败%w", err)
return nil, fmt.Errorf("创建请求失败: %w", err)
}
request.Header.Set("Content-Type", "application/json")
if env.DebugHttpDump == true {
reqDump, err := httputil.DumpRequest(request, true)
if err != nil {
return nil, fmt.Errorf("请求内容转储失败%w", err)
return nil, fmt.Errorf("请求内容转储失败: %w", err)
}
println(string(reqDump) + "\n\n")
}
response, err := http.DefaultClient.Do(request)
if err != nil {
return nil, fmt.Errorf("请求失败%w", err)
return nil, fmt.Errorf("请求失败: %w", err)
}
if env.DebugHttpDump == true {
respDump, err := httputil.DumpResponse(response, true)
if err != nil {
return nil, fmt.Errorf("响应内容转储失败%w", err)
return nil, fmt.Errorf("响应内容转储失败: %w", err)
}
println(string(respDump) + "\n\n")
}
if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf("请求响应失败%d", response.StatusCode)
return nil, fmt.Errorf("请求响应失败: %d", response.StatusCode)
}
defer func(body io.ReadCloser) {
_ = body.Close()
@@ -300,18 +301,18 @@ func call[T any](s *SftClient, url string, req any) (*T, error) {
body, err := io.ReadAll(response.Body)
if err != nil {
return nil, fmt.Errorf("读取响应内容失败%w", err)
return nil, fmt.Errorf("读取响应内容失败: %w", err)
}
decode, err := s.verify(body)
if err != nil {
return nil, fmt.Errorf("解密响应内容失败%w", err)
return nil, fmt.Errorf("解密响应内容失败: %w", err)
}
var resp = new(T)
err = json.Unmarshal([]byte(decode), resp)
if err != nil {
return nil, fmt.Errorf("响应正文解析失败%w", err)
return nil, fmt.Errorf("响应正文解析失败: %w", err)
}
return resp, nil
@@ -321,7 +322,7 @@ func (s *SftClient) sign(msg any) (*request, error) {
bytes, err := json.Marshal(msg)
if err != nil {
return nil, fmt.Errorf("格式化加密正文失败%w", err)
return nil, fmt.Errorf("格式化加密正文失败: %w", err)
}
if env.DebugHttpDump {
@@ -341,7 +342,7 @@ func (s *SftClient) sign(msg any) (*request, error) {
hashed := sha256.Sum256([]byte(body.String()))
signature, err := rsa.SignPKCS1v15(nil, s.privateKey, crypto.SHA256, hashed[:])
if err != nil {
return nil, fmt.Errorf("签名失败%w", err)
return nil, fmt.Errorf("签名失败: %w", err)
}
body.Sign = base64.StdEncoding.EncodeToString(signature)
@@ -353,11 +354,11 @@ func (s *SftClient) verify(str []byte) (string, error) {
var resp = new(response)
err := json.Unmarshal(str, resp)
if err != nil {
return "", fmt.Errorf("解析响应正文失败%w", err)
return "", fmt.Errorf("解析响应正文失败: %w", err)
}
if resp.Code != "000000" {
return "", fmt.Errorf("请求业务响应失败%s", u.Z(resp.Msg))
return "", fmt.Errorf("请求业务响应失败: %s", u.Z(resp.Msg))
}
if resp.Sign == nil {
@@ -371,13 +372,13 @@ func (s *SftClient) verify(str []byte) (string, error) {
ser, err := resp.String()
if err != nil {
return "", fmt.Errorf("格式化响应内容失败%w", err)
return "", fmt.Errorf("格式化响应内容失败: %w", err)
}
hashed := sha256.Sum256([]byte(ser))
err = rsa.VerifyPKCS1v15(s.publicKey, crypto.SHA256, hashed[:], sign)
if err != nil {
return "", fmt.Errorf("验签失败%w", err)
return "", fmt.Errorf("验签失败: %w", err)
}
return *resp.BizData, nil
@@ -412,7 +413,7 @@ type response struct {
func (r response) String() (string, error) {
if r.BizData == nil || r.Msg == nil || r.SignType == nil {
return "", core.NewServErr(fmt.Sprintf(
"上游数据返回有空值BizData %vMsg %v, SignType %v",
"上游数据返回有空值: BizData %vMsg %v, SignType %v",
r.BizData == nil, r.Msg == nil, r.SignType == nil,
))
}