使用golang快速开发微信公众平台(六):给用户发红包(用户提现至微信钱包)

                                                                                                     
 
 
  1. 给用户发红包

  2. 用户买了商品,剩下的钱,可以自己再提出来。


问题1我纠结了好久,并没有找到合适解决方法,因为按照这个要求,操作由后台发起,由后台执行,而这样做,微信是不允许的这也是为什么我会写一篇关于支付宝提现的帖子,但你去看支付宝的文档,会发现过程极其繁琐,还有时间差,而且微信与支付宝打架,这个功能还得放在微信外的页面,用户体验非常不好。

经过与老板的讨价还价,终于改变为了问题2 : 将发起者改为用户,这样以上的问题,就都不是问题了。

阅读代码之前墙裂建议先看完官方文档

业务场景: 
用户点击页面上的按钮,post请求发送至后台,获取用户的id和要提现的金额,经过校验向用户微信钱包打款。

func (c *WXRedPacketController) Post() {      uid, _ := c.GetSession("uid").(string)     packegtMoney, err := c.GetFloat("packegtMoney", 0)      o := orm.NewOrm()      if err == nil {          //检查用户钱包内是否有这么多钱可供提现         uwallet := models.UserWallet{Uid:uid}         if _, _, err := o.ReadOrCreate(&uwallet, "uid"); err == nil {              umoney, _ := strconv.ParseFloat(uwallet.Money, 64)             if umoney >= packegtMoney {                  //提现至微信红包                 str_req := makeRedPacketXML(packegtMoney, uid)                 if ok, errInfo := sendRedPacketRequest(str_req, uid); ok {                      uwallet.Money = strconv.FormatFloat(math.Floor((umoney - packegtMoney) * 100) / 100, 'f', 2, 64)                     _, err := o.Update(&uwallet, "money")                     if err != nil {                         fmt.Println("用户提现更新钱包失败", err)                         logUtils.GetLog().Error("用户提现更新钱包失败", err)                         c.Data["errinfo"] = "更新钱包失败"                     } else {                         //插入 wallet-his                         _, err = o.Insert(&models.UserWalletHis{Uid:uid, MoneyChange:strconv.FormatFloat(math.Floor(packegtMoney * 100) / 100, 'f', 2, 64), BonusChange:"0", ChangeReason:models.DRAW, BankType:"", BankNum:"", ReasonOrder:"", ReasonPerson:"", CreateTime:time.Now().Format(TIMELAYOUT), })                         if err != nil {                             fmt.Printf("插入 UserWalletHis 错误 %v", err)                             logUtils.GetLog().Error("插入 UserWalletHis 错误 %v", err)                         }                     }                      c.Redirect("/wx_red_packet", 302)                 } else {                     c.Data["errinfo"] = errInfo                 }              } else {                 c.Data["errinfo"] = "钱包余额不足"             }         } else {             c.Data["errinfo"] = "钱包查询错误"         }     }      c.Data["money"] = showWalletMoney(o, uid)//可提现     c.TplName = "wx_red_packget.html"}  //生成红包的申请xml money 提现的金额 元 func makeRedPacketXML(money float64, uid string) string {      //拼接xml     var redPacket models.RedPacket     redPacket.Nonce_str = RandomStrUtil.GetRandomString(32)     redPacket.Mch_billno = beego.AppConfig.String("shopKey") + time.Now().Format(TIMELAYOUT3) + strconv.FormatInt(time.Now().Unix(), 10)     redPacket.Mch_id = beego.AppConfig.String("shopKey")     redPacket.Appid = beego.AppConfig.String("APPID")     redPacket.Send_name = "商城"     redPacket.Re_openid = uid     redPacket.Total_amount = int(money * 100)//分钱     redPacket.Total_num = 1     redPacket.Wishing = "收红包啦"     redPacket.Client_ip = "122.122.122.122"     redPacket.Act_name = "红包名称"     redPacket.Remark = "红包说明"      var n map[string]interface{}     n = make(map[string]interface{}, 0)     n["nonce_str"] = redPacket.Nonce_str     n["mch_billno"] = redPacket.Mch_billno     n["mch_id"] = redPacket.Mch_id     n["wxappid"] = redPacket.Appid     n["send_name"] = redPacket.Send_name     n["re_openid"] = redPacket.Re_openid     n["total_amount"] = redPacket.Total_amount     n["total_num"] = redPacket.Total_num     n["wishing"] = redPacket.Wishing     n["client_ip"] = redPacket.Client_ip     n["act_name"] = redPacket.Act_name     n["remark"] = redPacket.Remark      redPacket.Sign = wxpayCalcSign(n, PAY_API_KEY) //这个key 微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全      bytes_req, err := xml.Marshal(redPacket)     if err != nil {         fmt.Println("转换为xml错误:", err)         logUtils.GetLog().Error("转换为xml错误:", err)     }      str_req := strings.Replace(string(bytes_req), "RedPacket", "xml", -1)     fmt.Println("发红包参数转换为xml--------", str_req)     return str_req }  func sendRedPacketRequest(str_req, uid string) (bool, string) {      bytes_req := []byte(str_req)      //发送unified order请求.     req, err := http.NewRequest("POST", "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack", bytes.NewReader(bytes_req))     if err != nil {         fmt.Println("发送红包 Request发生错误,原因:", err)         logUtils.GetLog().Error("发送红包 Request发生错误,原因:", err)         return false, "未知错误"      }     req.Header.Set("Accept", "application/xml")     //这里的http header的设置是必须设置的.     req.Header.Set("Content-Type", "application/xml;charset=utf-8")      tlsConfig, err := WxPlatUtil.GetTLSConfig()     if err != nil {         fmt.Println("解析证书出现错误", err)         return false, "未知错误"     }      tr := &http.Transport{TLSClientConfig: tlsConfig}     client := &http.Client{Transport: tr}      resp, _err := client.Do(req)     if _err != nil {         fmt.Println("请求发送红包接口发送错误, 原因:", _err)         logUtils.GetLog().Error("请求发送红包接口发送错误, 原因:", _err)         return false, "未知错误"     }      respBytes, err := ioutil.ReadAll(resp.Body)     if err != nil {         fmt.Println("请求发送红包解析返回body错误", err)         logUtils.GetLog().Error("请求发送红包解析返回body错误", err)         return false, "未知错误"     } else {         fmt.Println("请求发送红包解析返回===================>", string(respBytes))         redPacketRes := models.RedPacketRes{}         if err := xml.Unmarshal(respBytes, &redPacketRes); err == nil {              recodeRedPacketRes(&redPacketRes, uid)//记录存入数据库              if redPacketRes.Return_code == "SUCCESS" {                  if redPacketRes.Result_code == "SUCCESS" {                      return true, "红包领取成功"                 } else {                     return false, redPacketRes.Err_code_des                 }              } else {                 //签名失败                 return false, "微信签名失败"             }          } else {             fmt.Println("红包领取记录解析错误", err)             logUtils.GetLog().Error("红包领取记录解析错误", err)         }     }      return false, "未知错误"}  func wxpayCalcSign(mReq map[string]interface{}, key string) string {      //fmt.Println("========STEP 1, 对key进行升序排序.========")     //fmt.Println("微信支付签名计算, API KEY:", key)     //STEP 1, 对key进行升序排序.     sorted_keys := make([]string, 0)     for k, _ := range mReq {         sorted_keys = append(sorted_keys, k)     }      sort.Strings(sorted_keys)      //fmt.Println("========STEP2, 对key=value的键值对用&连接起来,略过空值========")     //STEP2, 对key=value的键值对用&连接起来,略过空值     var signStrings string     for _, k := range sorted_keys {         //fmt.Printf("k=%v, v=%v/n", k, mReq[k])         value := fmt.Sprintf("%v", mReq[k])         if value != "" {             signStrings = signStrings + k + "=" + value + "&"         }     }      //fmt.Println("========STEP3, 在键值对的最后加上key=API_KEY========")     //STEP3, 在键值对的最后加上key=API_KEY     if key != "" {         signStrings = signStrings + "key=" + key     }      //fmt.Println("========STEP4, 进行MD5签名并且将所有字符转为大写.========")     //STEP4, 进行MD5签名并且将所有字符转为大写.     md5Ctx := md5.New()     md5Ctx.Write([]byte(signStrings))     cipherStr := md5Ctx.Sum(nil)     upperSign := strings.ToUpper(hex.EncodeToString(cipherStr))      return upperSign }  func recodeRedPacketRes(redPacketRes *models.RedPacketRes, uid string) {      //插入数据库 红包领取记录     o := orm.NewOrm()     wxUser := models.WxUser{WxId:uid}     if err := o.Read(&wxUser, "wx_id"); err == nil {         redPacketHis := models.RedPacketResHis{RedPacketRes:*redPacketRes, Name:wxUser.Name, Phone:wxUser.Phone, CreateTime:time.Now().Format(TIMELAYOUT)}         _, err := o.Insert(&redPacketHis)         if err != nil {             fmt.Println("插入红包领取记录错误", err)             logUtils.GetLog().Error("红包领取记录", err)         }     } else {         fmt.Println("查询用户信息错误", err)         logUtils.GetLog().Error("查询用户信息错误", err)     } }

这就OK啦,用户的微信钱包是实时更新的。当然要是想再友好点,可以给用户发个消息,下一篇,就来写微信的客服功能。

本文来自:CSDN博客

感谢作者:u012210379

查看原文:使用golang快速开发微信公众平台(六):给用户发红包(用户提现至微信钱包)




查看原文:http://www.zoues.com/2016/10/27/%e4%bd%bf%e7%94%a8golang%e5%bf%ab%e9%80%9f%e5%bc%80%e5%8f%91%e5%be%ae%e4%bf%a1%e5%85%ac%e4%bc%97%e5%b9%b3%e5%8f%b0%e5%85%ad%e7%bb%99%e7%94%a8%e6%88%b7%e5%8f%91%e7%ba%a2%e5%8c%85%e7%94%a8%e6%88%b7/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值