收藏
回答

微信支付(服务商/电商平台) 图片上传API 一直提示400?

使用服务商/点商品平台v3文件上传接口时,返回的一直是400,且没有任何错误代码

发起方法

public String partnerMediaUpload(MultipartFile file1) throws IOException {
    // 构建uri
    URI uri = buildPartnerUpdateURI();

    // 创建post请求
    HttpPost httpPost = new HttpPost();

    // 使用演示的文件
    File file = new File("D:\\temp\\afa3b3dc1bc087324cb264b747dcffc.jpg");

    // 文件名称以及后缀
    String fileName = file.getName();
    String fileSuffixName = FileUtils.getFileSuffixName(fileName);

    // sha256计算
    String sha256;
    try {
        InputStream inputStream = Files.newInputStream(file.toPath());
        sha256 = DigestUtils.sha256Hex(inputStream);
        inputStream.close();
    } catch (IOException e) {
        logger.error("将图片进行二进制进行sha256失败!错误信息为:{}", e.getMessage());
        throw new ServiceException("上传文件失败!");
    }

    // meta信息
    Map<String, String> metaParam = new HashMap<>();
    metaParam.put("filename", fileName);
    metaParam.put("sha256", sha256);
    String metaJsonStr = JSON.toJSONString(metaParam);

    // 构建请求body
    MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
    entityBuilder
            .setBoundary(BOUNDARY)
            .setMode(HttpMultipartMode.RFC6532)
            .addTextBody("meta", metaJsonStr, ContentType.APPLICATION_JSON)
            .addBinaryBody("file", Files.newInputStream(file.toPath()), ContentType.create(MIMEUtils.ofMimeType(fileSuffixName)), fileName);
    HttpEntity entity = entityBuilder.build();

    // 生成签名
    WxSignResultDetailDTO signDetail;
    try {
        signDetail = WxPayUtils.sign(httpPost, WxPayUrlPathConstant.PARTNER_MERCHANT_MEDIA_UPLOAD, metaJsonStr, wxPayHttpClient.buildPrivateKey());
    } catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
        logger.error("生成微信图片签名失败!错误信息为:{}", e.getMessage());
        throw new ServiceException("上传文件失败!");
    }

    // 构建请求头参数
    String contentType = "multipart/form-data;boundary=" + BOUNDARY;
    String authorization = "WECHATPAY2-SHA256-RSA2048 " +
            "mchid=\"" + wxPayConfig.getMerchantId() + "\","
            + "nonce_str=\"" + signDetail.getNonceStr() + "\","
            + "timestamp=\"" + signDetail.getTimestamp() + "\","
            + "serial_no=\"" + wxPayConfig.getMerchantSerialNumber() + "\","
            + "signature=\"" + signDetail.getSignature() + "\"";

    // 添加请求参数
    httpPost.setURI(uri);
    httpPost.setEntity(entity);
    httpPost.setHeader("Content-Type", contentType);
    httpPost.setHeader("Authorization", authorization);

    // 发送请求
    WxRes<WxPartnerMediaUploadRes> uploadRes = wxPayHttpClient.execute(httpPost, WxPartnerMediaUploadRes.class);
    if (!Objects.equals(Boolean.TRUE, uploadRes.getSuccess())) {
        logger.error("发送微信上传图片请求失败 !请求地址为:{},错误信息为{}", WxPayUrlPathConstant.PARTNER_MERCHANT_MEDIA_UPLOAD, uploadRes.getErrMsg());
        throw new ServiceException("上传失败!");
    }

    return uploadRes.getData().getMedia_id();
}


签名方法

public static WxSignResultDetailDTO sign(HttpRequestBase request,
                                         String url,
                                         String paramsStr,
                                         PrivateKey privateKey) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
    // 生成一个随机数(这里使用uuid)
    String nonceStr = UUID.randomUUID().toString().replace("-", "");
    // 当前时间戳(按秒)
    long timestamp = System.currentTimeMillis() / 1000;

    // 需要签名的字符串
    String message =
            request.getMethod() + "\n"
                    + url + "\n"
                    + timestamp + "\n"
                    + nonceStr + "\n"
                    + paramsStr + "\n";

    // 进行签名
    String sign = sign(message.getBytes(StandardCharsets.UTF_8), privateKey);

    // 封装参数
    WxSignResultDetailDTO result = new WxSignResultDetailDTO();
    result.setNonceStr(nonceStr);
    result.setTimestamp(String.valueOf(timestamp));
    result.setSignature(sign);

    return result;
}


private static String sign(byte[] message, PrivateKey privateKey) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
    // 创建一个签名对象
    Signature sign = Signature.getInstance("SHA256withRSA");
    // 初始化私钥
    sign.initSign(privateKey);
    // 添加消息体
    sign.update(message);

    // 生成签名
    return Base64.getEncoder().encodeToString(sign.sign());
}


debug的信息:

