withdraw.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. package kaya
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "fmt"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "strings"
  10. "time"
  11. "bet24.com/log"
  12. "bet24.com/public"
  13. notification "bet24.com/servers/micros/notification/proto"
  14. "bet24.com/servers/payment/config"
  15. "bet24.com/servers/payment/db"
  16. "github.com/gin-gonic/gin"
  17. )
  18. // 提现请求
  19. func WithdrawOrder(c *gin.Context) {
  20. obj := db.NewKayaWithdrawReq()
  21. if err := c.ShouldBind(&obj.In); err != nil {
  22. log.Debug("%s query params err %v", "kaya.WithdrawOrder", err)
  23. c.String(http.StatusOK, "fail")
  24. return
  25. }
  26. obj.In.IPAddress = strings.Split(c.Request.RemoteAddr, ":")[0]
  27. obj.DoAction()
  28. if obj.Out.OrderID == "" {
  29. log.Debug("%s GenOrder fail obj.In=%+v obj.Out=%+v", "kaya.WithdrawOrder", obj.In, obj.Out)
  30. c.String(http.StatusOK, "fail")
  31. return
  32. }
  33. // 请求时,没有传手机号
  34. if obj.In.Mobile == "" {
  35. obj.In.Mobile = obj.Out.Tel
  36. }
  37. // 请求withdrawOrder的代码
  38. req := withdraw_req{
  39. MerchantCode: config.Server.KayaPay.MerchantCode,
  40. OrderNum: obj.Out.OrderID,
  41. Money: obj.In.Amount,
  42. Description: "withdraw",
  43. Name: obj.In.RealName,
  44. BankCode: obj.In.BankName,
  45. Number: obj.In.BankCard,
  46. NotifyUrl: config.Server.KayaPay.Url_withdraw_notify,
  47. FeeType: 0,
  48. DateTime: TIME_FORMAT,
  49. }
  50. params := url.Values{}
  51. params.Set("merchantCode", req.MerchantCode)
  52. params.Set("orderNum", req.OrderNum)
  53. params.Set("money", strconv.Itoa(req.Money))
  54. params.Set("description", req.Description)
  55. params.Set("name", req.Name)
  56. params.Set("bankCode", req.BankCode)
  57. params.Set("number", req.Number)
  58. params.Set("notifyUrl", req.NotifyUrl)
  59. params.Set("feeType", strconv.Itoa(req.FeeType))
  60. params.Set("dateTime", req.DateTime)
  61. // 生成签名
  62. checkContent := createEncryptStr(params)
  63. log.Debug("kaya.WithdrawOrder.checkContent ==> %s", checkContent)
  64. // 商户请求我们接口时使用商户私钥对请求参数 进行加密
  65. mchPriKey := fmt.Sprintf(`-----BEGIN PRIVATE KEY-----
  66. %s
  67. -----END PRIVATE KEY-----
  68. `, config.Server.KayaPay.MCH_PRIVATE_KEY)
  69. if err := public.RSA.SetPrivateKey(mchPriKey); err != nil {
  70. log.Error("kaya.WithdrawOrder set private key :%v ==> %+v", err, params)
  71. return
  72. }
  73. // 私钥加密
  74. prienctypt, err := public.RSA.PriKeyENCTYPT([]byte(checkContent))
  75. if err != nil {
  76. log.Error("kaya.WithdrawOrder RSA.PriKeyENCTYPT err %v", err)
  77. return
  78. }
  79. req.Sign = base64.StdEncoding.EncodeToString(prienctypt)
  80. // log.Debug("kaya.payOrder req ==> %+v ", params)
  81. buf, _ := json.Marshal(req)
  82. respBody := public.HttpPostByJson(config.Server.KayaPay.Url_withdraw_order, string(buf))
  83. log.Debug("kaya.WithdrawOrder req ==> %+v resp ==> %+v", params, respBody)
  84. var resp withdraw_resp
  85. if err := json.Unmarshal([]byte(respBody), &resp); err != nil {
  86. log.Error("kaya.WithdrawOrder json unmarshal req ==> %+v resp ==> %+v fail %v", params, respBody, err)
  87. c.String(http.StatusOK, "fail")
  88. return
  89. }
  90. log.Debug("kaya.WithdrawOrder resp ==> %+v", resp)
  91. // 请求响应码,00000表示成功,其他失败
  92. if resp.PlatRespCode != RESP_CODE_SUCCESS {
  93. log.Error("kaya.WithdrawOrder post return resp fail ==> %+v", resp)
  94. c.String(http.StatusOK, "fail")
  95. return
  96. }
  97. go notification.AddNotification(obj.In.UserID, notification.Notification_Gold, "")
  98. // 更新银行信息
  99. objBank := db.NewBankInfoUp()
  100. objBank.In.UserID = obj.In.UserID
  101. objBank.In.RealName = req.Name
  102. objBank.In.BankCard = req.Number
  103. objBank.In.BankName = req.BankCode
  104. objBank.In.Mobile = obj.In.Mobile
  105. objBank.In.EMail = obj.In.Email
  106. objBank.In.Address = obj.In.Address
  107. objBank.DoAction()
  108. log.Debug("kaya.WithdrawNotify need save bankInfo")
  109. c.String(http.StatusOK, "success")
  110. return
  111. }
  112. // 提现通知
  113. func WithdrawNotify(c *gin.Context) {
  114. var resp withdrawNotify
  115. if err := c.ShouldBind(&resp); err != nil {
  116. log.Debug("%s query params err %v", "kaya.WithdrawNotify", err)
  117. c.String(http.StatusOK, "")
  118. return
  119. }
  120. log.Debug("kaya.WithdrawNotify resp ==> %+v", resp)
  121. params := url.Values{}
  122. params.Set("bankCode", resp.BankCode)
  123. params.Set("description", resp.Description)
  124. params.Set("fee", strconv.Itoa(resp.Fee))
  125. params.Set("feeType", strconv.Itoa(resp.FeeType))
  126. params.Set("money", strconv.Itoa(resp.Money))
  127. params.Set("name", resp.Name)
  128. params.Set("number", resp.Number)
  129. params.Set("orderNum", resp.OrderNum)
  130. params.Set("platOrderNum", resp.PlatOrderNum)
  131. params.Set("status", resp.Status)
  132. params.Set("statusMsg", resp.StatusMsg)
  133. // 生成签名
  134. checkContent := createEncryptStr(params)
  135. log.Debug("kaya.WithdrawNotify checkContent ==> %s", checkContent)
  136. // 商户使用 商户后台显示的平台公钥 进行解密
  137. platPubKey := fmt.Sprintf(`-----BEGIN PUBLIC KEY-----
  138. %s
  139. -----END PUBLIC KEY-----
  140. `, config.Server.KayaPay.PLAT_PUBLIC_KEY)
  141. if err := public.RSA.SetPublicKey(platPubKey); err != nil {
  142. log.Error("kaya.WithdrawNotify set public key :%v ==> %+v", err, params)
  143. return
  144. }
  145. data, err := base64.StdEncoding.DecodeString(resp.PlatSign)
  146. if err != nil {
  147. log.Error("kaya.WithdrawNotify base64.StdEncoding.DecodeString err %v", err)
  148. return
  149. }
  150. // 公钥解密
  151. pubdecrypt, err := public.RSA.PubKeyDECRYPT(data)
  152. if err != nil {
  153. log.Error("kaya.WithdrawNotify RSA.PubKeyDECRYPT err %v", err)
  154. return
  155. }
  156. // 校验信息
  157. if checkContent != string(pubdecrypt) {
  158. log.Error("kaya.payOrder 签名失败 ==> %+v", resp)
  159. return
  160. }
  161. log.Debug("kaya.PayNotify 签名成功")
  162. // 状态:2-成功 4-失败
  163. if resp.Status != WITHDRAW_SUCCESS && resp.Status != WITHDRAW_FAIL {
  164. log.Error("kaya.WithdrawNotify req ==> %+v", resp)
  165. c.String(http.StatusOK, "")
  166. return
  167. }
  168. // 查询账户余额
  169. balance := queryAccount()
  170. // 状态(0=Failure 1=Success 2=Pending(Success))
  171. status := 0
  172. switch resp.Status {
  173. case "2": // 2=成功
  174. status = 1
  175. case "4": // 4=失败
  176. status = 0
  177. default:
  178. status = 2
  179. }
  180. obj := db.NewKayaWithdrawNotify()
  181. obj.In.OrderID = resp.OrderNum
  182. obj.In.DfTransactionId = resp.PlatOrderNum
  183. obj.In.Status = status
  184. obj.In.DfDesc = fmt.Sprintf("%s,手续费: %d", resp.StatusMsg, resp.Fee)
  185. obj.In.Balance = balance
  186. obj.DoAction()
  187. log.Debug("kaya.WithdrawNotify obj.In=%+v obj.Out=%+v", obj.In, obj.Out)
  188. // 提现失败,退款
  189. if resp.Status == WITHDRAW_FAIL {
  190. go notification.AddNotification(obj.Out.UserID, notification.Notification_Gold, "")
  191. }
  192. c.String(http.StatusOK, "success")
  193. return
  194. }
  195. // 账户余额
  196. func queryAccount() int {
  197. req := queryAccount_req{
  198. MerchantCode: config.Server.KayaPay.MerchantCode,
  199. DateTime: time.Now().Format(TIME_FORMAT),
  200. }
  201. params := url.Values{}
  202. params.Set("merchantCode", req.MerchantCode)
  203. params.Set("dateTime", req.DateTime)
  204. // 生成签名
  205. checkContent := createEncryptStr(params)
  206. log.Debug("kaya.queryAccount.checkContent ==> %s", checkContent)
  207. // 商户请求我们接口时使用商户私钥对请求参数 进行加密
  208. mchPriKey := fmt.Sprintf(`-----BEGIN PRIVATE KEY-----
  209. %s
  210. -----END PRIVATE KEY-----
  211. `, config.Server.KayaPay.MCH_PRIVATE_KEY)
  212. if err := public.RSA.SetPrivateKey(mchPriKey); err != nil {
  213. log.Error("kaya.queryAccount set private key :%v ==> %+v", err, params)
  214. return -1
  215. }
  216. // 私钥加密
  217. prienctypt, err := public.RSA.PriKeyENCTYPT([]byte(checkContent))
  218. if err != nil {
  219. log.Error("kaya.queryAccount RSA.PriKeyENCTYPT err %v", err)
  220. return -1
  221. }
  222. req.Sign = base64.StdEncoding.EncodeToString(prienctypt)
  223. // log.Debug("kaya.queryAccount req ==> %+v ", params)
  224. buf, _ := json.Marshal(req)
  225. respBody := public.HttpPostByJson(config.Server.KayaPay.Url_queryAccount, string(buf))
  226. log.Debug("kaya.queryAccount req ==> %+v resp ==> %+v", params, respBody)
  227. var resp queryAccount_resp
  228. if err := json.Unmarshal([]byte(respBody), &resp); err != nil {
  229. log.Error("kaya.queryAccount json unmarshal req ==> %+v resp ==> %+v fail %v", params, respBody, err)
  230. return -1
  231. }
  232. log.Debug("kaya.queryAccount resp ==> %+v", resp)
  233. // 请求响应码
  234. if resp.PlatRespCode != RESP_CODE_SUCCESS {
  235. log.Error("kaya.queryAccount post return resp fail ==> %+v", resp)
  236. return -1
  237. }
  238. balance, err := strconv.Atoi(resp.Balance)
  239. if err != nil {
  240. log.Error("kaya.queryAccount get balance %v", err)
  241. return -1
  242. }
  243. return balance
  244. }