withdraw.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package payermax
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "net/http"
  7. "strconv"
  8. "strings"
  9. "bet24.com/log"
  10. "bet24.com/public"
  11. "bet24.com/servers/common"
  12. notification "bet24.com/servers/micros/notification/proto"
  13. "bet24.com/servers/payment/config"
  14. "bet24.com/servers/payment/db"
  15. "github.com/gin-gonic/gin"
  16. )
  17. // 提现请求
  18. func WithdrawOrder(c *gin.Context) {
  19. obj := db.NewPayerMaxWithdrawReq()
  20. if err := c.ShouldBind(&obj.In); err != nil {
  21. log.Debug("%s query params err %v", "payermax.WithdrawOrder", err)
  22. c.String(http.StatusOK, "fail")
  23. return
  24. }
  25. // 判断提现金额足购
  26. /*if !coreClient.TryWithdraw(obj.In.UserID, obj.In.Amount, true) {
  27. c.String(http.StatusOK, "Insufficient amount")
  28. return
  29. }*/
  30. obj.In.IPAddress = strings.Split(c.Request.RemoteAddr, ":")[0]
  31. obj.DoAction()
  32. if obj.Out.OrderID == "" {
  33. log.Debug("%s GenOrder fail obj.In=%+v obj.Out=%+v", "payermax.WithdrawOrder", obj.In, obj.Out)
  34. c.String(http.StatusOK, "fail")
  35. return
  36. }
  37. if obj.Out.GetStatus != 0 {
  38. log.Debug("%s GenOrder Audit obj.In=%+v obj.Out=%+v", "payermax.WithdrawOrder", obj.In, obj.Out)
  39. c.String(http.StatusOK, "fail")
  40. return
  41. }
  42. // 请求时,没有传手机号
  43. if obj.In.Mobile == "" {
  44. obj.In.Mobile = obj.Out.Tel
  45. }
  46. // 请求withdrawOrder的代码
  47. req := withdraw_req{
  48. Version: "1.0",
  49. KeyVersion: "1",
  50. RequestTime: common.GetNowTime().Format(dateFormat),
  51. MerchantAppId: config.Server.PayerMax.MerchantAppId,
  52. MerchantNo: config.Server.PayerMax.MerchantNo,
  53. Data: withdrawReqData{
  54. OutTradeNo: obj.Out.OrderID,
  55. Country: "SA",
  56. Trade: &tradeData{
  57. Amount: strconv.Itoa(obj.In.Amount),
  58. Currency: "SAR",
  59. },
  60. PayeeInfo: &payeeInfoData{
  61. PaymentMethod: "WALLET",
  62. TargetOrg: "STCPAY",
  63. AccountInfo: &accountInfoData{
  64. AccountNo: obj.In.BankCard,
  65. },
  66. BankInfo: &bankInfoData{
  67. BankCode: obj.In.BankCode,
  68. BankName: obj.In.BankName,
  69. },
  70. Name: &nameData{
  71. FullName: obj.In.RealName,
  72. },
  73. },
  74. NotifyUrl: config.Server.PayerMax.Url_withdraw_Notify,
  75. },
  76. }
  77. // 生成签名
  78. buf, err := json.Marshal(req)
  79. if err != nil {
  80. log.Error("payermax.WithdrawOrder checkContent json marshal fail %v", err)
  81. return
  82. }
  83. checkContent := string(buf)
  84. sign := public.Sha256WithRsa(checkContent, config.Server.PayerMax.MCH_PRIVATE_KEY)
  85. log.Debug("payermax.WithdrawOrder checkContent=%s sign=%s", checkContent, sign)
  86. respBody := httpPostByJson(config.Server.PayerMax.Url_withdraw_order, checkContent, sign)
  87. log.Debug("payermax.WithdrawOrder req ==> %+v resp ==> %+v", checkContent, respBody)
  88. var resp withdraw_resp
  89. if err := json.Unmarshal([]byte(respBody), &resp); err != nil {
  90. log.Error("payermax.WithdrawOrder json unmarshal req ==> %+v resp ==> %+v fail %v", req, respBody, err)
  91. c.String(http.StatusOK, "fail")
  92. return
  93. }
  94. log.Debug("payermax.WithdrawOrder resp ==> %+v", resp)
  95. // 接口响应码,’APPLY_SUCCESS’代表成功
  96. if resp.Code != "APPLY_SUCCESS" {
  97. log.Error("payermax.withdrawRequest post return resp fail ==> %+v", resp)
  98. // 余额不足,退款
  99. // if resp.Data.Status != "PENDING" {
  100. // obj := db.NewPayerMaxWithdrawNotify()
  101. // obj.In.OrderID = req.Data.OutTradeNo
  102. // obj.In.DfTransactionId = resp.Data.TradeNo
  103. // obj.In.Status = 0
  104. // obj.In.DfDesc = fmt.Sprintf("%s", resp.Data.Status)
  105. // obj.In.Balance = 0
  106. // obj.DoAction()
  107. //
  108. // log.Debug("payermax.WithdrawOrder obj.In=%+v obj.Out=%+v", obj.In, obj.Out)
  109. // }
  110. c.String(http.StatusOK, "fail")
  111. return
  112. }
  113. go func() {
  114. //coreClient.TryWithdraw(obj.In.UserID, obj.In.Amount, false)
  115. // 通知
  116. notification.AddNotification(obj.In.UserID, notification.Notification_Gold, "")
  117. }()
  118. // 更新银行信息
  119. // objBank := db.NewBankInfoUp()
  120. // objBank.In.UserID = obj.In.UserID
  121. // objBank.In.RealName = req.Name
  122. // objBank.In.BankCard = req.Number
  123. // objBank.In.BankName = req.BankCode
  124. // objBank.In.Mobile = obj.In.Mobile
  125. // objBank.In.EMail = obj.In.Email
  126. // objBank.In.Address = obj.In.Address
  127. // objBank.DoAction()
  128. // log.Debug("payermax.WithdrawNotify need save bankInfo")
  129. c.String(http.StatusOK, "success")
  130. return
  131. }
  132. // 提现通知
  133. func WithdrawNotify(c *gin.Context) {
  134. bodyData, _ := io.ReadAll(c.Request.Body)
  135. log.Debug("payermax.WithdrawNotify ==> ctx.Request.body: %v", string(bodyData))
  136. // 获取签名
  137. sign := c.Request.Header.Get("sign")
  138. log.Debug("payermax.WithdrawNotify sign=%s", sign)
  139. var resp withdrawNotify
  140. if err := json.Unmarshal(bodyData, &resp); err != nil {
  141. log.Debug("%s query params err %v", "payermax.WithdrawNotify", err)
  142. c.String(http.StatusOK, "")
  143. return
  144. }
  145. log.Debug("payermax.WithdrawNotify resp ==> %+v", resp)
  146. // 验证签名
  147. if public.VerifyRsaSignBySHA256(string(bodyData), sign, config.Server.PayerMax.PLAT_PUBLIC_KEY) != nil {
  148. log.Error("payermax.WithdrawNotify 签名失败 ==> %+v", resp)
  149. return
  150. }
  151. log.Debug("payermax.WithdrawNotify 签名成功")
  152. // 返回码,’APPLY_SUCCESS’代表成功
  153. if resp.Code != "APPLY_SUCCESS" {
  154. log.Error("payermax.WithdrawNotify req ==> %+v", resp)
  155. c.String(http.StatusOK, "")
  156. return
  157. }
  158. // 交易状态,SUCCESS成功, FAILD失败 ,PENDING进行中,BOUNCEBACK退票
  159. // 0=Failure 1=Success 2=Pending(Success) 3=BOUNCEBACK退票
  160. status := 0
  161. switch resp.Data.Status {
  162. case "FAILD": // 0=失败
  163. status = 0
  164. case "SUCCESS": // 1=成功
  165. status = 1
  166. case "PENDING": // 2=进行中
  167. status = 2
  168. case "BOUNCEBACK": // 3=退票
  169. status = 3
  170. default:
  171. status = 2
  172. }
  173. obj := db.NewPayerMaxWithdrawNotify()
  174. obj.In.OrderID = resp.Data.OutTradeNo
  175. obj.In.DfTransactionId = resp.Data.TradeNo
  176. obj.In.Status = status
  177. obj.In.DfDesc = fmt.Sprintf("%s,Fee: %s", strings.ReplaceAll(resp.Data.Status, "'", ""), resp.Data.Source.Fee)
  178. obj.In.Balance = 0
  179. obj.DoAction()
  180. log.Debug("payermax.WithdrawNotify obj.In=%+v obj.Out=%+v", obj.In, obj.Out)
  181. // 提现失败,退款
  182. // if resp.Status == WITHDRAW_FAIL {
  183. // go coreClient.AddNotification(obj.Out.UserID, notification.Notification_Gold, "")
  184. // }
  185. c.JSON(http.StatusOK, ret{
  186. Code: "SUCCESS",
  187. Msg: "Success",
  188. })
  189. return
  190. }