Authorization: WECHATPAY2-SHA256-RSA2048 mchid="********",nonce_str="66f55f5a69e843fd94a04e8e9677d9b7",timestamp="1689132016",serial_no="***************************",signature="0oS5i68DJTzVUhctKYEaoXPRUkPfPK9tSMYivIxTKGFBg7SLAAegHVhM6wvGYhH/oyZGTniaP0agcZG8S8+MkyXRP3qgMKaauC1b3uqwSJBMq7gZJRoS6RmUfG9jUgu+gf3OZJNbRGoQqe6IbDHu6EGXGW0pNFr+BkRBWyFJGjGOv+XvzAyx/+Os3BJc0NrnFtvmyXVoS0V1bjVcd9rJgK9pkmkQ9c+8ehq7ocvsvmkWgfKiBVymhiNICdjkevjjGZrHQGsjj8oyiPMSY8IDb5F7udjIVYRGXqNY/MGWetnVgHsW7ZpCCgmHxchx2mSPUjdB0dJFdfRpESzDwP4urQ=="

错误信息为:

11:23:29.283 [http-nio-9207-exec-3] ERROR c.w.p.c.a.h.SignatureExec - [executeWithSignature,95] - 应答的状态码不为200-299。status code[400]    request headers[[Content-Type: multipart/form-data;boundary=mengchongtech, Authorization: WECHATPAY2-SHA256-RSA2048 mchid="******",nonce_str="66f55f5a69e843fd94a04e8e9677d9b7",timestamp="1689132016",serial_no="***********************",signature="0oS5i68DJTzVUhctKYEaoXPRUkPfPK9tSMYivIxTKGFBg7SLAAegHVhM6wvGYhH/oyZGTniaP0agcZG8S8+MkyXRP3qgMKaauC1b3uqwSJBMq7gZJRoS6RmUfG9jUgu+gf3OZJNbRGoQqe6IbDHu6EGXGW0pNFr+BkRBWyFJGjGOv+XvzAyx/+Os3BJc0NrnFtvmyXVoS0V1bjVcd9rJgK9pkmkQ9c+8ehq7ocvsvmkWgfKiBVymhiNICdjkevjjGZrHQGsjj8oyiPMSY8IDb5F7udjIVYRGXqNY/MGWetnVgHsW7ZpCCgmHxchx2mSPUjdB0dJFdfRpESzDwP4urQ==", Accept: application/json, Authorization: WECHATPAY2-SHA256-RSA2048 mchid="********",nonce_str="4FlV9Blikk8d42Yyj96VclRqVLRvbPu0",timestamp="1689132209",serial_no="*****************",signature="gFOocuO5z2o7gPlW/ZJj9PRp9XHVH4VQ40kcn/EA6DwXsiMRMFCSjZecJ6t/ob/U5+zinLgzFj+uX7VJOzefrz/N1+NktdDzYB/tGHpiFKqYVdtCBXziOMDuePM+ydx4uyN5rObHdpYYkK4qIW5RRAL/WYm+sgguHQ4moYDppWVj8Cyx/QP6JShAHFkYkfYRW3RV9TaOxcQdC84u1A+HLXODAPHf0csTTYzQvVdJ9NbJJLHzzojLIY9lcor7TJldK8yxV1E+MT5mjC1JIh3KxLgY7MSE0UQsEaLx0eAeqe0YkiaAoGMM7vMrVL6ezmTcAXEpToXwivUnAGisHV6hGg==", Content-Length: 193679, Host: api.mch.weixin.qq.com, Connection: Keep-Alive, User-Agent: WechatPay-Apache-HttpClient/0.4.8 (Windows 10/10.0) Java/1.8.0_202, Accept-Encoding: gzip,deflate]]
11:23:29.285 [http-nio-9207-exec-3] ERROR c.w.p.c.a.h.SignatureExec - [executeWithSignature,100] - 应答的状态码不为200-299。request body
[--mengchongtech
Content-Disposition: form-data; name="meta"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit

{"filename":"afa3b3dc1bc087324cb264b747dcffc.jpg","sha256":"1f03585317885cc1603cb28fa4ab07bcd272b3f2508594406d89177226ce6305"}
--mengchongtech
Content-Disposition: form-data; name="file"; filename="afa3b3dc1bc087324cb264b747dcffc.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary

ÿØÿà JFIF      ÿÛ C    #,%!*!&4'*./121%6:60:,010ÿÛ C        
0  00000000000000000000000000000000000000000000000000ÿÀ     ä’" ÿÄ 
……文件二进制流
.
.
.
.
,qF¡`*€ KEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPÿÙЁ;    Æ…™Êó}NQü¢ìf/
--mengchongtech--
]              



一直找不到错误,麻烦看一下错误在哪里。



回答关注问题邀请回答
收藏

2 个回答

  • LiuXiangLin
    LiuXiangLin
    2023-07-12

    问题找到了,上述代码没有任何问题。问题在于

    wxPayHttpClient.execute
    

    的方法上。这里是我对微信官方的工具进行了二次封装,可能这个工具类也进行了二次签名还是啥的。然后可能把里面参数搞错了。看错误信息中有head中有两个签名数据,之前一直没注意,所以问题大概率也在这里。最后将

    wxPayHttpClient.execute
    

    换为普通的httpClient即可

    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    CloseableHttpResponse res = httpClient.execute(httpPost);
    
    2023-07-12
    有用
    回复
  • 大熊
    大熊
    2023-07-12

    你好,请先参考这个帖子看看是否能解决您的问题

    https://developers.weixin.qq.com/community/develop/doc/000c46e5004088a0dd3b5bbed51400?_at=1614235075250


    2023-07-12
    有用
    回复 1
    • LiuXiangLin
      LiuXiangLin
      2023-07-12
      问题已经找到了 谢谢
      2023-07-12
      回复
登录 后发表内容