使用golang快速开发微信公众平台(九):下载对账单
来源:互联网 发布:阿里云国际版怎么注册 编辑:程序博客网 时间:2024/04/28 07:21
首先,对账单是csv格式的;其次,对账单不是非常标准非常标准的csv格式——你直接解析会挂掉。
所以我采用的方式为:把对账单分为2部分,先写第1部分,再把第2部分拼进去。
唉卧槽他大爷的微信。
package controllersimport ( "github.com/astaxie/beego" "monkeyServer/shopUtils/RandomStrUtil" "encoding/xml" "strings" "net/http" "bytes" "io/ioutil" "fmt" "os" "encoding/csv" "io" "log")type AdminWXBillsController struct { beego.Controller}func (c *AdminWXBillsController) Post() { c.EnableRender = false //查询哪一天的对账单 date := c.GetString("wxDate", "") if len(date) != 8 || date == "" { c.Ctx.WriteString("日期参数长度错误") } //https://api.mch.weixin.qq.com/pay/downloadbill //商户可以通过该接口下载历史交易清单。比如掉单、系统错误等导致商户侧和微信侧数据不一致,通过对账单核对后可校正支付状态。 //注意: //1、微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账单中,跟原支付单订单号一致; //2、微信在次日9点启动生成前一天的对账单,建议商户10点后再获取; //3、对账单中涉及金额的字段单位为“元”。 //4、对账单接口只能下载三个月以内的账单。 //首先定义一个UnifyOrderReq用于填入我们要传入的参数。 type WXBillReq struct { Appid string `xml:"appid"` //公众账号ID Mch_id string `xml:"mch_id"` //商户号 Nonce_str string `xml:"nonce_str"` //随机字符串 Sign string `xml:"sign"` //签名 BillDate string `xml:"bill_date"` //下载对账单的日期,格式:20140603 BillType string `xml:"bill_type"` //ALL,返回当日所有订单信息,默认值 SUCCESS,返回当日成功支付的订单 REFUND,返回当日退款订单 RECHARGE_REFUND,返回当日充值退款订单(相比其他对账单多一栏“返还手续费”) } type WXBillResp struct { Return_code string `xml:"return_code"` Return_msg string `xml:"return_msg"` } var yourReq WXBillReq yourReq.Appid = beego.AppConfig.String("APPID") yourReq.Mch_id = beego.AppConfig.String("Mchid") yourReq.Nonce_str = RandomStrUtil.GetRandomString(32) yourReq.BillDate = date yourReq.BillType = "ALL" var m map[string]interface{} m = make(map[string]interface{}, 0) m["appid"] = yourReq.Appid m["mch_id"] = yourReq.Mch_id m["nonce_str"] = yourReq.Nonce_str m["bill_date"] = yourReq.BillDate m["bill_type"] = yourReq.BillType yourReq.Sign = wxpayCalcSign(m, WX_PAY_API_KEY) //这个key 微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全 bytes_req, err := xml.Marshal(yourReq) if err != nil { beego.Error("wxpay转换为xml错误:", err) return } str_req := strings.Replace(string(bytes_req), "UnifyOrderReq", "xml", -1) //beego.Error("请求UnifiedOrder 拼接 xml 完成--------", str_req) bytes_req = []byte(str_req) //发送unified order请求. req, err := http.NewRequest("POST", "https://api.mch.weixin.qq.com/pay/downloadbill", bytes.NewReader(bytes_req)) if err != nil { beego.Error("New Http Request发生错误,原因:", err) return } req.Header.Set("Accept", "application/xml") //这里的http header的设置是必须设置的. req.Header.Set("Content-Type", "application/xml;charset=utf-8") client := http.Client{} resp, _err := client.Do(req) if _err != nil { beego.Error("请求微信对账单接口发送错误, 原因:", _err) return } beego.Error("请求微信对账单接口已经执行完成") respBytes, err := ioutil.ReadAll(resp.Body) if err != nil { beego.Error("解析返回body错误", err) return } defer resp.Body.Close() xmlResp := WXBillResp{} _err = xml.Unmarshal(respBytes, &xmlResp) if xmlResp.Return_code == "FAIL" { fmt.Printf("请求微信对账单失败 %+v\n:", xmlResp) } else { newPath := createWxBillCSVFile(date) in := string(respBytes) in = strings.Replace(in, "`", "", -1) spliteAfter := strings.Split(in, "总交易单数") r := csv.NewReader(strings.NewReader(spliteAfter[0])) resultStr := make([][]string, 0) for { record, err := r.Read() if err == io.EOF { break } if err != nil { log.Fatal(err) } resultStr = append(resultStr, record) } //写入文件 f, err := os.Create(newPath)//创建文件 if err != nil { beego.Error("创建csv文件错误", err) } defer f.Close() w := csv.NewWriter(f)//创建一个新的写入文件流 err = w.WriteAll(resultStr)//写入数据 w.Flush() //再读取文件 把因为分割缺少的文字补进来 r2 := csv.NewReader(strings.NewReader(strings.Replace(spliteAfter[1], ",总交易额", "总交易单数,总交易额", -1))) resultStr2 := make([][]string, 0) for { record2, err := r2.Read() if err == io.EOF { break } if err != nil { log.Fatal(err) } resultStr2 = append(resultStr2, record2) } //写入剩下2行 w2 := csv.NewWriter(f) //创建一个新的写入文件流 w2.WriteAll(resultStr2) //写入数据 w2.Flush() c.Ctx.WriteString(string(respBytes)) }}func createWxBillCSVFile(date string) string { dirPath := "static/wxcsv/" if !IsFileExist(dirPath) { err := os.MkdirAll(dirPath, 0) beego.Error("创建csv文件夹存在错误 ", err) } newPath := dirPath + date + ".csv" if IsFileExist(newPath) { err := os.Remove(newPath) if err != nil { beego.Error("删除旧的csv文件错误", err) } } return newPath}
阅读全文
0 0
- 使用golang快速开发微信公众平台(九):下载对账单
- 使用golang快速开发微信公众平台(五):公众号支付
- 微信开发下载对账单-公众号支付开发-视频教程12
- 使用Delphi Xe8 开发微信功能 -- (一)微信支付商户平台之对账单下载
- 使用golang快速开发微信公众平台(一):开启服务器配置
- 使用golang快速开发微信公众平台(二):获取accessToken
- 使用golang快速开发微信公众平台(三):定制菜单
- 使用golang快速开发微信公众平台(四):网页授权
- 使用golang快速开发微信公众平台(六):给用户发红包(用户提现至微信钱包)
- 使用golang快速开发微信公众平台(七):通过客服向用户发消息
- 使用golang快速开发微信公众平台(六):给用户发红包(用户提现至微信钱包)
- 使用golang快速开发微信公众平台(八):获取用户二维码
- 使用Golang开发微信公众平台----接入验证
- 使用Golang开发微信公众平台----接收消息
- 微信公众平台快速开发框架
- golang 实现微信公众平台API引擎开发模式
- 使用Golang开发微信公众平台----自定义菜单(删除、新
- 微信支付开发(3) 对账单
- post请求
- Lavarel文件上传
- 【补充】ARM MMU页表框架
- LeetCode
- python-练习4
- 使用golang快速开发微信公众平台(九):下载对账单
- 10分钟学会如何使用Shiro
- 安卓实现okhttp上传视频到php服务器
- Leetcode Sort List
- Github入门教程
- 线性结构——单链表
- asp.net c# 發送mail
- html 网站发布到公网
- Codeforces 459D Pashmak and Parmida's problem【树状数组】