蛋蛋星球-客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

229 lines
7.1 KiB

  1. package alipay
  2. import (
  3. "context"
  4. "crypto/rsa"
  5. "crypto/x509"
  6. "encoding/json"
  7. "encoding/pem"
  8. "errors"
  9. "fmt"
  10. "github.com/go-pay/crypto/xrsa"
  11. "github.com/go-pay/gopay"
  12. "github.com/go-pay/gopay/alipay"
  13. "github.com/go-pay/xtime"
  14. "github.com/syyongx/php2go"
  15. "strings"
  16. "time"
  17. )
  18. const (
  19. // URL
  20. baseUrl = "https://openapi.alipay.com/gateway.do"
  21. sandboxBaseUrl = "https://openapi.alipaydev.com/gateway.do"
  22. baseUrlUtf8 = "https://openapi.alipay.com/gateway.do?charset=utf-8"
  23. sandboxBaseUrlUtf8 = "https://openapi.alipaydev.com/gateway.do?charset=utf-8"
  24. LocationShanghai = "Asia/Shanghai"
  25. PKCS1 PKCSType = 1
  26. PKCS8 PKCSType = 2
  27. RSA = "RSA"
  28. RSA2 = "RSA2"
  29. )
  30. type PKCSType uint8
  31. type UserCertifyOpenInitData struct {
  32. AlipayUserCertifyOpenInitializeResponse struct {
  33. CertifyID interface{} `json:"certify_id"`
  34. Code interface{} `json:"code"`
  35. Msg interface{} `json:"msg"`
  36. } `json:"alipay_user_certify_open_initialize_response"`
  37. }
  38. type UserCertifyOpenQueryData struct {
  39. AlipayUserCertifyOpenQueryResponse struct {
  40. Code string `json:"code"`
  41. FailReason string `json:"fail_reason"`
  42. IdentityInfo string `json:"identity_info"`
  43. MaterialInfo string `json:"material_info"`
  44. Msg string `json:"msg"`
  45. Passed interface{} `json:"passed"`
  46. } `json:"alipay_user_certify_open_query_response"`
  47. Sign string `json:"sign"`
  48. }
  49. func commClient(notiURL string, paySet *PayData) (*alipay.Client, error) {
  50. client, _ := alipay.NewClient(paySet.AlipayAppId, paySet.AlipayPrivateKey, true)
  51. client.DebugSwitch = gopay.DebugOn
  52. //配置公共参数
  53. client.SetCharset("utf-8").
  54. SetNotifyUrl(notiURL)
  55. client.AutoVerifySign([]byte(paySet.AlipayPublicContentRSA2))
  56. // 传入证书内容
  57. err := client.SetCertSnByContent([]byte(paySet.AppPublicContent), []byte(paySet.AlipayRootContent), []byte(paySet.AlipayPublicContentRSA2))
  58. if err != nil {
  59. return nil, err
  60. }
  61. return client, nil
  62. }
  63. // UserCertifyOpenInit is 支付宝APP支身份认证初始化服务
  64. // alipay.user.certify.open.initialize
  65. func UserCertifyOpenInit(realName, identityNum, orderID, notiURL string, paySet *PayData) (UserCertifyOpenInitData, error) {
  66. var param = UserCertifyOpenInitData{}
  67. //初始化支付宝客户端
  68. // appID 是在支付宝申请的APPID
  69. // priKey 是支付宝私钥
  70. // realName 是姓名
  71. // identityNum 是身份证
  72. // orderID 是智莺这边生成的订单id
  73. // notiURL 通知地址url
  74. // passback_params 回调通知参数
  75. client, _ := commClient(notiURL, paySet)
  76. fmt.Println(client)
  77. merchantConfig := map[string]string{
  78. "return_url": notiURL,
  79. }
  80. identityParam := map[string]string{
  81. "identity_type": "CERT_INFO",
  82. "cert_type": "IDENTITY_CARD",
  83. "cert_name": realName,
  84. "cert_no": identityNum,
  85. }
  86. var bizContent = map[string]interface{}{
  87. "biz_code": "FACE",
  88. "merchant_config": merchantConfig,
  89. "identity_param": identityParam,
  90. "outer_order_no": orderID,
  91. }
  92. //请求参数
  93. bizContentJson, _ := json.Marshal(bizContent)
  94. bizContentStr := strings.ReplaceAll(string(bizContentJson), "\\u0026", "&")
  95. body := make(gopay.BodyMap)
  96. body.Set("biz_content", bizContentStr)
  97. err := client.PostAliPayAPISelfV2(context.Background(), body, "alipay.user.certify.open.initialize", &param)
  98. if err != nil {
  99. return param, err
  100. }
  101. return param, nil
  102. }
  103. // UserCertifyOpenQuery is 身份认证记录查询
  104. // alipay.user.certify.open.query
  105. func UserCertifyOpenQuery(certifyId, notiURL string, paySet *PayData) (UserCertifyOpenQueryData, error) {
  106. var param = UserCertifyOpenQueryData{}
  107. //初始化支付宝客户端
  108. // appID 是在支付宝申请的APPID
  109. // priKey 是支付宝私钥
  110. // certifyId 是认证id 初始化获得
  111. // notiURL 通知地址url
  112. // passback_params 回调通知参数
  113. client, _ := commClient(notiURL, paySet)
  114. fmt.Println(client)
  115. var bizContent = map[string]interface{}{
  116. "certify_id": certifyId,
  117. }
  118. //请求参数
  119. bizContentJson, _ := json.Marshal(bizContent)
  120. bizContentStr := strings.ReplaceAll(string(bizContentJson), "\\u0026", "&")
  121. body := make(gopay.BodyMap)
  122. body.Set("biz_content", bizContentStr)
  123. //body.Set("timeout_express", "30m")
  124. err := client.PostAliPayAPISelfV2(context.Background(), body, "alipay.user.certify.open.query", &param)
  125. if err != nil {
  126. return param, err
  127. }
  128. return param, nil
  129. }
  130. // UserCertifyOpenCertify is 支付宝APP身份认证开始认证
  131. // alipay.user.certify.open.initialize
  132. func UserCertifyOpenCertify(certifyId, notiURL string, paySet *PayData) (string, error) {
  133. //初始化支付宝客户端
  134. // appID 是在支付宝申请的APPID
  135. // priKey 是支付宝私钥
  136. // certifyId 是认证id 初始化获得
  137. // orderID 是智莺这边生成的订单id
  138. // notiURL 通知地址url
  139. // passback_params 回调通知参数
  140. client, _ := commClient(notiURL, paySet)
  141. fmt.Println(client)
  142. var bizContent = map[string]interface{}{
  143. "certify_id": certifyId,
  144. }
  145. //请求参数
  146. bizContentJson, _ := json.Marshal(bizContent)
  147. bizContentStr := strings.ReplaceAll(string(bizContentJson), "\\u0026", "&")
  148. body := make(gopay.BodyMap)
  149. body.Set("biz_content", bizContentStr)
  150. body.Set("method", "alipay.user.certify.open.certify")
  151. body = checkPublicParam(client, body)
  152. key := xrsa.FormatAlipayPrivateKey(paySet.AlipayPrivateKey)
  153. var block *pem.Block
  154. if block, _ = pem.Decode([]byte(key)); block == nil {
  155. return "", errors.New("获取失败")
  156. }
  157. pkcs8Key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
  158. if err != nil {
  159. return "", errors.New("获取失败")
  160. }
  161. pk8, ok := pkcs8Key.(*rsa.PrivateKey)
  162. if !ok {
  163. return "", errors.New("获取失败")
  164. }
  165. keys := pk8
  166. sign, err := alipay.GetRsaSign(body, body.GetString("sign_type"), keys)
  167. if err != nil {
  168. return "", fmt.Errorf("GetRsaSign Error: %v", err)
  169. }
  170. body.Set("sign", sign)
  171. var str = "https://openapi.alipay.com/gateway.do"
  172. for k, v := range body {
  173. if strings.Contains(str, "?") == false {
  174. str += "?" + k + "=" + php2go.URLEncode(v.(string))
  175. } else {
  176. str += "&" + k + "=" + php2go.URLEncode(v.(string))
  177. }
  178. }
  179. return str, nil
  180. }
  181. // 公共参数检查
  182. func checkPublicParam(a *alipay.Client, bm gopay.BodyMap) gopay.BodyMap {
  183. bm.Set("format", "JSON")
  184. if bm.GetString("app_id") == "" && a.AppId != "" {
  185. bm.Set("app_id", a.AppId)
  186. }
  187. if bm.GetString("app_cert_sn") == "" && a.AppCertSN != "" {
  188. bm.Set("app_cert_sn", a.AppCertSN)
  189. }
  190. if bm.GetString("alipay_root_cert_sn") == "" && a.AliPayRootCertSN != "" {
  191. bm.Set("alipay_root_cert_sn", a.AliPayRootCertSN)
  192. }
  193. if bm.GetString("return_url") == "" && a.ReturnUrl != "" {
  194. bm.Set("return_url", a.ReturnUrl)
  195. }
  196. bm.Set("charset", "utf-8")
  197. if bm.GetString("charset") == "" && a.Charset != "" {
  198. bm.Set("charset", a.Charset)
  199. }
  200. bm.Set("sign_type", RSA2)
  201. if bm.GetString("sign_type") == "" && a.SignType != "" {
  202. bm.Set("sign_type", a.SignType)
  203. }
  204. bm.Set("timestamp", time.Now().Format(xtime.TimeLayout))
  205. bm.Set("version", "1.0")
  206. if bm.GetString("notify_url") == "" && a.NotifyUrl != "" {
  207. bm.Set("notify_url", a.NotifyUrl)
  208. }
  209. if bm.GetString("app_auth_token") == "" && a.AppAuthToken != "" {
  210. bm.Set("app_auth_token", a.AppAuthToken)
  211. }
  212. return bm
  213. }