使用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
原创粉丝点击