微信支付-批次核销明细下载 API

  •   相关官方文档

​​​​​​下载批次核销明细icon-default.png?t=N7T8https://pay.weixin.qq.com/docs/merchant/apis/cash-coupons/stock/use-flow.html如何生成请求签名icon-default.png?t=N7T8https://pay.weixin.qq.com/docs/merchant/development/interface-rules/signature-generation.html如何使用V3验签工具校验签名icon-default.png?t=N7T8https://developers.weixin.qq.com/community/develop/article/doc/00084630cf40e82afc2c843eb5b413

签名相关问题icon-default.png?t=N7T8https://pay.weixin.qq.com/docs/merchant/development/interface-rules/signature-faqs.html

 代码实现

验签

参数说明:

        url:请求地址url

        paymentData : 微信支付配置 

               主要参数: mch_id    微信支付商户号

                                  sn            序列号

                                  key_path  : 证书路径   私钥

        stockId :    批次号                

public static String createAuth(String url,JSONObject paymentData,String stockId){
        //组装Authorization 以及签名
        String schema = "WECHATPAY2-SHA256-RSA2048";
        //时间戳
        long timestamp = System.currentTimeMillis() / 1000L;
        //随机串
        String s = OrderNoGeneratorUtil.generateOrderNumber("");
        String method = "GET";
        //批次号
        String stock_id = stockId;
        HttpUrl httpurl = HttpUrl.parse(url);
        String body = "";
        //商户号
        String yourMerchantId = paymentData.getString("mch_id");
        //证书序列号
        String yourCertificateSerialNo = paymentData.getString("sn");
        String signature = null;
        String preSign = buildMessage(method, httpurl, timestamp, s, body);
        try {
            signature = sign(preSign.getBytes("utf-8"),paymentData.getString("key_path").substring(1));
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("签名:" + signature);
        return schema + " mchid=\"" + yourMerchantId + "\","
                + "nonce_str=\"" + s + "\","
                + "timestamp=\"" + timestamp + "\","
                + "serial_no=\"" + yourCertificateSerialNo + "\","
                + "signature=\"" + signature + "\"";
    }
private static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
        String canonicalUrl = url.encodedPath();
        if (url.encodedQuery() != null) {
            canonicalUrl += "?" + url.encodedQuery();
        }
        System.out.println(method + "\n" + canonicalUrl + "\n" + timestamp + "\n" + nonceStr + "\n" + body);

        return method + "\n"
                + canonicalUrl + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + body + "\n";
    }
/***
     * 对签名串进行RSA2加签
     */
    private static String sign(byte[] message,String keyPath) throws Exception {
        Signature sign = Signature.getInstance("SHA256withRSA");
        //微信支付私钥
        String content = new String(Files.readAllBytes(Paths.get(keyPath)), "utf-8");
        try {
            String privateKeyStr = content.replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "");
            KeyFactory kf = KeyFactory.getInstance("RSA");
            PrivateKey privateKey =  kf.generatePrivate(
                    new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyStr)));
            sign.initSign(privateKey);
            sign.update(message);
            return Base64.getEncoder().encodeToString(sign.sign());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持RSA", e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("无效的密钥格式");
        }
    }
 请 求接口   下载批次核销明细
//设置HTTP Authorization头
String hostUrl = "https://api.mch.weixin.qq.com";
//stock_id 替换成已有的值
String method = "v3/marketing/favor/stocks/{stock_id}/use-flow";
//GET请求(官网)
    HttpGet httpGet = new HttpGet(hostUrl + method);
    httpGet.addHeader("Accept", "application/json");
    httpGet.addHeader("Authorization", auth);
    response = httpClient.execute(httpGet);
//POST请求
  HttpPost httpPost = new HttpPost(hostUrl + method);
  StringEntity reqEntity = new StringEntity(
  requestJson, ContentType.create("application/json", "utf-8"));
  httpPost.setEntity(reqEntity);
  httpPost.addHeader("Accept", "application/json");
  httpPost.addHeader("Authorization", auth);
  response = httpClient.execute(httpPost);

HttpEntity resEntity = response.getEntity();
String retMsg = EntityUtils.toString(resEntity, "UTF-8");// 微信返回的参数
  •  返回参数示例:url是储存在微信服务器的文件地址
{
  "url" : "https://api.mch.weixin.qq.com/v3/billdownload/file?token=ja7q-s1yy1ZbROASakz0Jx4BjW3qdnympjfcB4v4yLftXXXXXXXXXXXX",
  "hash_value" : "8ae0eb442c408d2e90d669d6f4ad6b7e6e049d6f",
  "hash_type" : "SHA1"
}
请求返回的url

url 无法直接请求,需要加上请求头 

Authorization: 认证类型 签名信息

Authorization: WECHATPAY2-SHA256-RSA2048 mchid="1900009191",nonce_str="593BEC0C930BF1AFEB40B4A08C8FB242",signature="uOVRnA4qG/MNnYzdQxJanN+zU+lTgIcnU9BxGw5dKjK+VdEUz2FeIoC+D5sB/LN+nGzX3hfZg6r5wT1pl2ZobmIc6p0ldN7J6yDgUzbX8Uk3sD4a4eZVPTBvqNDoUqcYMlZ9uuDdCvNv4TM3c1WzsXUrExwVkI1XO5jCNbgDJ25nkT/c1gIFvqoogl7MdSFGc4W4xZsqCItnqbypR3RuGIlR9h9vlRsy7zJR9PBI83X8alLDIfR1ukt1P7tMnmogZ0cuDY8cZsd8ZlCgLadmvej58SLsIkVxFJ8XyUgx9FmutKSYTmYtWBZ0+tNvfGmbXU7cob8H/4nLBiCwIUFluw==",timestamp="1554208460",serial_no="1DDE55AD98ED71D6EDD4A4A16996DE7B47773A8C"

 要保证:要保证与 下载批次核销明细的时间戳(timestamp)  随机数(s)  商户号(mch_id)  证书(私钥)(key_path) 序列号(sn) 批次号(stockId) 一致

//读取数据
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
     .url(url)   //  url为下载核销明细api返回url
     .header("Accept", "application/json")
     .header("Authorization",auth)
     .build();
try {
    Response response = okHttpClient.newCall(request).execute();
    if (response.isSuccessful()) {
        response.body().string();
    }
} catch (IOException e) {
    e.printStackTrace();
}
错误
  • 验签错误

没有保证两次生成验签的数据一致   

  •  请求头 的Authorization 是两部分组成

Authorization: 认证类型 签名信息

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值