entrust.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // 委托
  2. package unionpay
  3. import (
  4. "bytes"
  5. "crypto/rsa"
  6. "crypto/sha256"
  7. "crypto/x509"
  8. "encoding/base64"
  9. "encoding/hex"
  10. "encoding/json"
  11. "fmt"
  12. "net/url"
  13. "sort"
  14. "git.chuangxin1.com/cx/util/binding"
  15. "git.chuangxin1.com/cx/util"
  16. )
  17. // MerchantInfo 商家信息
  18. type MerchantInfo struct {
  19. MerID string // 商户代码
  20. OrderID string // 商户订单号,8-32位数字字母,不能含“-”或“_”
  21. TxnTime string // 订单发送时间,格式为YYYYMMDDhhmmss,取北京时间
  22. }
  23. // CustomerInfo 客户信息
  24. type CustomerInfo struct {
  25. CardNo string `form:"cardNo" json:"cardNo" xml:"cardNo"` // 卡号
  26. Phone string `form:"phone" json:"phone" xml:"phone"` // 手机号
  27. CertifTp string `form:"certifTp" json:"certifTp" xml:"certifTp"` // 证件类型, 01 - 身份证
  28. CertifID string `form:"certifId" json:"certifId" xml:"certifId"` // 证件号,15位身份证不校验尾号,18位会校验尾号
  29. CustomerName string `form:"customerNm" json:"customerNm" xml:"customerNm"` // 姓名
  30. Cvn2 string `form:"cvn2" json:"cvn2" xml:"cvn2"` // 信用卡安全码
  31. Expired string `form:"expired" json:"expired" xml:"expired"` // 有效期,YYMM格式,持卡人卡面印的是MMYY的,请注意代码设置倒一下
  32. }
  33. // ReqRes 请求返回
  34. type ReqRes struct {
  35. TxnType string `form:"txnType" json:"txnType" xml:"txnType"`
  36. RespCode string `form:"respCode" json:"respCode" xml:"respCode"`
  37. ChannelType string `form:"channelType" json:"channelType" xml:"channelType"`
  38. MerID string `form:"merId" json:"merId" xml:"merId"`
  39. TxnSubType string `form:"txnSubType" json:"txnSubType" xml:"txnSubType"`
  40. CustomerInfo string `form:"customerInfo" json:"customerInfo" xml:"customerInfo"`
  41. Version string `form:"version" json:"version" xml:"version"`
  42. SignPubKeyCert string `form:"signPubKeyCert" json:"signPubKeyCert" xml:"signPubKeyCert"`
  43. SignMethod string `form:"signMethod" json:"signMethod" xml:"signMethod"`
  44. AccNo string `form:"accNo" json:"accNo" xml:"accNo"`
  45. CertID string `form:"certId" json:"certId" xml:"certId"`
  46. Encoding string `form:"encoding" json:"encoding" xml:"encoding"`
  47. RespMsg string `form:"respMsg" json:"respMsg" xml:"respMsg"`
  48. BizType string `form:"bizType" json:"bizType" xml:"bizType"`
  49. EncryptCertID string `form:"encryptCertId" json:"encryptCertId" xml:"encryptCertId"`
  50. Signature string `form:"signature" json:"signature" xml:"signature"`
  51. OrderID string `form:"orderId" json:"orderId" xml:"orderId"`
  52. TxnTime string `form:"txnTime" json:"txnTime" xml:"txnTime"`
  53. AccessType int `form:"accessType" json:"accessType" xml:"accessType"`
  54. }
  55. // Sign 签名
  56. // encryptCert 公钥证书路径
  57. // signCert 签名证书路径
  58. func Sign(encryptCert, signCert string, mi MerchantInfo, ci CustomerInfo) (err error) {
  59. var (
  60. cert = &x509.Certificate{}
  61. priveKey = &rsa.PrivateKey{}
  62. accNo []byte
  63. )
  64. cert, _, err = GetCertificate(encryptCert)
  65. if err != nil {
  66. return
  67. }
  68. priveKey, err = GetPrivateKey(signCert)
  69. if err != nil {
  70. return
  71. }
  72. args := url.Values{}
  73. args.Add("version", "5.1.0") // 版本号
  74. args.Add("encoding", "utf-8") // 编码方式
  75. args.Add("signMethod", "01") // 签名方法
  76. args.Add("txnType", "72") // 交易类型
  77. args.Add("txnSubType", "11") // 交易子类
  78. args.Add("bizType", "000501") // 业务类型
  79. args.Add("accessType", "0") // 接入类型
  80. args.Add("channelType", "07") // 渠道类型
  81. args.Add("certId", cert.SerialNumber.String()) // 证书序列号
  82. args.Add("encryptCertId", cert.SerialNumber.String()) // 验签证书序列号
  83. args.Add("merId", mi.MerID) // 商户代码
  84. args.Add("orderId", mi.OrderID) // 商户订单号,8-32位数字字母,不能含“-”或“_”
  85. args.Add("txnTime", mi.TxnTime) // 订单发送时间,格式为YYYYMMDDhhmmss,取北京时间
  86. publickey := cert.PublicKey.(*rsa.PublicKey)
  87. accNo, err = RSAEncrypt(publickey, []byte(ci.CardNo))
  88. if err != nil {
  89. return
  90. }
  91. args.Add("accNo", base64.StdEncoding.EncodeToString(accNo)) // 卡号,敏感信息加密方式
  92. fmt.Println("CardNo", ci.CardNo)
  93. var cardNo []byte
  94. cardNo, err = RSADecrypt(priveKey, accNo)
  95. fmt.Println("CardNo", ci.CardNo)
  96. fmt.Println("De CardNo", string(cardNo))
  97. // 持卡人身份信息,敏感信息加密方式
  98. var phone []byte
  99. phone, err = RSAEncrypt(publickey, []byte(ci.Phone))
  100. if err != nil {
  101. return
  102. }
  103. encryptedInfo := `phone=` + base64.StdEncoding.EncodeToString(phone)
  104. if len(ci.Cvn2) > 0 {
  105. var cvn2 []byte
  106. cvn2, err = RSAEncrypt(publickey, []byte(ci.Cvn2))
  107. if err != nil {
  108. return
  109. }
  110. encryptedInfo += `cvn2=` + base64.StdEncoding.EncodeToString(cvn2)
  111. }
  112. if len(ci.Expired) > 0 {
  113. var expired []byte
  114. expired, err = RSAEncrypt(publickey, []byte(ci.Cvn2))
  115. if err != nil {
  116. return
  117. }
  118. encryptedInfo += `expired=` + base64.StdEncoding.EncodeToString(expired)
  119. }
  120. kvs := `encryptedInfo=` + encryptedInfo
  121. kvs += `&certifTp=` + ci.CertifTp
  122. kvs += `&certifId=` + ci.CertifID
  123. kvs += `&customerNm=` + ci.CustomerName // `&cvn2=&=expired`
  124. info := `{` + kvs + `}`
  125. args.Add("customerInfo", base64.StdEncoding.EncodeToString([]byte(info))) // 持卡人身份信息,敏感信息加密方式
  126. keys := make([]string, 0)
  127. for k := range args {
  128. keys = append(keys, k)
  129. }
  130. sort.Strings(keys)
  131. var s string
  132. for _, k := range keys {
  133. for _, value := range args[k] {
  134. if value != "" {
  135. s = s + "&" + k + "=" + value
  136. }
  137. }
  138. }
  139. fmt.Println(s[1:])
  140. hash := sha256.New()
  141. hash.Write([]byte(s[1:]))
  142. fmt.Println("sha1", hex.EncodeToString(hash.Sum(nil)))
  143. var signature []byte
  144. signature, err = RSASign256(priveKey, hash.Sum(nil))
  145. if err != nil {
  146. return
  147. }
  148. s = base64.StdEncoding.EncodeToString(signature)
  149. fmt.Println("signature", s)
  150. args.Add("signature", s) // 签名
  151. fmt.Println(args.Encode())
  152. headers := make(map[string]string)
  153. headers["Accept"] = "text/html; charset=UTF-8"
  154. headers["Accept-Encoding"] = "gzip, deflate, br"
  155. headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8"
  156. var msg util.Message
  157. msg, err = util.Post(BaseURL+ReqBackTrans, "", "", headers, bytes.NewReader([]byte(args.Encode())))
  158. if err != nil {
  159. return
  160. }
  161. fmt.Println("*************************************")
  162. fmt.Println(BaseURL + ReqBackTrans)
  163. fmt.Println(msg.StatusCode)
  164. fmt.Println(msg.Header)
  165. fmt.Println(string(msg.Body))
  166. fmt.Println("*************************************")
  167. var (
  168. res ReqRes
  169. values url.Values
  170. )
  171. values, err = url.ParseQuery(string(msg.Body))
  172. if err != nil {
  173. fmt.Println(err)
  174. return
  175. }
  176. err = binding.MapForm(&res, values)
  177. fmt.Println(err)
  178. if err == nil {
  179. bs, _ := json.Marshal(&res)
  180. fmt.Println(string(bs))
  181. }
  182. return
  183. }