package pay import ( "crypto" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/json" "encoding/pem" "errors" "fmt" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "io/ioutil" "strings" "system_pay/controller/base" "system_pay/models" "system_pay/repository/pay" ) // 卡拉卡统一支付回调 type NoticeController struct { } // WxNotice 拉卡拉统一支付微信回调 // @Summary 拉卡拉统一支付微信回调 // @Description 拉卡拉统一支付微信回调 // @Tags 拉卡拉统一支付回调 // @Accept application/json // @Produce application/json // @Param body body models.WxNoticeInput true "参数" // @Param language header string ture "语言类型 zh-CN简体中文 en-US英文 ja 日文 默认中文" // @Success 200 // @router /api/v1/pay/wx_notice [post] func (l *PayController) WxNotice(c *gin.Context) { fmt.Println("拉卡拉微信回调start") //验证签名 err := VerifySignCert(c) if err != nil { fmt.Println("verySignByPublicKey err: ", err) response := new(base.ResponseDataWxNotice) response.Code = "FAIL" response.Message = "验证签名失败" base.ResponseWxNotice(c, response) return } //fmt.Println("验证签名成功...") //response := new(base.ResponseDataWxNotice) //response.Code = "SUCCESS" //response.Message = "执行成功" //base.ResponseWxNotice(c, response) //return fmt.Println("验证签名成功...") ph := new(models.WxNoticeInput) err = c.ShouldBindJSON(ph) if err != nil { response := new(base.ResponseDataWxNotice) response.Code = "FAIL" response.Message = "执行失败2" base.ResponseWxNotice(c, response) return } fmt.Println(ph) // 拉卡拉统一支付微信回调 response, err := pay.WxNotice(ph) fmt.Println("拉卡拉微信回调end") base.ResponseWxNotice(c, response) } //读取证书文件,验证签名 func VerifySignCert(c *gin.Context) error { // 1、读取证书文件,获取证书字节 certPEM, err := ioutil.ReadFile("./cert/dev/lkl-apigw-v2.cer") //测试 //certPEM, err := ioutil.ReadFile("./cert/prod/dbc/lkl-apigw-v1.cer") //正式 if err != nil { fmt.Println("ioutil.ReadFile failed") return err } block, _ := pem.Decode([]byte(certPEM)) if block == nil { fmt.Println("failed to parse certificate PEM") return errors.New("failed to parse certificate") } cert, err := x509.ParseCertificate(block.Bytes) if err != nil { fmt.Println("failed to parse certificate: " + err.Error()) return err } authorization := c.GetHeader("Authorization") fmt.Println("wangpei test 验证签名0...") fmt.Println("Authorization1="+authorization) authorization = strings.Replace(authorization, "LKLAPI-SHA256withRSA ", "", -1) authorization = strings.Replace(authorization, ",","&", -1) authorization = strings.Replace(authorization, "\"","", -1) //authorization = "timestamp=1689752771&nonce_str=5HO2w0AjbhJc&signature=VNk9oio0rUMOs1X2j37p9+6o2EyAL3SaLwq2riO0C2FIbTbCZaOrpLSHt6LmgWHHYf50GOQnjZb3oWiTW6LBhF/2ROisEtl78tef6HtMl4mrnDy8BkQGpJS3IL/du+t35OlxeKpBjrpr6ObdZlaA26OZf4uMXRnSv15tvntSi0zM0GA7+dcUCBd4sFPGRgU0qfABiqC7bzzOZFrUpEe7ZZRfXQ2PLkJO0uBQt7vUoqt0fVXsPR+FjR++e1JASg821Gf7+J+Tr73MoAVkRJ0HwJX72HbbffVMNAYF/5cc/sL50WtFJ8JrLj6WAJdesSmeFBrs+tOEMH62b+Wr/mPnXw==" auth_parts := strings.Split(authorization, "&") params := make(map[string]string) for _, param := range auth_parts { item := strings.Split(param, "=") params[item[0]] = item[1] } //if params["signature"] != "" && len(params["signature"]) > 10 { // //params["signature"] = substr($query, strrpos($query, 'signature=') + 10); // params["signature"] = params["signature"][0:10] //} timestamp := params["timestamp"] nonce := params["nonce_str"] signature := params["signature"] signature = signature + "==" //signature = "VNk9oio0rUMOs1X2j37p9+6o2EyAL3SaLwq2riO0C2FIbTbCZaOrpLSHt6LmgWHHYf50GOQnjZb3oWiTW6LBhF/2ROisEtl78tef6HtMl4mrnDy8BkQGpJS3IL/du+t35OlxeKpBjrpr6ObdZlaA26OZf4uMXRnSv15tvntSi0zM0GA7+dcUCBd4sFPGRgU0qfABiqC7bzzOZFrUpEe7ZZRfXQ2PLkJO0uBQt7vUoqt0fVXsPR+FjR++e1JASg821Gf7+J+Tr73MoAVkRJ0HwJX72HbbffVMNAYF/5cc/sL50WtFJ8JrLj6WAJdesSmeFBrs+tOEMH62b+Wr/mPnXw==" //b, err := c.GetRawData() //if err != nil { // fmt.Println("failed to get request body: " + err.Error()) // return err //} //reqBody := string(b) //获取response body var body interface{} if err = c.ShouldBindBodyWith(&body, binding.JSON); err != nil { //log.Default().Error("should bind body error", zap.Error(err)) fmt.Println("should bind body error: " + err.Error()) return err } byteBody, err := json.Marshal(body) if err != nil { fmt.Println("json.Marshal error: " + err.Error()) return err } reqBody := string(byteBody) //reqBody, _ := json.MarshalToString(body) //JAVA demo //timestamp = "1630905585"; //nonce = "9003323344"; //signature = "tnjIAcEISq/ClrOppv/nojeZnE/pB1wNfQC/hMTME+rQMapWzvs9v1J68ueDpVzs1RW22dNotmUVy2sM6thNFRkaOx4qQGslX6kIttwvlsJsSEIR3qrjdPdUAkbP2KDRLujspxE9X0daJ6BU+rOoJ8p4c6y1/QSOMtDJoO3EABOF4O6RFHR3N7JW8o4qcf7lOOO7D4rlAB2vw6tV8WeG+OEyJ++Q0K3V1oM5uJEIPPuJkb2qlEqVYKiYLyvIdEJ1Z5qMbC9U7rKuHdeTQPl7last/h5nd6WauzDfYPKlAjZBEPYjiDqRv6Dm+4FeNtALoy6Mg7Ruxeq1pJudfj0iKg=="; //reqBody = "{\"payOrderNo\":\"21090611012001970631000463034\",\"merchantOrderNo\":\"CH2021090613190866292\",\"orderInfo\":null,\"merchantNo\":\"822126090640003\",\"termId\":\"47781282\",\"tradeMerchantNo\":\"822126090640003\",\"tradeTermId\":\"47781282\",\"channelId\":\"10000038\",\"currency\":\"156\",\"amount\":1,\"tradeType\":\"PAY\",\"payStatus\":\"S\",\"notifyStatus\":0,\"orderCreateTime\":\"2021-09-06T05:19:43.000+00:00\",\"orderEfficientTime\":\"2021-09-06T05:19:43.000+00:00\",\"extendField\":null,\"payTime\":\"2021-09-06T05:19:43.000+00:00\",\"remark\":\"\",\"noticeNum\":1,\"sign\":null,\"notifyUrl\":null,\"notifyMode\":\"2\",\"payInfo\":\"1#1#ALIPAY#0#2021090622001432581427657317\",\"lklOrderNo\":\"2021090666210003610012\",\"crdFlg\":\"92\",\"payerId1\":\"2088702852632582\",\"payerId2\":\"rob***@126.com\",\"smCrdFlg\":\"01\",\"tradeTime\":\"20210906131943\",\"accountChannelOrderNo\":\"2021090622001432581427657317\",\"actualPayAmount\":1,\"logNo\":\"66210003610012\"}"; preSignData := timestamp +"\n" + nonce + "\n" +reqBody + "\n"; fmt.Println("wangpei test 验证签名1...") fmt.Println("params=");fmt.Println(params) fmt.Println("wangpei test 验证签名2...") fmt.Println("signature="+signature) fmt.Println("wangpei test 验证签名3...") fmt.Println("Authorization2="+authorization) fmt.Println("wangpei test 验证签名4...") fmt.Println("preSignData=" + preSignData) fmt.Println("wangpei test 验证签名5...") //证书 => 公钥 publicKey := cert.PublicKey.(*rsa.PublicKey) //验证签名 bytes, err := base64.StdEncoding.DecodeString(signature) if err != nil { fmt.Println("failed to base64.StdEncoding.DecodeString: " + err.Error()) return err } hashed := sha256.Sum256([]byte(preSignData)) err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], bytes) if err != nil { fmt.Println("failed to VerifyPKCS1v15: " + err.Error()) return err } fmt.Println("wangpei test ok") return nil }