接口文档
https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/chapter3_1.shtml
代码
/** * v3 图片资料上传 * @Param fileNetUrl 网络图片地址 * @return */ public static String mediaUploadV3(String fileNetUrl){ try { //商户号 String mchid = ""; //微信支付平台公钥 String rsaPublicKeyFile = ""; // 公钥文件路径 String pubilcKeyPath = "" // 私钥文件路径 String privageKeyPath = "" //证书序列号 String serial_no = getSerialNo(pubilcKeyPath); //时间戳 String timestamp = Long.toString(System.currentTimeMillis()/1000); //随机数 String nonce_str = randomString(32).toUpperCase(); //图片文件 String filename = getFileNameUrl(fileNetUrl);//文件名 byte[] fileBytes = getImageFromNetByUrl(fileNetUrl); String fileSha256 = DigestUtils.sha256Hex(new ByteArrayInputStream(fileBytes));//文件sha256 //拼签名串 StringBuffer sb =new StringBuffer(); sb.append("POST").append("\n"); sb.append("/v3/merchant/media/upload").append("\n"); sb.append(timestamp).append("\n"); sb.append(nonce_str).append("\n"); sb.append("{\"filename\":\""+filename+"\",\"sha256\":\""+fileSha256+"\"}").append("\n"); System.out.println("签名原串:"+sb.toString()); //计算签名 String sign = new String(Base64.encodeBase64(signRSA(sb.toString(),privageKeyPath))); System.out.println("签名sign值:"+sign); //拼装http头的Authorization内容 String authorization ="WECHATPAY2-SHA256-RSA2048 mchid=\""+mchid+"\",nonce_str=\""+nonce_str+"\",signature=\""+sign+"\",timestamp=\""+timestamp+"\",serial_no=\""+serial_no+"\""; System.out.println("authorization值:"+authorization); //接口URL String url ="https://api.mch.weixin.qq.com/v3/merchant/media/upload"; CloseableHttpClient httpclient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(url); //设置头部 httpPost.addHeader("Accept","application/json"); httpPost.addHeader("Content-Type","multipart/form-data"); httpPost.addHeader("Authorization", authorization); //创建MultipartEntityBuilder MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532); //设置boundary multipartEntityBuilder.setBoundary("boundary"); multipartEntityBuilder.setCharset(StandardCharsets.UTF_8); //设置meta内容 multipartEntityBuilder.addTextBody("meta","{\"filename\":\""+filename+"\",\"sha256\":\""+fileSha256+"\"}", ContentType.APPLICATION_JSON); //设置图片内容 multipartEntityBuilder.addBinaryBody("file", fileBytes, ContentType.create("image/jpg"), filename); //放入内容 httpPost.setEntity(multipartEntityBuilder.build()); //获取返回内容 CloseableHttpResponse response = httpclient.execute(httpPost); HttpEntity httpEntity = response.getEntity(); String rescontent =new String(readInputStream(httpEntity.getContent())); System.out.println("返回内容:" + rescontent); //获取返回的http header Header[] headers = response.getAllHeaders(); int i =0; while (i < headers.length) { System.out.println(headers[i].getName() +": " + headers[i].getValue()); i++; } //验证微信支付返回签名 String Wtimestamp = response.getHeaders("Wechatpay-Timestamp")[0].getValue(); String Wnonce = response.getHeaders("Wechatpay-Nonce")[0].getValue(); String Wsign = response.getHeaders("Wechatpay-Signature")[0].getValue(); //拼装待签名串 StringBuffer ss =new StringBuffer(); ss.append(Wtimestamp).append("\n"); ss.append(Wnonce).append("\n"); ss.append(rescontent).append("\n"); //验证签名 if(verifyRSA(ss.toString(), Base64.decodeBase64(Wsign.getBytes()), rsaPublicKeyFile)) { System.out.println("签名验证成功"); }else { System.out.println("签名验证失败"); } EntityUtils.consume(httpEntity); response.close(); return rescontent; }catch (Exception e){ } return null; } public static byte[] signRSA(String data,privageKeyPath) throws Exception { //签名的类型 Signature sign = Signature.getInstance("SHA256withRSA"); sign.initSign(getPrivateKey(privageKeyPath)); sign.update(data.getBytes(StandardCharsets.UTF_8)); return sign.sign(); } public static boolean verifyRSA(String data, byte[] sign, String pubKey) throws Exception{ if(data == null || sign == null || pubKey == null){ return false; } CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream in = new FileInputStream(pubKey); Certificate c = cf.generateCertificate(in); in.close(); PublicKey publicKey = c.getPublicKey(); Signature signature = Signature.getInstance("SHA256WithRSA"); signature.initVerify(publicKey); signature.update(data.getBytes(StandardCharsets.UTF_8)); return signature.verify(sign); } /** * 获取私钥。 * * @param filename 私钥文件路径 (required) * @return 私钥对象 */ public static PrivateKey getPrivateKey(String filename) throws IOException { String content = new String(Files.readAllBytes(Paths.get(filename)), StandardCharsets.UTF_8); try { String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "") .replace("-----END PRIVATE KEY-----", "") .replaceAll("\\s+", ""); KeyFactory kf = KeyFactory.getInstance("RSA"); return kf.generatePrivate( new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey))); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("当前Java环境不支持RSA", e); } catch (InvalidKeySpecException e) { throw new RuntimeException("无效的密钥格式"); } } /** * 获取证书序列号 * * @param certPath 获取商户证书序列号 传递商号证书路径 apiclient_cert * @return * @throws IOException */ public static String getSerialNo(String certPath) throws IOException { X509Certificate certificate = getCertificate(certPath); return certificate.getSerialNumber().toString(16).toUpperCase(); } public static String getFileNameUrl(String url) { try { String[] url_split = url.split("/"); String name = url_split[url_split.length - 1]; String suffixes = name.split("\\.")[name.split("\\.").length - 1]; return getFileNameNoEx(name) + "." + suffixes; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 根据地址获得数据的字节流 * * @param strUrl 网络连接地址 * @return */ public static byte[] getImageFromNetByUrl(String strUrl) { try { URL url = new URL(strUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5 * 1000); InputStream inStream = conn.getInputStream();// 通过输入流获取图片数据 return readInputStream(inStream); } catch (Exception e) { e.printStackTrace(); } return null; } /** * @Function: 从输入流中获取数据 * @param inStream - 输入流 * @throws IOException */ public static byte[] readInputStream(InputStream inStream) throws IOException { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } inStream.close(); return outStream.toByteArray(); } /** * * @Description: 随机字符串 * @author 441889070@qq.com * @date 2015年11月12日 下午1:55:21 * @param */ public static String randomString(int length) { String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; Random random = new Random(); StringBuffer buf = new StringBuffer(); for(int i = 0 ;i < length ; i ++) { int num = random.nextInt(62); buf.append(str.charAt(num)); } return buf.toString(); }
- 热门文章
- Mysql 8.0+开启远程访问
- Vue3+Ts 组合API调用子组件方法
- JAVA生成微信小程序分享海报
- 基于 Vue 实现魔方矩阵排列效果
- JAVA开发微信特约商户进件/提交申请单
- 检查Office(Word/Excel)文档是否需要密码-通...
- Nginx 跨域配置支持
- 微信/v3/merchant/media/upload 网络图片上...
- 简述分布式CAP理论
- Iterator迭代器设计模式
- 我的标签
- JAVA<7>
- Js<4>
- 设计模式<4>
- TS<2>
- nginx<2>
- 微信服务商<2>
- 微信小程序<1>
- Vue<1>
- Vue3<1>
- IPv6<1>
- Apache POI<1>
- Mysql<1>
- rocketmq<1>
- 分布式数据库<1>
- polygon<1>
- 地图<1>
- CAP<1>
- jQuery<1>
- Git<1>
- curl<1>
- 分布式系统<1>
- 设计<0>
- Redis<0>
- HikariCP<0>
- 数据库连接池<0>
- 多线程<0>
- 友情链接
- 江西云戈信息技术