党费收缴管理系统(十二) 获取微信支付资金账单数据

本文介绍了如何通过微信支付API获取GZIP压缩的资金账单文件,包括正确设置请求参数、下载并解压缩文件,以及对解压后文件进行SHA1校验的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        这次解决两个技术点,一个是如何对下载的资金账单GZIP文件来进行hash校验,另外一个就是如何解压缩GZIP的文件.对hash校验走了点弯路,还好及时发现,没有浪费时间.

  1. 通过接口获取微信支付资金数据

        微信支付按天提供微信支付账户的资金流水账单文件,当日账单在次日上午9点开始生成,建议商户在上午10点以后获取;资金账单中涉及金额的字段单位为“元”。标记红色是都需要注意的.

接口地址: https://api.mch.weixin.qq.com/v3/bill/fundflowbill

请求的参数:   Header 头必须带上  Authorization , Accept 设置为 application/json

Query 参数有
        bill_date  : 账单日期  
        account_type  资金账户类型   BASIC: 基本账户   OPERATION: 运营账户    FEES: 手续费账户
        tar_type: GZIP   压缩格式,不填则以不压缩的方式返回数据流可选取值:

   注意:  这里提交参数的方式是GET, 我习惯性的使用了POST,一直报405错误, 后面错误码里面又没找到405, 折腾了一会才发现这个问题.
   接口返回数据格式如下:

{
 "hash_type": "SHA1",
 "hash_value": "79bb0f45fc4c42234a918000b2668d689e2bde04",
 "download_url": " https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx"
}

        核心就是拿到download_url 数据, 注意这个链接的有效期只有5分钟.

 string url = "https://api.mch.weixin.qq.com/v3/bill/fundflowbill";
 HttpClient client = new HttpClient(new HttpHandler(WxPayTool.mchId, WxPayTool.serialNO));      
 string queryString = $"bill_date={riqi}&account_type=BASIC&tar_type=GZIP";       
 var response = client.GetAsync(url + "?" + queryString);
 var rep = response.Result;   
 var respStr = rep.Content.ReadAsStringAsync().Result;
 JObject  downObject = JObject.Parse(respStr);

        2. 下载账单数据:

        这里我也想当然的以为直接读取链接然后保存文件就可以了. 结果失败.看文档才知道一样的需要对downurl 进行签名,然后发起请求方可以下载.

  string  filename =   Path.Combine(hostEnvironment.WebRootPath,"bill", Guid.NewGuid().ToString()+".gzip");  //定义下载文件名
  string csvFileName = Path.Combine(hostEnvironment.WebRootPath, "bill", riqi +".csv" );  //解压缩后的文件名
  string downurl = downObject["download_url"].ToString();
  string fileHashCode = downObject["hash_value"].ToString();
  var  downresp = client.GetAsync(downurl);   
  var   downrep  = downresp.Result;
  using (Stream reader = downresp.Result.Content.ReadAsStream()) {
      using (FileStream writer = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write))
      {
          byte[] buffer = new byte[1024];
          int c = 0;
          while ((c = reader.Read(buffer, 0, buffer.Length)) > 0)
          {
              writer.Write(buffer, 0, c);
          }
      }
  }

        3. 解压缩gzip数据

        直接在网上找到的解压缩文件代码

 public static void DeCompressFile(String compressPath, String DecompressPath)
 {
     int fileszie = (int) new FileInfo(compressPath).Length;
     byte[] buffer = new byte[fileszie];
     using (FileStream fileStream = new FileStream(compressPath, FileMode.Open, FileAccess.Read)) { 
         using(BinaryReader binaryReader = new BinaryReader(fileStream))
         {
             binaryReader.BaseStream.Seek(0, SeekOrigin.Begin);
             buffer = binaryReader.ReadBytes(fileszie);
             binaryReader.Close();

         }
         fileStream.Close();
     
     }
     using(MemoryStream memoryStream = new MemoryStream(buffer)) {
         using(GZipStream zipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) {
             using(MemoryStream resutlStream = new MemoryStream())
             {
                 int readLength = 1024;
                 byte[] buf = new byte[readLength];
                 int len = 0;
                 while ((len = zipStream.Read(buf, 0, readLength)) > 0) { 
                     resutlStream.Write(buf, 0, len);    
                 }
                 using(FileStream fs = new FileStream(DecompressPath,FileMode.Create, FileAccess.ReadWrite)) {
                     using(BinaryWriter  bw = new BinaryWriter(fs)) { 
                         bw.Write(resutlStream.ToArray());   
                         bw.Flush();
                         bw.Close(); 
                     }
                   fs.Close();
                 }
             }
         }
     }

 }

        4. 进行HASH校验

        为什么在这里才写hash校验, 因为我之前也是想当然得也为hash值码是下载的GZIP文件的校验码,然而并不是, 校验的是解压缩后的文件.  同样在网上找到的校验代码了.   到此账单就是下载完成了,后续如何读取就很简单了,字段含义都很清晰.     

public static  class HashHelper
{
    
    ///<summary>
    ///  计算指定文件的SHA1值
    ///</summary>
    /// <paramname="fileName">指定文件的完全限定名称</param>
    ///<returns>返回值的字符串形式</returns>
    public static string   ComputeSHA1(String fileName)
    {
        String hashSHA1 = String.Empty;
        //检查文件是否存在,如果文件存在则进行计算,否则返回空值
        if (System.IO.File.Exists(fileName))
        {
            using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                //计算文件的SHA1值
                System.Security.Cryptography.SHA1 calculator = System.Security.Cryptography.SHA1.Create();
                Byte[] buffer = calculator.ComputeHash(fs);
                calculator.Clear();
                //将字节数组转换成十六进制的字符串形式
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < buffer.Length; i++)
                {
                    stringBuilder.Append(buffer[i].ToString("x2"));
                }

                hashSHA1 = stringBuilder.ToString();

            }//关闭文件流
        }

        return hashSHA1;
    } 


}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT大灰狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值