fix:
This commit is contained in:
parent
759bbe0646
commit
564c9a5341
|
@ -497,7 +497,14 @@ func RentCardOrderCreate(c *gin.Context) {
|
||||||
RespJson(c, status.InternalServerError, nil)
|
RespJson(c, status.InternalServerError, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
webPay, err := wxpay.WebPay(order.OrderSn, req.Price, user.WxOpenID, "N", wxpay.WxPayRentCard, configInfo.NotifyUrl)
|
//webPay, err := wxpay.WebPay(order.OrderSn, req.Price, user.WxOpenID, "N", wxpay.WxPayRentCard, configInfo.NotifyUrl)
|
||||||
|
//if err != nil {
|
||||||
|
// logger.Error(errors.New("WebPay err"))
|
||||||
|
// RespJson(c, status.InternalServerError, nil)
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
|
webPay, err := wxpay.HmJsPayUnifiedOrder(order.OrderSn, req.Price, user.WxOpenID, "N", wxpay.WxPayRentCard, configInfo.NotifyUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(errors.New("WebPay err"))
|
logger.Error(errors.New("WebPay err"))
|
||||||
RespJson(c, status.InternalServerError, nil)
|
RespJson(c, status.InternalServerError, nil)
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -16,6 +16,7 @@ require (
|
||||||
github.com/qiniu/x v7.0.8+incompatible // indirect
|
github.com/qiniu/x v7.0.8+incompatible // indirect
|
||||||
github.com/rs/zerolog v1.23.0
|
github.com/rs/zerolog v1.23.0
|
||||||
github.com/satori/go.uuid v1.2.0 // indirect
|
github.com/satori/go.uuid v1.2.0 // indirect
|
||||||
|
github.com/shopspring/decimal v1.3.1
|
||||||
github.com/spf13/cobra v1.1.3
|
github.com/spf13/cobra v1.1.3
|
||||||
github.com/spf13/viper v1.7.1
|
github.com/spf13/viper v1.7.1
|
||||||
github.com/wechatpay-apiv3/wechatpay-go v0.2.6
|
github.com/wechatpay-apiv3/wechatpay-go v0.2.6
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -227,6 +227,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
|
||||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
|
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||||
|
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
|
|
|
@ -3,9 +3,15 @@ package wxpay
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"crypto"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
b64 "encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"encoding/pem"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -21,7 +27,7 @@ import (
|
||||||
mathrand "math/rand"
|
mathrand "math/rand"
|
||||||
"mh-server/config"
|
"mh-server/config"
|
||||||
"mh-server/lib/utils"
|
"mh-server/lib/utils"
|
||||||
//"mh-server/model"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -50,6 +56,11 @@ const (
|
||||||
//NotifyUrl = "https://dev.switch.deovo.com:8004/api/v1/wxpay/notice" // 测试
|
//NotifyUrl = "https://dev.switch.deovo.com:8004/api/v1/wxpay/notice" // 测试
|
||||||
|
|
||||||
wxPayOrderRefundsUrl = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds"
|
wxPayOrderRefundsUrl = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds"
|
||||||
|
|
||||||
|
HmPayMerchantId = "664403000030115"
|
||||||
|
HmWxSubMerchantId = "546017470"
|
||||||
|
//HmPayUnifiedOrderUrl = "https://hmpay.sandpay.com.cn/gateway/api"
|
||||||
|
HmPayUnifiedOrderUrl = "https://hmpay.sandpay.com.cn/gateway/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
//web 微信支付
|
//web 微信支付
|
||||||
|
@ -300,6 +311,11 @@ type T struct {
|
||||||
CouponId3 string `json:"coupon_id_3"`
|
CouponId3 string `json:"coupon_id_3"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
DateTimeFormat = "2006-01-02"
|
||||||
|
TimeFormat = "2006-01-02 15:04:05"
|
||||||
|
)
|
||||||
|
|
||||||
//type T struct {
|
//type T struct {
|
||||||
// Xml struct {
|
// Xml struct {
|
||||||
// Appid string `json:"appid"`
|
// Appid string `json:"appid"`
|
||||||
|
@ -419,9 +435,9 @@ func struct2Map(r interface{}) (s map[string]string, err error) {
|
||||||
case string:
|
case string:
|
||||||
result[k] = v2
|
result[k] = v2
|
||||||
case uint, int8, uint8, int, int16, uint16, int32, uint32, int64, uint64:
|
case uint, int8, uint8, int, int16, uint16, int32, uint32, int64, uint64:
|
||||||
result[k] = fmt.Sprintf("%d", v2)
|
result[k] = fmt.Sprintf("%d", v)
|
||||||
case float32, float64:
|
case float32, float64:
|
||||||
result[k] = fmt.Sprintf("%.0f", v2)
|
result[k] = fmt.Sprintf("%.02f", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,3 +956,392 @@ func newHttpClient(certFile, keyFile string) (*http.Client, error) {
|
||||||
|
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HmPayPublicPara struct {
|
||||||
|
AppId string `json:"app_id"`
|
||||||
|
//SubAppId string `json:"sub_app_id"`
|
||||||
|
Method string `json:"method"`
|
||||||
|
Charset string `json:"charset"`
|
||||||
|
//SignType string `json:"sign_type"`
|
||||||
|
Sign string `json:"sign"`
|
||||||
|
Timestamp string `json:"timestamp"`
|
||||||
|
Nonce string `json:"nonce"`
|
||||||
|
//Version string `json:"version"`
|
||||||
|
//Format string `json:"format"`
|
||||||
|
BizContent string `json:"biz_content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HmJsPayUnifiedOrderReq struct {
|
||||||
|
CreateIp string `json:"create_ip"`
|
||||||
|
CreateTime string `json:"create_time"`
|
||||||
|
//ExpireTime string `json:"expire_time"`
|
||||||
|
//BankWay string `json:"bank_way"`
|
||||||
|
PayWay string `json:"pay_way"`
|
||||||
|
PayType string `json:"pay_type"`
|
||||||
|
MerAppId string `json:"mer_app_id"`
|
||||||
|
MerBuyerId string `json:"mer_buyer_id"`
|
||||||
|
//BuyerId string `json:"buyer_id"`
|
||||||
|
TotalAmount float64 `json:"total_amount"`
|
||||||
|
OutOrderNo string `json:"out_order_no"`
|
||||||
|
//scene_info
|
||||||
|
Body string `json:"body"`
|
||||||
|
StoreId string `json:"store_id"`
|
||||||
|
//TerminalId string `json:"terminal_id"`
|
||||||
|
//OperatorId string `json:"operator_id"`
|
||||||
|
NotifyUrl string `json:"notify_url"`
|
||||||
|
//RedirectUrl string `json:"redirect_url"`
|
||||||
|
//LimitPay string `json:"limit_pay"`
|
||||||
|
//ReqReserved string `json:"req_reserved"`
|
||||||
|
|
||||||
|
//extend_params
|
||||||
|
//discount_info
|
||||||
|
//goods_details
|
||||||
|
//device_info
|
||||||
|
//ext_user_info
|
||||||
|
|
||||||
|
HmPayPublicPara
|
||||||
|
}
|
||||||
|
|
||||||
|
//hm 微信支付
|
||||||
|
func HmJsPayUnifiedOrder(orderId string, totalFee uint32, openId, profitSharing, attach, notifyUrl string) (*Sextuple, error) {
|
||||||
|
now := time.Now().Local()
|
||||||
|
strTime := fmt.Sprintf("%04d%02d%02d%02d%02d%02d", now.Year(), now.Month(), now.Day(), now.Hour(),
|
||||||
|
now.Minute(), now.Second())
|
||||||
|
nonce := utils.GenRandStr(NonceStringLength)
|
||||||
|
|
||||||
|
if notifyUrl == "" {
|
||||||
|
logger.Error("NotifyUrl is null")
|
||||||
|
return nil, errors.New("NotifyUrl is null")
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("MchId:", config.AppConfig.WxMchID)
|
||||||
|
logger.Info("AppId:", config.AppConfig.WxAppId)
|
||||||
|
logger.Info("MchSecret:", config.AppConfig.WxMchSecret)
|
||||||
|
|
||||||
|
//unifiedOrderReq := UnifiedOrderReq{
|
||||||
|
// DeviceInfo: "WEB",
|
||||||
|
// NonceStr: nonce,
|
||||||
|
// Sign: "",
|
||||||
|
// SignType: "MD5",
|
||||||
|
// Body: "创建订单",
|
||||||
|
// OutTradeNo: orderId,
|
||||||
|
// FeeType: "CNY",
|
||||||
|
// TotalFee: strconv.Itoa(int(totalFee)),
|
||||||
|
// //SpbillCreateIp: config.AppConfig.IP,
|
||||||
|
// SpbillCreateIp: clientIp,
|
||||||
|
// //NotifyUrl: "https://" + config.AppConfig.Domain + config.AppConfig.WxPayNotifyUrl,
|
||||||
|
// //NotifyUrl: "https://" + domain + wxPayNotifyUrl,
|
||||||
|
// //NotifyUrl: configInfo.NotifyUrl,
|
||||||
|
// NotifyUrl: notifyUrl,
|
||||||
|
//
|
||||||
|
// TradeType: "JSAPI",
|
||||||
|
// MchId: config.AppConfig.WxMchID,
|
||||||
|
// AppId: config.AppConfig.WxAppId,
|
||||||
|
// OpenId: openId,
|
||||||
|
// TimeStart: strTime,
|
||||||
|
// ProfitSharing: profitSharing,
|
||||||
|
// Attach: attach,
|
||||||
|
//}
|
||||||
|
|
||||||
|
unifiedOrderReq := HmJsPayUnifiedOrderReq{
|
||||||
|
CreateIp: clientIp,
|
||||||
|
CreateTime: strTime,
|
||||||
|
//ExpireTime: "",
|
||||||
|
//BankWay: "",
|
||||||
|
PayWay: "WECHAT",
|
||||||
|
PayType: "JSAPI",
|
||||||
|
MerAppId: config.AppConfig.WxAppId,
|
||||||
|
MerBuyerId: openId,
|
||||||
|
//BuyerId: "",
|
||||||
|
TotalAmount: float64(totalFee) / 100,
|
||||||
|
OutOrderNo: orderId,
|
||||||
|
Body: "会员",
|
||||||
|
StoreId: "100001",
|
||||||
|
//TerminalId: "",
|
||||||
|
//OperatorId: "",
|
||||||
|
NotifyUrl: notifyUrl,
|
||||||
|
//RedirectUrl: "",
|
||||||
|
//LimitPay: "",
|
||||||
|
//ReqReserved: "",
|
||||||
|
}
|
||||||
|
publicPara := HmPayPublicPara{
|
||||||
|
AppId: HmPayMerchantId,
|
||||||
|
//SubAppId: HmWxSubMerchantId,
|
||||||
|
Method: "trade.create",
|
||||||
|
Charset: "UTF-8",
|
||||||
|
//SignType: "",
|
||||||
|
Sign: "",
|
||||||
|
Timestamp: now.Format(TimeFormat),
|
||||||
|
Nonce: nonce,
|
||||||
|
//Version: "",
|
||||||
|
//Format: "",
|
||||||
|
BizContent: fmt.Sprintf(`{"attach":"%s"}`, attach),
|
||||||
|
}
|
||||||
|
unifiedOrderReq.HmPayPublicPara = publicPara
|
||||||
|
|
||||||
|
//fmt.Println("OutTradeNo:", unifiedOrderReq.OutTradeNo)
|
||||||
|
fmt.Println("OutOrderNo:", unifiedOrderReq.OutOrderNo)
|
||||||
|
|
||||||
|
m, err := struct2Map(unifiedOrderReq)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//mJson, _ := json.MarshalIndent(&m, "", " ")
|
||||||
|
//fmt.Println("mJson:", string(mJson))
|
||||||
|
|
||||||
|
sign, err := GenHmPaySign(m)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//unifiedOrderReq.Sign = strings.ToUpper(sign)
|
||||||
|
unifiedOrderReq.Sign = sign
|
||||||
|
|
||||||
|
//unifiedOrderReqJson, _ := json.Marshal(&unifiedOrderReq)
|
||||||
|
//fmt.Println("unifiedOrderReqJson:", string(unifiedOrderReqJson))
|
||||||
|
|
||||||
|
unifiedOrderResp, err := HmPayUnifiedOrder(unifiedOrderReq)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("WxUnifiedOrder unified order error %#v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var sextuple Sextuple
|
||||||
|
sextuple.NonceStr = unifiedOrderResp.NonceStr
|
||||||
|
sextuple.AppId = unifiedOrderResp.AppId
|
||||||
|
sextuple.Timestamp = fmt.Sprintf("%d", now.Unix())
|
||||||
|
sextuple.Package = "prepay_id=" + unifiedOrderResp.PrepayId
|
||||||
|
sextuple.SignType = "MD5"
|
||||||
|
//logger.Debugf("unified order sextuple: %#v", sextuple)
|
||||||
|
|
||||||
|
m, err = struct2Map(sextuple)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("struct to map error %#v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sextuple.PaySign, err = GenWxPaySign(m, config.AppConfig.WxMchSecret)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("GenWxPaySign gen response sign error: %#v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &sextuple, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//func RsaSign(signContent string, privateKey string, hash crypto.Hash) string {
|
||||||
|
// shaNew := hash.New()
|
||||||
|
// shaNew.Write([]byte(signContent))
|
||||||
|
// hashed := shaNew.Sum(nil)
|
||||||
|
// priKey, err := ParsePrivateKey(privateKey)
|
||||||
|
// if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// signature, err := rsa.SignPKCS1v15(rand.Reader, priKey, hash, hashed)
|
||||||
|
// if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
// return base64.StdEncoding.EncodeToString(signature)
|
||||||
|
|
||||||
|
//digest := sha256.Sum256(data)
|
||||||
|
//
|
||||||
|
//signature, signErr := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, digest[:])
|
||||||
|
//
|
||||||
|
//if signErr != nil {
|
||||||
|
//t.Errorf("Could not sign message:%s", signErr.Error())
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// just to check that we can survive to and from b64
|
||||||
|
//b64sig := base64.StdEncoding.EncodeToString(signature)
|
||||||
|
//
|
||||||
|
//decodedSignature, _ := base64.StdEncoding.DecodeString(b64sig)
|
||||||
|
//}
|
||||||
|
|
||||||
|
func GenHmPaySign(m map[string]string) (string, error) {
|
||||||
|
delete(m, "sign")
|
||||||
|
var signData []string
|
||||||
|
for k, v := range m {
|
||||||
|
if k == "openid" {
|
||||||
|
fmt.Println(k, ":", v)
|
||||||
|
}
|
||||||
|
//fmt.Println("k:", k)
|
||||||
|
//fmt.Println("v:", v)
|
||||||
|
if v != "" && v != "0" {
|
||||||
|
signData = append(signData, fmt.Sprintf("%s=%s", k, v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
signDataJson, _ := json.MarshalIndent(&signData, "", " ")
|
||||||
|
fmt.Println("signDataJson1", string(signDataJson))
|
||||||
|
|
||||||
|
sort.Strings(signData)
|
||||||
|
|
||||||
|
signDataJson2, _ := json.MarshalIndent(&signData, "", " ")
|
||||||
|
fmt.Println("signDataJson2", string(signDataJson2))
|
||||||
|
|
||||||
|
signStr := strings.Join(signData, "&")
|
||||||
|
//signStr = signStr + "&key=" + payKey
|
||||||
|
logger.Info("签字符串1 :", signStr)
|
||||||
|
//c := md5.New()
|
||||||
|
//_, err := c.Write([]byte(signStr))
|
||||||
|
//if err != nil {
|
||||||
|
// logger.Error(err)
|
||||||
|
// return "", err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//signByte := c.Sum(nil)
|
||||||
|
//
|
||||||
|
//return fmt.Sprintf("%x", signByte), nil
|
||||||
|
signature, err := Sha256withRsa(signStr)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("signature err:", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return signature, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sha256withRsa(signContent string) (string, error) {
|
||||||
|
hash := crypto.SHA256
|
||||||
|
shaNew := hash.New()
|
||||||
|
shaNew.Write([]byte(signContent))
|
||||||
|
hashed := shaNew.Sum(nil)
|
||||||
|
priKey, err := ParsePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("parse err:", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
signature, err := rsa.SignPKCS1v15(rand.Reader, priKey, hash, hashed)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("sign err:", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return b64.StdEncoding.EncodeToString(signature), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParsePrivateKey() (*rsa.PrivateKey, error) {
|
||||||
|
fp := "/Users/li/mh/mh_server/pack/configs/hm_pay/private_key.pem"
|
||||||
|
privateKey, err := ioutil.ReadFile(fp)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("read file err:", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
block, _ := pem.Decode([]byte(privateKey))
|
||||||
|
if block == nil {
|
||||||
|
return nil, errors.New("私钥信息错误!")
|
||||||
|
}
|
||||||
|
//priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||||
|
priKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if priKey == nil {
|
||||||
|
return nil, errors.New("pri key is nil")
|
||||||
|
}
|
||||||
|
return priKey.(*rsa.PrivateKey), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
PEM_BEGIN = "-----BEGIN RSA PRIVATE KEY-----\n"
|
||||||
|
PEM_END = "\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.HasSuffix(privateKey, PEM_END) {
|
||||||
|
privateKey = privateKey + PEM_END
|
||||||
|
}
|
||||||
|
return privateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func VerifySha256Rsa(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(publicKeyString))
|
||||||
|
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.SHA256
|
||||||
|
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), crypto.SHA256, hashed, sign)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("verify err:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//logger.Error("验签成功")
|
||||||
|
fmt.Println("验签成功")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmPayUnifiedOrder(r HmJsPayUnifiedOrderReq) (UnifiedOrderResp, error) {
|
||||||
|
var payResp UnifiedOrderResp
|
||||||
|
|
||||||
|
data, err := json.Marshal(r)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
return payResp, err
|
||||||
|
}
|
||||||
|
fmt.Println("data json:", string(data))
|
||||||
|
client := http.Client{}
|
||||||
|
req, err := http.NewRequest("POST", HmPayUnifiedOrderUrl, bytes.NewBuffer(data))
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
return payResp, err
|
||||||
|
}
|
||||||
|
//req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
return payResp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
return payResp, err
|
||||||
|
}
|
||||||
|
fmt.Println("body:", string(body))
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
//err = xml.Unmarshal(body, &payResp)
|
||||||
|
//if err != nil {
|
||||||
|
// logger.Error(err)
|
||||||
|
// return payResp, err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//if payResp.ReturnCode != "SUCCESS" {
|
||||||
|
// return payResp, errors.New(payResp.ReturnMsg)
|
||||||
|
//}
|
||||||
|
|
||||||
|
return payResp, nil
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/codinl/go-logger"
|
"github.com/codinl/go-logger"
|
||||||
"mh-server/model"
|
"mh-server/model"
|
||||||
|
|
||||||
|
//"mh-server/model"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -48,3 +50,12 @@ func TestWxPayTransactionOrderClose(t *testing.T) {
|
||||||
|
|
||||||
WxPayTransactionOrderClose("100000", "1609877389")
|
WxPayTransactionOrderClose("100000", "1609877389")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHmJsPayUnifiedOrder(t *testing.T) {
|
||||||
|
order, err := HmJsPayUnifiedOrder("84FDC15BCC", 2, "ohuHh4riVVPxwKHrYHsWwZRpxVMk", "N", WxPayRentCard, "https://dev.switch.deovo.com:8004/api/v1/wxpay/notice")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("err:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("order:", order)
|
||||||
|
}
|
||||||
|
|
|
@ -2,10 +2,19 @@ package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto"
|
||||||
|
cryrand "crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha1"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"math/rand"
|
||||||
"mh-server/lib/auth"
|
"mh-server/lib/auth"
|
||||||
"mh-server/lib/utils"
|
"mh-server/lib/utils"
|
||||||
"mh-server/lib/wxpay"
|
"mh-server/lib/wxpay"
|
||||||
|
@ -19,7 +28,7 @@ import (
|
||||||
"github.com/codinl/go-logger"
|
"github.com/codinl/go-logger"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/xuri/excelize/v2"
|
"github.com/xuri/excelize/v2"
|
||||||
"math/rand"
|
//"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -2060,3 +2069,55 @@ func TestNewUser(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPasKey(t *testing.T) {
|
||||||
|
d := `{"hm":10}`
|
||||||
|
|
||||||
|
p := "/Users/li/mh/mh_server/pack/configs/hm_pay/private_key.pem"
|
||||||
|
readFile, err := ioutil.ReadFile(p)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("read file err:", err)
|
||||||
|
}
|
||||||
|
block, _ := pem.Decode(readFile)
|
||||||
|
priKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||||
|
if err != nil || priKey == nil {
|
||||||
|
logger.Error("parse private err:", err)
|
||||||
|
}
|
||||||
|
//x509.SHA256WithRSA
|
||||||
|
h := sha1.New()
|
||||||
|
h.Write([]byte(d))
|
||||||
|
sum := h.Sum(nil)
|
||||||
|
signPKCS1v15, err := rsa.SignPKCS1v15(cryrand.Reader, priKey.(*rsa.PrivateKey), crypto.SHA1, sum[:])
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("sign err:", err)
|
||||||
|
}
|
||||||
|
encodeToString := base64.StdEncoding.EncodeToString(signPKCS1v15)
|
||||||
|
|
||||||
|
fmt.Println("key:", encodeToString)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSha256withRsa(t *testing.T) {
|
||||||
|
d := `{"hm":10}`
|
||||||
|
|
||||||
|
withRsa, err := wxpay.Sha256withRsa(d)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("err:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("sign:", withRsa)
|
||||||
|
|
||||||
|
err = wxpay.VerifySha256Rsa(d, withRsa)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("verify rsa err:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHmJsPayUnifiedOrder(t *testing.T) {
|
||||||
|
order, err := wxpay.HmJsPayUnifiedOrder("84FDC15BCC", 2, "ohuHh4riVVPxwKHrYHsWwZRpxVMk", "N", wxpay.WxPayRentCard, "https://dev.switch.deovo.com:8004/api/v1/wxpay/notice")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("err:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("order:", order)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user