golang下载支付宝对账单

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u012210379/article/details/74979813

GRD支付宝,就不能不用zip来打包吗!!!!!
支付宝的对账单下载并不复杂,但他特么的就是不告诉你用GET还是用POST发送,发错了还给你甩一堆HTML过来,还都是乱码,唉卧槽他大爷坑了我2天时间。
下载及处理zip如下:

package controllers

import (
    "github.com/astaxie/beego"
    "time"
    "monkeyServer/shopUtils/timeUtils"
    "fmt"
    "net/http"
    "io/ioutil"
    "net/url"
    "encoding/json"
    "monkeyServer/shopUtils/logUtils"
    "os"
    "archive/zip"
    "strings"
    "io"
)

type AdminAliBillsController struct {
    beego.Controller
}

func (c *AdminAliBillsController) Post() {
    c.EnableRender = false
    //checkLogin.CheckAdminLogin(c.Ctx)

    date := c.GetString("alDate", "")
    date = "2017-07-08"
    if len(date) != 10 || date == "" {
        c.Ctx.WriteString("日期参数长度错误")
    }

    m := make(map[string]interface{})
    m["app_id"] = ALI_APP_ID
    m["method"] = "alipay.data.dataservice.bill.downloadurl.query"
    m["charset"] = "utf-8"
    m["sign_type"] = "RSA"
    m["timestamp"] = time.Now().Format(timeUtils.TIMELAYOUT)
    m["version"] = "1.0"
    //bill_type:trade指商户基于支付宝交易收单的业务账单;signcustomer是指基于商户支付宝余额收入及支出等资金变动的帐务账单
    m["biz_content"] = `{"bill_type":"trade","bill_date":"` + date + `"}`

    sign := aliPaySign(m)
    //签名
    encodStr := ""
    for k, _ := range m {
        //所有一级value(biz_content作为一个value)进行encode
        value := fmt.Sprintf("%v", m[k])
        encodStr = encodStr + k + "=" + url.QueryEscape(value) + "&"
        //encodStr = encodStr + k + "=" + value + "&"
    }
    encodStr = encodStr + "sign=" + url.QueryEscape(sign)

    //beego.Error("组合的请求 ", encodStr)

    resp, err := http.Get("https://openapi.alipay.com/gateway.do?" + encodStr)
    if err != nil {
        beego.Error("发起对账单get请求错误", err)
        logUtils.GetLog().Error("发起对账单get请求错误", err)
    } else {
        defer resp.Body.Close()
        body, err := ioutil.ReadAll(resp.Body)
        if err != nil {
            beego.Error("解析对账单get返回错误", err)
            logUtils.GetLog().Error("解析对账单get返回错误", err)
        } else {
            //result := string(body)
            //beego.Error("解析对账单get返回ok ", result)

            type alipay_bill_response struct {
                Code            string `json:"code"`
                Msg             string `json:"msg"`
                BillDownloadUrl string `json:"bill_download_url"`
            }

            type aliBillResp struct {
                Alipay_bill_response *alipay_bill_response `json:"alipay_data_dataservice_bill_downloadurl_query_response"`
                Sign                 string                `json:"sign"`
            }

            var ar aliBillResp
            uerr := json.Unmarshal(body, &ar)
            if uerr == nil {

                fmt.Printf("%+v\n", ar.Alipay_bill_response)

                if ar.Alipay_bill_response.Code == "10000" && ar.Alipay_bill_response.Msg == "Success" {
                    beego.Error("解析对账单下载地址为 ", ar.Alipay_bill_response.BillDownloadUrl)

                    //下载并保存csv.zip
                    saveAliBillZip(ar.Alipay_bill_response.BillDownloadUrl, date)
                } else {
                    beego.Error("code及msg不正确", ar)
                    logUtils.GetLog().Error("code及msg不正确", ar)
                }
            } else {
                beego.Error("解析对账单json转换错误", uerr)
                logUtils.GetLog().Error("解析对账单json转换错误", uerr)
            }
        }
    }

}

//下载对账zip文件 解压缩 删除文件
func saveAliBillZip(downUrl, billDate string) {

    resp, err := http.Get(downUrl)
    if err == nil {

        defer resp.Body.Close()
        body, err := ioutil.ReadAll(resp.Body)
        if err != nil {
            beego.Error("解析下载ali对账zip结果错误", err)
            logUtils.GetLog().Error("解析下载ali对账zip结果错误", err)
        } else {

            zipPath := createAlBillCSVZipFile(billDate)
            err := ioutil.WriteFile(zipPath, body, os.ModeAppend)
            if err == nil {
                beego.Error("zip文件写入成功")

                unZipAliZip(zipPath)

            } else {
                beego.Error("ali zip文件写入失败", err)
                logUtils.GetLog().Error("ali zip文件写入失败", err)
            }
        }

    } else {
        beego.Error("获取地址之后下载ali对账zip失败", err)
        logUtils.GetLog().Error("获取地址之后下载ali对账zip失败", err)
    }
}

