diff --git a/controller/user.go b/controller/user.go index dd46a26..a0bab2c 100644 --- a/controller/user.go +++ b/controller/user.go @@ -319,20 +319,20 @@ func OpenMember(c *gin.Context) { RespJson(c, status.InternalServerError, nil) return } - webPay, err := wxpay.WebPay(orderSn, totalFee, user.WxOpenID, "N", wxpay.WxPayMember, configInfo.NotifyUrl) - if err != nil { - logger.Error(errors.New("WebPay err")) - RespJson(c, status.InternalServerError, nil) - return - } - - //webPay, err := wxpay.HmJsPayUnifiedOrder(orderSn, totalFee, user.WxOpenID, "N", wxpay.WxPayRentCard, configInfo.NotifyUrl) + //webPay, err := wxpay.WebPay(orderSn, totalFee, user.WxOpenID, "N", wxpay.WxPayMember, configInfo.NotifyUrl) //if err != nil { // logger.Error(errors.New("WebPay err")) // RespJson(c, status.InternalServerError, nil) // return //} + webPay, err := wxpay.HmJsPayUnifiedOrder(orderSn, totalFee, user.WxOpenID, "N", wxpay.WxPayRentCard, configInfo.NotifyUrl) + if err != nil { + logger.Error(errors.New("WebPay err")) + RespJson(c, status.InternalServerError, nil) + return + } + RespOK(c, webPay) } diff --git a/lib/wxpay/wx_pay.go b/lib/wxpay/wx_pay.go index 406ea5d..963b2bb 100644 --- a/lib/wxpay/wx_pay.go +++ b/lib/wxpay/wx_pay.go @@ -976,20 +976,22 @@ type HmJsPayUnifiedOrderReq struct { } type HmPayBizContent struct { - Body string `json:"body"` - BuyerId string `json:"buyer_id"` - CreateIp string `json:"create_ip"` - CreateTime string `json:"create_time"` - DiscountInfo struct { - DiscountableAmount float64 `json:"discountable_amount"` - } `json:"discount_info"` - ExpireTime string `json:"expire_time"` - ExtendParams struct { - AccessPartyCode string `json:"access_party_code"` - } `json:"extend_params"` - GoodsDetails []HmPayGoodsDetails `json:"goods_details"` - LimitPay string `json:"limit_pay"` - NotifyUrl string `json:"notify_url"` + Body string `json:"body"` + MerAppId string `json:"mer_app_id"` + //BuyerId string `json:"buyer_id"` + MerBuyerId string `json:"mer_buyer_id"` + CreateIp string `json:"create_ip"` + CreateTime string `json:"create_time"` + //DiscountInfo struct { + // DiscountableAmount float64 `json:"discountable_amount"` + //} `json:"discount_info"` + ExpireTime string `json:"expire_time"` + //ExtendParams struct { + // AccessPartyCode string `json:"access_party_code"` + //} `json:"extend_params"` + //GoodsDetails []HmPayGoodsDetails `json:"goods_details"` + LimitPay string `json:"limit_pay"` + NotifyUrl string `json:"notify_url"` //OperatorId string `json:"operator_id"` OutOrderNo string `json:"out_order_no"` PayType string `json:"pay_type"` @@ -1071,27 +1073,12 @@ func HmJsPayUnifiedOrder(orderId string, totalFee uint32, openId, profitSharing, } biz := HmPayBizContent{ - Body: "会员费", - BuyerId: openId, - CreateIp: clientIp, - CreateTime: strTime, - DiscountInfo: struct { - DiscountableAmount float64 `json:"discountable_amount"` - }{}, - ExpireTime: strExpireTime, - ExtendParams: struct { - AccessPartyCode string `json:"access_party_code"` - }{}, - GoodsDetails: []HmPayGoodsDetails{ - { - Body: "会员", - GoodsId: "1", - GoodsName: "会员服务", - Price: 399, - Quantity: 1, - ShowUrl: "", - }, - }, + Body: "会员费", + MerAppId: WxAppId, + MerBuyerId: openId, + CreateIp: clientIp, + CreateTime: strTime, + ExpireTime: strExpireTime, LimitPay: "NO_CREDIT", NotifyUrl: notifyUrl, OutOrderNo: orderId, @@ -1132,6 +1119,17 @@ func HmJsPayUnifiedOrder(orderId string, totalFee uint32, openId, profitSharing, logger.Errorf("WxUnifiedOrder unified order error %#v", err) return nil, err } + + signContent, err := ToSignContent(unifiedOrderResp) + if err != nil { + logger.Error("ToSignContent err:", err) + return nil, err + } + err = HmVerifySha1Rsa(signContent, unifiedOrderResp.Sign) + if err != nil { + logger.Error("HmVerifySha1Rsa err:", err) + return nil, err + } //fmt.Println("unifiedOrderResp:", unifiedOrderResp.Data) var hmPayDetail HmPayUnifiedOrderDetail err = json.Unmarshal([]byte(unifiedOrderResp.Data), &hmPayDetail) @@ -1152,6 +1150,34 @@ func HmJsPayUnifiedOrder(orderId string, totalFee uint32, openId, profitSharing, return &hmPayData, nil } +func ToSignContent(s interface{}) (string, error) { + m, err := struct2Map(s) + if err != nil { + logger.Error(err) + return "", err + } + + delete(m, "sign") + var signData []string + for k, v := range m { + if k == "openid" { + fmt.Println(k, ":", v) + } + if v != "" && v != "0" { + signData = append(signData, fmt.Sprintf("%s=%s", k, v)) + } + } + + sort.Strings(signData) + + //signDataJson2, _ := json.MarshalIndent(&signData, "", " ") + //fmt.Println("signDataJson2", string(signDataJson2)) + + signStr := strings.Join(signData, "&") + + return signStr, nil +} + func GenHmPaySign(m map[string]string) (string, error) { delete(m, "sign") var signData []string @@ -1203,8 +1229,8 @@ func Sha1withRsa(signContent string) (string, error) { } func ParsePrivateKey() (*rsa.PrivateKey, error) { - fp := "/Users/li/mh/mh_server/pack/configs/hm_pay/private_key.pem" - //fp := "./configs/hm_pay/private_key.pem" + //fp := "/Users/li/mh/mh_server/pack/configs/hm_pay/private_key.pem" + fp := "./configs/hm_pay/private_key.pem" privateKey, err := ioutil.ReadFile(fp) if err != nil { logger.Error("read file err:", err) @@ -1227,21 +1253,67 @@ func ParsePrivateKey() (*rsa.PrivateKey, error) { } const ( - PEM_BEGIN = "-----BEGIN RSA PRIVATE KEY-----\n" - PEM_END = "\n-----END RSA PRIVATE KEY-----" + PemBegin = "-----BEGIN RSA PRIVATE KEY-----\n" + PemEnd = "\n-----END RSA PRIVATE KEY-----" ) func FormatPrivateKey(privateKey string) string { //privateKey = strings.Trim(privateKey, "\n") - if !strings.HasPrefix(privateKey, PEM_BEGIN) { - privateKey = PEM_BEGIN + privateKey + if !strings.HasPrefix(privateKey, PemBegin) { + privateKey = PemBegin + privateKey } - if !strings.HasSuffix(privateKey, PEM_END) { - privateKey = privateKey + PEM_END + if !strings.HasSuffix(privateKey, PemEnd) { + privateKey = privateKey + PemEnd } return privateKey } +const HmPubKey = `MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDzGVH0Fxpb2M48U1BWr6lpNs2W3VHqtjO8X5RqWjtTwpQVKo8dqaiAGxVbsdnefPpsbI5l9rKquRAOJhWFU07hxSUgXZOk55QQmll03MBgRDXLgxyKfycLLQwhsCJAzDIWC7IWgok/RHV9m9AV2GbQxWBl+7iDE4prcbpgG8Z0HwIDAQAB` + +func HmVerifySha1Rsa(signContent, signBase string) error { + //fp := "/Users/li/mh/mh_server/pack/configs/hm_pay/public_key.pme" + //publicKeyString, err := ioutil.ReadFile(fp) + //if err != nil { + // fmt.Println("read file err:", err) + // return err + //} + + block, _ := pem.Decode([]byte(FormatPrivateKey(HmPubKey))) + if block == nil { + fmt.Println("decode block is nil") + return errors.New("decode block is nil") + } + publicKey, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + fmt.Println("public key err:", err) + return err + } + + if publicKey == nil { + fmt.Println("public key nil:") + return err + } + hash := crypto.SHA1 + shaNew := hash.New() + shaNew.Write([]byte(signContent)) + hashed := shaNew.Sum(nil) + + sign, err := b64.StdEncoding.DecodeString(signBase) + if err != nil { + fmt.Println("sign decode err:", err) + return err + } + + err = rsa.VerifyPKCS1v15(publicKey.(*rsa.PublicKey), hash, hashed, sign) + if err != nil { + fmt.Println("verify err:", err) + return err + } + //logger.Error("验签成功") + fmt.Println("验签成功") + return nil +} + func VerifySha1Rsa(signContent, signBase string) error { fp := "/Users/li/mh/mh_server/pack/configs/hm_pay/public_key.pme" publicKeyString, err := ioutil.ReadFile(fp) @@ -1251,6 +1323,10 @@ func VerifySha1Rsa(signContent, signBase string) error { } block, _ := pem.Decode([]byte(publicKeyString)) + if block == nil { + fmt.Println("decode block is nil") + return errors.New("decode block is nil") + } publicKey, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { fmt.Println("public key err:", err)