package pay_service import ( "errors" "fmt" "github.com/iGoogle-ink/gopay/v2" "github.com/iGoogle-ink/gopay/v2/wechat" "github.com/ouxuanserver/osmanthuswine/src/core" "hudongzhuanjia/libs/wx" "hudongzhuanjia/logger" "hudongzhuanjia/models" "net/http" "strconv" "time" ) const CALLBACK_ORDER_URL = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackOrder" func Order(content, ip, openid string, fee, goodType int, userId, activityId int64) (map[string]interface{}, error) { client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true) //设置国家 client.SetCountry(wechat.China) now := time.Now() outTradeNo := gopay.GetRandomString(32) nonceStr := gopay.GetRandomString(32) timeStart := now.Format("20060101150405") timeExpire := now.Add(2 * time.Hour).Format("20060101150405") //初始化参数Map body := make(gopay.BodyMap) body.Set("nonce_str", nonceStr) body.Set("body", content) body.Set("out_trade_no", outTradeNo) body.Set("total_fee", fee) body.Set("spbill_create_ip", ip) body.Set("notify_url", CALLBACK_ORDER_URL) body.Set("trade_type", wechat.TradeType_JsApi) body.Set("device_info", "WEB") body.Set("sign_type", wechat.SignType_MD5) body.Set("openid", openid) body.Set("time_start", timeStart) //body.Set("time_expire", timeExpire) //请求支付下单,成功后得到结果 res, err := client.UnifiedOrder(body) if err != nil { return nil, err } //ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res) //if err != nil { // return nil, err //} //if !ok { // return nil, errors.New("签名验证失败") //} if res.ReturnCode != wx.CODE_SUCCESS { return nil, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) } if res.ResultCode != wx.CODE_SUCCESS { return nil, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) } userOrder := new(models.UserOrder) userOrder.DeviceInfo = "WEB" userOrder.Desc = content userOrder.UserId = userId userOrder.ActivityId = activityId userOrder.FeeType = "CNY" userOrder.GoodType = goodType userOrder.OpenId = openid userOrder.OutTradeNo = outTradeNo userOrder.TimeStart = timeStart userOrder.TimeExpire = timeExpire userOrder.TotalFee = fee userOrder.TradeType = wechat.TradeType_JsApi userOrder.PrepayId = res.PrepayId userOrder.Status = 0 userOrder.IsDelete = false userOrder.CreatedAt = time.Now() userOrder.UpdatedAt = time.Now() if _, err := core.GetXormAuto().InsertOne(userOrder); err != nil { return nil, err } timestamp := strconv.FormatInt(time.Now().Unix(), 10) //获取H5支付需要的paySign pac := "prepay_id=" + res.PrepayId paySign := wechat.GetH5PaySign(wx.Appid, res.NonceStr, pac, wechat.SignType_MD5, timestamp, wx.ApiKey) return map[string]interface{}{ "appid": wx.Appid, "timestamp": timestamp, "nonce_str": res.NonceStr, "package": pac, "sign_type": wechat.SignType_MD5, "pay_sign": paySign, "out_trade_no": outTradeNo, "user_order_id": userOrder.Id, }, nil } func CallbackOrder(req *http.Request) error { res, err := wechat.ParseNotifyResult(req) if err != nil { logger.Sugar.Error("解析微信毁掉结果失败") return err } //ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res) //if err != nil { // return err //} //if !ok { // return errors.New("sign verify failed") //} if res.ReturnCode != wx.CODE_SUCCESS { return fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) } if res.ResultCode != wx.CODE_SUCCESS { return fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) } userOrder := new(models.UserOrder) exist, err := userOrder.GetByOutTradeNo(res.OutTradeNo) if err != nil { return err } if !exist { return fmt.Errorf("user order not exist") } userOrder.TimeEnd = res.TimeEnd userOrder.TransactionId = res.TransactionId userOrder.Status = 1 if _, err := core.GetXormAuto().Id(userOrder.Id).Cols("time_end, transaction_id, status").Update(userOrder); err != nil { return err } // 设置一下 if userOrder.GoodType == 1 { // 霸屏 history := new(models.BullyScreenHistory) history.Status = 0 _, err := core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrder.Id).Cols("status").Update(history) return err } else if userOrder.GoodType == 2 { history := new(models.RewardHistory) history.Status = 0 _, err := core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrder.Id).Cols("status").Update(history) return err } logger.Sugar.Infof("%+v", res) return nil } func Query(outTradeNo string) (*wechat.QueryOrderResponse, error) { client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true) client.SetCountry(wechat.China) body := make(gopay.BodyMap) body.Set("out_trade_no", outTradeNo) body.Set("nonce_str", gopay.GetRandomString(32)) body.Set("sign_type", wechat.SignType_MD5) // 请求订单查询,成功后得到结果 res, err := client.QueryOrder(body) if err != nil { logger.Sugar.Errorf("wechat query order error, %s", err) return nil, err } if res.TradeState == wx.CODE_SUCCESS { // 付款成功 userOrder := new(models.UserOrder) userOrder.Status = 1 if _, err := core.GetXormAuto().Where("is_delete=0 and out_trade_no=?", outTradeNo). Cols("status").Update(userOrder); err != nil { return nil, err } } return res, nil } func BatchQueryByUserId(userId int64) error { orders := make([]*models.UserOrder, 0) if err := core.GetXormAuto().Where("is_delete = 0 and status = 0 and user_id = ?", userId).Find(&orders); err != nil { return err } return batchQuery(orders) } func BatchQueryByActivityId(activityId int64) error { orders := make([]*models.UserOrder, 0) if err := core.GetXormAuto().Where("is_delete = 0 and status = 0 and activity_id = ?", activityId).Find(&orders); err != nil { return err } return batchQuery(orders) } func batchQuery(orders []*models.UserOrder) error { for _, order := range orders { res, err := Query(order.OutTradeNo) if err != nil { return err } if res.TradeState == wx.CODE_SUCCESS { // 付款成功 order.Status = 1 // 已支付 order.TransactionId = res.TransactionId if _, err := core.GetXormAuto().ID(order.Id).Cols("status, transaction_id").Update(order); err != nil { return err } if order.GoodType == 1 { history := new(models.BullyScreenHistory) exist, err := history.GetByUserOrderId(order.Id) if err != nil { return err } if !exist { return errors.New("BullyScreenHistory not exist") } if history.Status == -1 { if _, err := history.UpdateStatus(history.Id, 0); err != nil { return err } } } else if order.GoodType == 2 { history := new(models.RewardHistory) exist, err := history.GetByUserOrderId(order.Id) if err != nil { return err } if !exist { return errors.New("RewardHistory not exist") } if history.Status == 0 { break } if history.Status == -1 { if _, err := history.UpdateStatus(history.Id, 0); err != nil { return err } } } else { logger.Sugar.Info("支付测试") } } else if order.TimeExpire <= time.Now().Format("20060101150405") { Close(order.OutTradeNo) order.Status = -1 // 关闭支付 order.TransactionId = res.TransactionId if _, err := core.GetXormAuto().ID(order.Id).Cols("status, transaction_id").Update(order); err != nil { return err } } } return nil } func Close(outTradeNo string) (*wechat.CloseOrderResponse, error) { client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true) // 初始化参数结构体 body := make(gopay.BodyMap) body.Set("out_trade_no", outTradeNo) body.Set("nonce_str", gopay.GetRandomString(32)) body.Set("sign_type", wechat.SignType_MD5) // 请求关闭订单,成功后得到结果 wxRsp, err := client.CloseOrder(body) if err != nil { fmt.Println("Error:", err) return nil, err } fmt.Println("wxRsp:", *wxRsp) return wxRsp, nil }