//解压缩zip包
func unZipAliZip(zipPath string) {


    rc, err := zip.OpenReader(zipPath)
    defer rc.Close()

    if err != nil {
        beego.Error("打开ali zip文件失败", err)
        logUtils.GetLog().Error("打开ali zip文件失败", err)
        return
    }

    for _, _file := range rc.File {

        //带括号的是汇总 不带括号的是明细
        fmt.Println("未进行转换之前:", _file.Name, len(_file.Name), strings.Contains(_file.Name, "("))

        f, err := _file.Open()
        if err != nil {
            beego.Error("读取alicsv文件失败", err)
            logUtils.GetLog().Error("读取alicsv文件失败", err)
            return
        }

        //把第一个下划线之前的字符全部去除 20887124614165740156_20170708_业务明细.csv
        csvName:=_file.Name[strings.Index(_file.Name, "_") + 1:]
        newCsvPath := "static/alicsv/" + csvName
        desfile, err1 := os.OpenFile(newCsvPath, os.O_CREATE | os.O_WRONLY, os.ModePerm)
        if err1 != nil {
            beego.Error("创建alicsv文件失败", err1)
            logUtils.GetLog().Error("创建alicsv文件失败", err1)
            return
        }

        _, err = io.CopyN(desfile, f, int64(_file.UncompressedSize64))
        if err != nil {
            beego.Error("写入alicsv文件失败", err)
            logUtils.GetLog().Error("写入alicsv文件失败", err)
            return
        }

        desfile.Close()
    }

    //删除压缩文件
    os.Remove(zipPath)
}

func createAlBillCSVZipFile(date string) string {

    dirPath := "static/alicsv/"
    if !IsFileExist(dirPath) {
        os.MkdirAll(dirPath, 0)
    }
    newPath := dirPath + date + ".csv.zip"
    if IsFileExist(newPath) {
        err := os.Remove(newPath)
        if err != nil {
            beego.Error("删除旧的csv文件错误", err)
        }
    }
    return newPath
}
展开阅读全文

支付API: 下载账单

06-17

<p>n <span style="font-size:12pt;"><span>帮助学员快速掌握微信支付开发</span>, <span>并提供相关工具及封装类使得学员开发周期从</span><span>2-4</span><span>周的时间缩短至</span><span>2-4</span><span>天</span><span>.</span></span><span style="font-size:12pt;"></span>n</p>n<p>n <span style="font-size:12pt;"><span>培训目标</span></span><span style="font-size:12pt;"></span>n</p>n<p>n <span style="font-size:12pt;">1.<span>掌握微信支付相关账号开通</span><span>,</span><span>应用场景及流程</span></span><span style="font-size:12pt;"></span>n</p>n<p>n <span style="font-size:12pt;">2.<span>掌握微信支付开发环境的搭建及</span><span>web2py</span><span>使用</span><span>.</span></span><span style="font-size:12pt;"></span>n</p>n<p>n <span style="font-size:12pt;">3.<span>学会相关</span><span>api</span><span>的使用</span></span><span style="font-size:12pt;"></span>n</p>n<p>n <span style="font-size:12pt;">4.</span><span style="font-size:12pt;"><span>跟老师一起</span></span><span style="font-size:12pt;"><span>进行需求分析</span>,接口</span><span style="font-size:12pt;"><span>设计</span></span><span style="font-size:12pt;"><span>完成</span>api</span><span style="font-size:12pt;"><span>封装类</span></span><span style="font-size:12pt;"><span>的开发</span></span><span style="font-size:12pt;">,进一步简化微信支付开发</span><span style="font-size:12pt;"></span>n</p>n<p>n <span style="font-size:12pt;">5.<span>使用课程提供的工具及新设计的</span><span>python</span><span>类</span><span>,</span><span>将开发周期从</span><span>2-4</span><span>周缩短至</span><span>2-4</span><span>天</span></span><span style="font-size:12pt;"></span>n</p>n<p style="text-align:left;">n <span style="font-size:10.5pt;"> </span>n</p>n<p>n <span style="font-size:12pt;"><span>培训内容主要分为</span>5<span>大部分</span><span>: </span></span><span style="font-size:12pt;"><br /></span><span style="font-size:12pt;">1.<span>微信支付相关账号开通</span><span>,</span><span>应用场景及支付流程</span></span><span style="font-size:12pt;"><br /></span><span style="font-size:12pt;">2.<span>开发环境搭建及相关工具介绍</span></span><span style="font-size:12pt;"><br /></span><span style="font-size:12pt;">3.web<span>框架</span><span>web2py</span><span>的使用</span></span><span style="font-size:12pt;"><br /></span><span style="font-size:12pt;">4.<span>设计</span><span>WxPay</span><span>类</span><span>, </span><span>封装</span><span>api</span><span>调用</span></span><span style="font-size:12pt;"><br /></span><span style="font-size:12pt;">5.<span>使用封装类进行微信支付开发</span></span><span style="font-size:12pt;"></span>n</p>n<br />

没有更多推荐了,返回首页