互动
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.

281 lines
8.0 KiB

5 years ago
  1. package pay_service
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/iGoogle-ink/gopay/v2"
  6. "github.com/iGoogle-ink/gopay/v2/wechat"
  7. "github.com/ouxuanserver/osmanthuswine/src/core"
  8. "hudongzhuanjia/libs/wx"
  9. "hudongzhuanjia/logger"
  10. "hudongzhuanjia/models"
  11. "net/http"
  12. "strconv"
  13. "time"
  14. )
  15. const CALLBACK_ORDER_URL = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackOrder"
  16. func Order(content, ip, openid string, fee, goodType int, userId, activityId int64) (map[string]interface{}, error) {
  17. client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true)
  18. //设置国家
  19. client.SetCountry(wechat.China)
  20. now := time.Now()
  21. outTradeNo := gopay.GetRandomString(32)
  22. nonceStr := gopay.GetRandomString(32)
  23. timeStart := now.Format("20060101150405")
  24. timeExpire := now.Add(2 * time.Hour).Format("20060101150405")
  25. //初始化参数Map
  26. body := make(gopay.BodyMap)
  27. body.Set("nonce_str", nonceStr)
  28. body.Set("body", content)
  29. body.Set("out_trade_no", outTradeNo)
  30. body.Set("total_fee", fee)
  31. body.Set("spbill_create_ip", ip)
  32. body.Set("notify_url", CALLBACK_ORDER_URL)
  33. body.Set("trade_type", wechat.TradeType_JsApi)
  34. body.Set("device_info", "WEB")
  35. body.Set("sign_type", wechat.SignType_MD5)
  36. body.Set("openid", openid)
  37. body.Set("time_start", timeStart)
  38. //body.Set("time_expire", timeExpire)
  39. //请求支付下单,成功后得到结果
  40. res, err := client.UnifiedOrder(body)
  41. if err != nil {
  42. return nil, err
  43. }
  44. //ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res)
  45. //if err != nil {
  46. // return nil, err
  47. //}
  48. //if !ok {
  49. // return nil, errors.New("签名验证失败")
  50. //}
  51. if res.ReturnCode != wx.CODE_SUCCESS {
  52. return nil, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
  53. }
  54. if res.ResultCode != wx.CODE_SUCCESS {
  55. return nil, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
  56. }
  57. userOrder := new(models.UserOrder)
  58. userOrder.DeviceInfo = "WEB"
  59. userOrder.Desc = content
  60. userOrder.UserId = userId
  61. userOrder.ActivityId = activityId
  62. userOrder.FeeType = "CNY"
  63. userOrder.GoodType = goodType
  64. userOrder.OpenId = openid
  65. userOrder.OutTradeNo = outTradeNo
  66. userOrder.TimeStart = timeStart
  67. userOrder.TimeExpire = timeExpire
  68. userOrder.TotalFee = fee
  69. userOrder.TradeType = wechat.TradeType_JsApi
  70. userOrder.PrepayId = res.PrepayId
  71. userOrder.Status = 0
  72. userOrder.IsDelete = false
  73. userOrder.CreatedAt = time.Now()
  74. userOrder.UpdatedAt = time.Now()
  75. if _, err := core.GetXormAuto().InsertOne(userOrder); err != nil {
  76. return nil, err
  77. }
  78. timestamp := strconv.FormatInt(time.Now().Unix(), 10)
  79. //获取H5支付需要的paySign
  80. pac := "prepay_id=" + res.PrepayId
  81. paySign := wechat.GetH5PaySign(wx.Appid, res.NonceStr, pac, wechat.SignType_MD5, timestamp, wx.ApiKey)
  82. return map[string]interface{}{
  83. "appid": wx.Appid,
  84. "timestamp": timestamp,
  85. "nonce_str": res.NonceStr,
  86. "package": pac,
  87. "sign_type": wechat.SignType_MD5,
  88. "pay_sign": paySign,
  89. "out_trade_no": outTradeNo,
  90. "user_order_id": userOrder.Id,
  91. }, nil
  92. }
  93. func CallbackOrder(req *http.Request) error {
  94. res, err := wechat.ParseNotifyResult(req)
  95. if err != nil {
  96. logger.Sugar.Error("解析微信毁掉结果失败")
  97. return err
  98. }
  99. //ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res)
  100. //if err != nil {
  101. // return err
  102. //}
  103. //if !ok {
  104. // return errors.New("sign verify failed")
  105. //}
  106. if res.ReturnCode != wx.CODE_SUCCESS {
  107. return fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
  108. }
  109. if res.ResultCode != wx.CODE_SUCCESS {
  110. return fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
  111. }
  112. userOrder := new(models.UserOrder)
  113. exist, err := userOrder.GetByOutTradeNo(res.OutTradeNo)
  114. if err != nil {
  115. return err
  116. }
  117. if !exist {
  118. return fmt.Errorf("user order not exist")
  119. }
  120. userOrder.TimeEnd = res.TimeEnd
  121. userOrder.TransactionId = res.TransactionId
  122. userOrder.Status = 1
  123. if _, err := core.GetXormAuto().Id(userOrder.Id).Cols("time_end, transaction_id, status").Update(userOrder); err != nil {
  124. return err
  125. }
  126. // 设置一下
  127. if userOrder.GoodType == 1 { // 霸屏
  128. history := new(models.BullyScreenHistory)
  129. history.Status = 0
  130. _, err := core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrder.Id).Cols("status").Update(history)
  131. return err
  132. } else if userOrder.GoodType == 2 {
  133. history := new(models.RewardHistory)
  134. history.Status = 0
  135. _, err := core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrder.Id).Cols("status").Update(history)
  136. return err
  137. }
  138. logger.Sugar.Infof("%+v", res)
  139. return nil
  140. }
  141. func Query(outTradeNo string) (*wechat.QueryOrderResponse, error) {
  142. client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true)
  143. client.SetCountry(wechat.China)
  144. body := make(gopay.BodyMap)
  145. body.Set("out_trade_no", outTradeNo)
  146. body.Set("nonce_str", gopay.GetRandomString(32))
  147. body.Set("sign_type", wechat.SignType_MD5)
  148. // 请求订单查询,成功后得到结果
  149. res, err := client.QueryOrder(body)
  150. if err != nil {
  151. logger.Sugar.Errorf("wechat query order error, %s", err)
  152. return nil, err
  153. }
  154. if res.TradeState == wx.CODE_SUCCESS { // 付款成功
  155. userOrder := new(models.UserOrder)
  156. userOrder.Status = 1
  157. if _, err := core.GetXormAuto().Where("is_delete=0 and out_trade_no=?", outTradeNo).
  158. Cols("status").Update(userOrder); err != nil {
  159. return nil, err
  160. }
  161. }
  162. return res, nil
  163. }
  164. func BatchQueryByUserId(userId int64) error {
  165. orders := make([]*models.UserOrder, 0)
  166. if err := core.GetXormAuto().Where("is_delete = 0 and status = 0 and user_id = ?", userId).Find(&orders); err != nil {
  167. return err
  168. }
  169. return batchQuery(orders)
  170. }
  171. func BatchQueryByActivityId(activityId int64) error {
  172. orders := make([]*models.UserOrder, 0)
  173. if err := core.GetXormAuto().Where("is_delete = 0 and status = 0 and activity_id = ?", activityId).Find(&orders); err != nil {
  174. return err
  175. }
  176. return batchQuery(orders)
  177. }
  178. func batchQuery(orders []*models.UserOrder) error {
  179. for _, order := range orders {
  180. res, err := Query(order.OutTradeNo)
  181. if err != nil {
  182. return err
  183. }
  184. if res.TradeState == wx.CODE_SUCCESS { // 付款成功
  185. order.Status = 1 // 已支付
  186. order.TransactionId = res.TransactionId
  187. if _, err := core.GetXormAuto().ID(order.Id).Cols("status, transaction_id").Update(order); err != nil {
  188. return err
  189. }
  190. if order.GoodType == 1 {
  191. history := new(models.BullyScreenHistory)
  192. exist, err := history.GetByUserOrderId(order.Id)
  193. if err != nil {
  194. return err
  195. }
  196. if !exist {
  197. return errors.New("BullyScreenHistory not exist")
  198. }
  199. if history.Status == -1 {
  200. if _, err := history.UpdateStatus(history.Id, 0); err != nil {
  201. return err
  202. }
  203. }
  204. } else if order.GoodType == 2 {
  205. history := new(models.RewardHistory)
  206. exist, err := history.GetByUserOrderId(order.Id)
  207. if err != nil {
  208. return err
  209. }
  210. if !exist {
  211. return errors.New("RewardHistory not exist")
  212. }
  213. if history.Status == 0 {
  214. break
  215. }
  216. if history.Status == -1 {
  217. if _, err := history.UpdateStatus(history.Id, 0); err != nil {
  218. return err
  219. }
  220. }
  221. } else {
  222. logger.Sugar.Info("支付测试")
  223. }
  224. } else if order.TimeExpire <= time.Now().Format("20060101150405") {
  225. Close(order.OutTradeNo)
  226. order.Status = -1 // 关闭支付
  227. order.TransactionId = res.TransactionId
  228. if _, err := core.GetXormAuto().ID(order.Id).Cols("status, transaction_id").Update(order); err != nil {
  229. return err
  230. }
  231. }
  232. }
  233. return nil
  234. }
  235. func Close(outTradeNo string) (*wechat.CloseOrderResponse, error) {
  236. client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true)
  237. // 初始化参数结构体
  238. body := make(gopay.BodyMap)
  239. body.Set("out_trade_no", outTradeNo)
  240. body.Set("nonce_str", gopay.GetRandomString(32))
  241. body.Set("sign_type", wechat.SignType_MD5)
  242. // 请求关闭订单,成功后得到结果
  243. wxRsp, err := client.CloseOrder(body)
  244. if err != nil {
  245. fmt.Println("Error:", err)
  246. return nil, err
  247. }
  248. fmt.Println("wxRsp:", *wxRsp)
  249. return wxRsp, nil
  250. }