github.com/chanxuehong/wechat@v0.0.0-20230222024006-36f0325263cd/mch/core/sign.go (about)

     1  package core
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"crypto/md5"
     7  	"crypto/sha1"
     8  	"encoding/hex"
     9  	"hash"
    10  	"sort"
    11  )
    12  
    13  // Sign 微信支付签名.
    14  //
    15  //	params: 待签名的参数集合
    16  //	apiKey: api密钥
    17  //	fn:     func() hash.Hash, 如果为 nil 则默认用 md5.New
    18  func Sign(params map[string]string, apiKey string, fn func() hash.Hash) string {
    19  	if fn == nil {
    20  		fn = md5.New
    21  	}
    22  	return Sign2(params, apiKey, fn())
    23  }
    24  
    25  // Sign2 微信支付签名.
    26  //
    27  //	params: 待签名的参数集合
    28  //	apiKey: api密钥
    29  //	h:      hash.Hash, 如果为 nil 则默认用 md5.New(), 特别注意 h 必须是 initial state.
    30  func Sign2(params map[string]string, apiKey string, h hash.Hash) string {
    31  	if h == nil {
    32  		h = md5.New()
    33  	}
    34  
    35  	keys := make([]string, 0, len(params))
    36  	for k := range params {
    37  		if k == "sign" {
    38  			continue
    39  		}
    40  		keys = append(keys, k)
    41  	}
    42  	sort.Strings(keys)
    43  
    44  	bufw := bufio.NewWriterSize(h, 128)
    45  	for _, k := range keys {
    46  		v := params[k]
    47  		if v == "" {
    48  			continue
    49  		}
    50  		bufw.WriteString(k)
    51  		bufw.WriteByte('=')
    52  		bufw.WriteString(v)
    53  		bufw.WriteByte('&')
    54  	}
    55  	bufw.WriteString("key=")
    56  	bufw.WriteString(apiKey)
    57  	bufw.Flush()
    58  
    59  	signature := make([]byte, hex.EncodedLen(h.Size()))
    60  	hex.Encode(signature, h.Sum(nil))
    61  	return string(bytes.ToUpper(signature))
    62  }
    63  
    64  // jssdk 支付签名, signType 只支持 "MD5", "SHA1", 传入其他的值会 panic.
    65  func JsapiSign(appId, timeStamp, nonceStr, packageStr, signType string, apiKey string) string {
    66  	var h hash.Hash
    67  	switch signType {
    68  	case SignType_MD5:
    69  		h = md5.New()
    70  	case SignType_SHA1:
    71  		h = sha1.New()
    72  	default:
    73  		panic("unsupported signType")
    74  	}
    75  	bufw := bufio.NewWriterSize(h, 128)
    76  
    77  	// appId
    78  	// nonceStr
    79  	// package
    80  	// signType
    81  	// timeStamp
    82  	bufw.WriteString("appId=")
    83  	bufw.WriteString(appId)
    84  	bufw.WriteString("&nonceStr=")
    85  	bufw.WriteString(nonceStr)
    86  	bufw.WriteString("&package=")
    87  	bufw.WriteString(packageStr)
    88  	bufw.WriteString("&signType=")
    89  	bufw.WriteString(signType)
    90  	bufw.WriteString("&timeStamp=")
    91  	bufw.WriteString(timeStamp)
    92  	bufw.WriteString("&key=")
    93  	bufw.WriteString(apiKey)
    94  
    95  	bufw.Flush()
    96  	signature := make([]byte, hex.EncodedLen(h.Size()))
    97  	hex.Encode(signature, h.Sum(nil))
    98  	return string(bytes.ToUpper(signature))
    99  }
   100  
   101  // EditAddressSign 收货地址共享接口签名
   102  func EditAddressSign(appId, url, timestamp, nonceStr, accessToken string) string {
   103  	h := sha1.New()
   104  	bufw := bufio.NewWriterSize(h, 128)
   105  
   106  	// accesstoken
   107  	// appid
   108  	// noncestr
   109  	// timestamp
   110  	// url
   111  	bufw.WriteString("accesstoken=")
   112  	bufw.WriteString(accessToken)
   113  	bufw.WriteString("&appid=")
   114  	bufw.WriteString(appId)
   115  	bufw.WriteString("&noncestr=")
   116  	bufw.WriteString(nonceStr)
   117  	bufw.WriteString("&timestamp=")
   118  	bufw.WriteString(timestamp)
   119  	bufw.WriteString("&url=")
   120  	bufw.WriteString(url)
   121  
   122  	bufw.Flush()
   123  	return hex.EncodeToString(h.Sum(nil))
   124  }