withdraw.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. package liu
  2. import (
  3. "bet24.com/log"
  4. "bet24.com/public"
  5. notification "bet24.com/servers/micros/notification/proto"
  6. "bet24.com/servers/payment/config"
  7. "bet24.com/servers/payment/db"
  8. "encoding/json"
  9. "github.com/gin-gonic/gin"
  10. uuid "github.com/satori/go.uuid"
  11. "net/http"
  12. "net/url"
  13. "strconv"
  14. "strings"
  15. "time"
  16. )
  17. // 提现请求
  18. func WithdrawOrder(c *gin.Context) {
  19. obj := db.NewLiuWithdrawReq()
  20. if err := c.ShouldBind(&obj.In); err != nil {
  21. log.Debug("%s query params err %v", "liu.WithdrawOrder", err)
  22. c.String(http.StatusOK, "fail")
  23. return
  24. }
  25. obj.In.IPAddress = strings.Split(c.Request.RemoteAddr, ":")[0]
  26. obj.DoAction()
  27. if obj.Out.OrderID == "" {
  28. log.Debug("%s GenOrder OrderId is empty fail obj.In=%+v obj.Out=%+v", "liu.WithdrawOrder", obj.In, obj.Out)
  29. c.String(http.StatusOK, "fail")
  30. return
  31. }
  32. // 下单失败
  33. if obj.Out.RetCode != 1 {
  34. log.Debug("%s GenOrder fail obj.In=%+v obj.Out=%+v", "liu.WithdrawOrder", obj.In, obj.Out)
  35. c.String(http.StatusOK, "fail")
  36. return
  37. }
  38. // 下单成功,待审核
  39. if obj.Out.GetStatus != 0 {
  40. log.Debug("%s GenOrder success obj.In=%+v obj.Out=%+v", "liu.WithdrawOrder", obj.In, obj.Out)
  41. c.String(http.StatusOK, "success")
  42. return
  43. }
  44. // 请求时,没有传手机号
  45. if obj.In.Mobile == "" {
  46. obj.In.Mobile = obj.Out.Tel
  47. }
  48. // 请求withdrawOrder的代码
  49. req := withdraw_req{
  50. MerchantCode: config.Server.LiuPay.MerchantCode,
  51. OrderNo: obj.Out.OrderID,
  52. Type: 1,
  53. AccNo: obj.In.BankCard,
  54. AccName: obj.In.RealName,
  55. Amount: obj.In.Amount,
  56. BankName: obj.In.BankName,
  57. BankBranch: "1",
  58. Province: "2",
  59. City: "3",
  60. Ccy_no: "IDR",
  61. }
  62. params := url.Values{}
  63. params.Set("merchantCode", req.MerchantCode)
  64. params.Set("orderNo", req.OrderNo)
  65. params.Set("type", strconv.Itoa(req.Type))
  66. params.Set("accNo", req.AccNo)
  67. params.Set("accName", req.AccName)
  68. params.Set("amount", strconv.Itoa(req.Amount))
  69. params.Set("bankName", req.BankName)
  70. params.Set("bankBranch", req.BankBranch)
  71. params.Set("province", req.Province)
  72. params.Set("city", req.City)
  73. params.Set("ccy_no", req.Ccy_no)
  74. // 生成签名
  75. checkContent := createEncryptStr(params) + "&key=" + config.Server.LiuPay.MD5Key
  76. // log.Debug("liu.WithdrawOrder.checkContent ==> %s", checkContent)
  77. signature := strings.ToUpper(public.GetMd5String(checkContent))
  78. req.Signature = signature
  79. // POST请求
  80. buf, _ := json.Marshal(req)
  81. respBody := public.HttpPostByJson(config.Server.LiuPay.Url_withdraw_order, string(buf))
  82. log.Debug("liu.WithdrawOrder req ==> %+v resp ==> %+v", string(buf), respBody)
  83. var resp withdraw_resp
  84. if err := json.Unmarshal([]byte(respBody), &resp); err != nil {
  85. log.Error("liu.WithdrawOrder json unmarshal req ==> %+v resp ==> %+v fail %v", string(buf), respBody, err)
  86. c.String(http.StatusOK, "fail")
  87. return
  88. }
  89. log.Debug("liu.WithdrawOrder resp ==> %+v", resp)
  90. // 请求响应码
  91. if resp.Err_code != "000002" {
  92. log.Error("liu.withdrawRequest post return resp fail ==> %+v", resp)
  93. c.String(http.StatusOK, "fail")
  94. return
  95. }
  96. // 请求响应码
  97. if resp.Status != "SUCCESS" {
  98. log.Error("liu.withdrawRequest post return resp fail ==> %+v", resp)
  99. c.String(http.StatusOK, "fail")
  100. return
  101. }
  102. go notification.AddNotification(obj.In.UserID, notification.Notification_Gold, "")
  103. // 更新银行信息
  104. objBank := db.NewBankInfoUp()
  105. objBank.In.UserID = obj.In.UserID
  106. objBank.In.RealName = req.AccName
  107. objBank.In.BankCard = req.AccNo
  108. objBank.In.BankName = req.BankName
  109. objBank.In.Mobile = obj.In.Mobile
  110. objBank.In.EMail = obj.In.Email
  111. objBank.In.Address = obj.In.Address
  112. objBank.DoAction()
  113. log.Debug("liu.WithdrawNotify need save bankInfo")
  114. // 加到队列
  115. go withdrawQueues.push(req.OrderNo)
  116. c.String(http.StatusOK, "success")
  117. }
  118. // 提现审核
  119. func WithdrawAudit(c *gin.Context) {
  120. obj := db.NewLiuWithdrawAudit()
  121. if err := c.ShouldBind(&obj.In); err != nil {
  122. log.Debug("%s shouldBind err %v", "WithdrawAudit", err)
  123. return
  124. }
  125. obj.DoAction(nil)
  126. // 审核失败
  127. if obj.Out.RetCode != 1 {
  128. c.JSON(http.StatusOK, obj.Out)
  129. return
  130. }
  131. log.Debug("liu.WithdrawAudit obj.In=%+v obj.Out=%+v", obj.In, obj.Out)
  132. // 审核成功
  133. // 状态 2=同意 11=拒绝
  134. if obj.In.Status != 2 {
  135. go notification.AddNotification(obj.Out.UserID, notification.Notification_Gold, "")
  136. c.JSON(http.StatusOK, obj.Out)
  137. return
  138. }
  139. // 请求withdrawOrder的代码
  140. req := withdraw_req{
  141. MerchantCode: config.Server.LiuPay.MerchantCode,
  142. OrderNo: obj.Out.OrderID,
  143. Type: 1,
  144. AccNo: obj.Out.BankCard,
  145. AccName: obj.Out.RealName,
  146. Amount: obj.Out.Amount,
  147. BankName: obj.Out.BankName,
  148. BankBranch: "1",
  149. Province: "2",
  150. City: "3",
  151. Ccy_no: "IDR",
  152. }
  153. params := url.Values{}
  154. params.Set("merchantCode", req.MerchantCode)
  155. params.Set("orderNo", req.OrderNo)
  156. params.Set("type", strconv.Itoa(req.Type))
  157. params.Set("accNo", req.AccNo)
  158. params.Set("accName", req.AccName)
  159. params.Set("amount", strconv.Itoa(req.Amount))
  160. params.Set("bankName", req.BankName)
  161. params.Set("bankBranch", req.BankBranch)
  162. params.Set("province", req.Province)
  163. params.Set("city", req.City)
  164. params.Set("ccy_no", req.Ccy_no)
  165. // 生成签名
  166. checkContent := createEncryptStr(params) + "&key=" + config.Server.LiuPay.MD5Key
  167. // log.Debug("liu.WithdrawAudit.checkContent ==> %s", checkContent)
  168. signature := strings.ToUpper(public.GetMd5String(checkContent))
  169. req.Signature = signature
  170. // POST请求
  171. buf, _ := json.Marshal(req)
  172. respBody := public.HttpPostByJson(config.Server.LiuPay.Url_withdraw_order, string(buf))
  173. log.Debug("liu.WithdrawAudit req ==> %+v resp ==> %+v", string(buf), respBody)
  174. var resp withdraw_resp
  175. if err := json.Unmarshal([]byte(respBody), &resp); err != nil {
  176. log.Error("liu.WithdrawAudit json unmarshal req ==> %+v resp ==> %+v fail %v", string(buf), respBody, err)
  177. c.String(http.StatusOK, "fail")
  178. return
  179. }
  180. log.Debug("liu.WithdrawAudit resp ==> %+v", resp)
  181. // 请求响应码
  182. if resp.Err_code != "000000" {
  183. log.Error("liu.WithdrawAudit post return resp fail ==> %+v", resp)
  184. c.String(http.StatusOK, "fail")
  185. return
  186. }
  187. // 请求响应码
  188. if resp.Status != "SUCCESS" {
  189. log.Error("liu.WithdrawAudit post return resp fail ==> %+v", resp)
  190. c.String(http.StatusOK, "fail")
  191. return
  192. }
  193. // 加到队列
  194. go withdrawQueues.push(req.OrderNo)
  195. c.JSON(http.StatusOK, obj.Out)
  196. return
  197. }
  198. // 提现查询
  199. func withdrawSearch(orderId string) bool {
  200. id, _ := uuid.NewV4()
  201. // 请求withdrawOrder的代码
  202. req := withdrawSearch_req{
  203. RequestNo: id.String(),
  204. RequestTime: time.Now().Add(1 * time.Hour).Format("20060102150405"), // 北京时间,所以这里需要+1小时
  205. MerchantCode: config.Server.LiuPay.MerchantCode,
  206. OrderNo: orderId,
  207. TerraceNo: "",
  208. }
  209. params := url.Values{}
  210. params.Set("requestNo", req.RequestNo)
  211. params.Set("requestTime", req.RequestTime)
  212. params.Set("merchantCode", req.MerchantCode)
  213. params.Set("orderNo", req.OrderNo)
  214. // 生成签名
  215. checkContent := createEncryptStr(params) + "&key=" + config.Server.LiuPay.MD5Key
  216. // log.Debug("liu.withdrawSearch.checkContent ==> %s", checkContent)
  217. signature := strings.ToUpper(public.GetMd5String(checkContent))
  218. req.Signature = signature
  219. // POST请求
  220. buf, _ := json.Marshal(req)
  221. respBody := public.HttpPostByJson(config.Server.LiuPay.Url_withdraw_search, string(buf))
  222. log.Debug("liu.withdrawSearch req ==> %+v resp ==> %+v", string(buf), respBody)
  223. var resp withdrawSearch_resp
  224. if err := json.Unmarshal([]byte(respBody), &resp); err != nil {
  225. log.Error("liu.withdrawSearch json unmarshal req ==> %+v resp ==> %+v fail %v", string(buf), respBody, err)
  226. return false
  227. }
  228. log.Debug("liu.withdrawSearch resp ==> %+v", resp)
  229. // 请求响应码
  230. if resp.Query_Status != "SUCCESS" {
  231. log.Error("liu.withdrawSearch post return resp fail ==> %+v", resp)
  232. return false
  233. }
  234. // 既没有成功,也没有失败,继续查询
  235. if resp.Status != "SUCCESS" && resp.Status != "FAIL" {
  236. return false
  237. }
  238. status := 0
  239. switch resp.Status {
  240. case "FAIL":
  241. status = Withdraw_Status_Failure
  242. case "SUCCESS":
  243. status = Withdraw_Status_Success
  244. default:
  245. status = Withdraw_Status_Pending_Success
  246. }
  247. obj := db.NewLiuWithdrawNotify()
  248. obj.In.OrderID = req.OrderNo
  249. obj.In.DfTransactionId = resp.TerraceNo
  250. obj.In.Status = status
  251. obj.In.DfDesc = resp.Status
  252. obj.In.Balance = 0
  253. obj.DoAction()
  254. log.Debug("lets.withdrawSearch obj.In=%+v obj.Out=%+v", obj.In, obj.Out)
  255. // 提现失败,退款
  256. if resp.Status == "FAIL" {
  257. go notification.AddNotification(obj.Out.UserID, notification.Notification_Gold, "")
  258. }
  259. return true
  260. }