需要配置如下:
1.微信证书私钥路径(账户中心-》API安全-》申请API证书-》API证书管理)
2.微信商户证书路径(账户中心-》API安全-》申请API证书-》API证书管理)
3.APIv3秘钥(账户中心-》API安全-》设置APIv3秘钥)
4.商户号

需要的pom,有时候会出现不能导入需要自己导入本地

 <dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-apache-httpclient</artifactId><version>0.2.1</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-rs-client</artifactId><version>3.1.11</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>3.1.11</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxrs</artifactId><version>3.1.11</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-rs-extension-providers</artifactId><version>3.1.11</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>3.14.9</version></dependency><dependency><groupId>com.squareup.okio</groupId><artifactId>okio</artifactId><version>1.13.0</version></dependency>

代码:请求接口

 @ApiOperation(value = "审核")@ApiResponses(value = {@ApiResponse(code = 0000, message = "请求已完成"),@ApiResponse(code = 0001, message = "操作失败"),})@ApiImplicitParams({@ApiImplicitParam(value = "(必传)token", name = "token", dataType = "String", required = true, paramType = "header"),})@PostMapping("/updateIspState")@ResponseBodypublic void updateIspState(   ) throws Exception {//需要提交的参数String sub = UploadServiceImpl.applyment4sub("");//返回提交申请单 微信支付申请单号String applyment_id =  V3Http.sendPost(sub);}

工具类


import com.alibaba.fastjson.JSON;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;import javax.crypto.*;
import java.io.*;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.*;/*** @program: UploadServiceImpl* @description:* @author: 云晓得峰* @create: 2022/9/21 16:27*/public class UploadServiceImpl {/*** 微信特约服务商 提交申请* @param str*/public static String applyment4sub( String str) throws Exception {HashMap<String, Object> map = new HashMap<>();HashMap<String, Object> contactMap = new HashMap<>();// 下面所有加密参数需要的对象String certString = V3Http.getCertStr();ByteArrayInputStream stringStream = new ByteArrayInputStream(certString.getBytes());// 下面所有加密参数需要的对象X509Certificate certx = PemUtil.loadCertificate(stringStream);/*** 提交的参数自行根据需求拼接,这里做个示例 加密参数*///微信支付平台证书公钥加密contactMap.put("contact_name",  rsaEncryptOAEP(str, certx));map.put("contact_info",contactMap);return  JSON.toJSONString(map);}/*** 加密** @param message* @param certificate* @return* @throws IllegalBlockSizeException* @throws IOException*/public static String rsaEncryptOAEP(String message, X509Certificate certificate) throws IllegalBlockSizeException, IOException {try {Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");cipher.init(Cipher.ENCRYPT_MODE, certificate.getPublicKey());byte[] data = message.getBytes("utf-8");byte[] cipherdata = cipher.doFinal(data);return Base64.getEncoder().encodeToString(cipherdata);} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);} catch (InvalidKeyException e) {throw new IllegalArgumentException("无效的证书", e);} catch (IllegalBlockSizeException | BadPaddingException e) {throw new IllegalBlockSizeException("加密原串的长度不能超过214字节");}}/*** 解密** @param ciphertext* @param privateKey* @return* @throws BadPaddingException* @throws IOException*/public static String rsaDecryptOAEP(String ciphertext, PrivateKey privateKey) throws BadPaddingException, IOException {try {Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] data = Base64.getDecoder().decode(ciphertext);return new String(cipher.doFinal(data), "utf-8");} catch (NoSuchPaddingException | NoSuchAlgorithmException e) {throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);} catch (InvalidKeyException e) {throw new IllegalArgumentException("无效的私钥", e);} catch (BadPaddingException | IllegalBlockSizeException e) {throw new BadPaddingException("解密失败");}}
}

import com.alibaba.fastjson.JSONObject;
import net.sf.json.JSONArray;
import okhttp3.HttpUrl;
import org.apache.cxf.jaxrs.client.WebClient;import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.UUID;/*** @program: V3Http* @description:* @author: 云晓得峰* @create: 2022/9/25 10:12*/
public class V3Http {/***  【需要设置】* 微信支付商户号*/public static String merchantId ="XXXXXX";/*** 【需要设置】登录微信商户平台账户中心-》API安全-》设置APIv3秘钥*/public static byte[] aesKey = "XXXXXXXXXXXXXXXX".getBytes();/*** 【需要设置】* 微信证书私钥路径(从微信商户平台下载,保存在本地)*/private final static String privateKeyFile = "C:/cert/apiclient_key.pem";public static String SCHEMA = "WECHATPAY2-SHA256-RSA2048";public static String POST = "POST";public static String GET = "GET";public static String host = "https://api.mch.weixin.qq.com";public static String APPLY_PATH = "/v3/applyment4sub/applyment/"; // 申请单urlpublic static String CERT_PATH = "/v3/certificates"; // 获取微信平台证书urlpublic static String APPLY_QUERY_PATH = "/v3/applyment4sub/applyment/applyment_id/"; // 查询申请状态static final int KEY_LENGTH_BYTE = 32;static final int TAG_LENGTH_BIT = 128;public V3Http(byte[] key) {if (key.length != KEY_LENGTH_BYTE) {throw new IllegalArgumentException("无效的ApiV3Key,长度必须为32个字节");}this.aesKey = key;}/*** 微信支付平台证书* @return* @throws Exception*/public static String getCertStr() throws Exception {try {String str =  sendGet();net.sf.json.JSONObject json = net.sf.json.JSONObject.fromObject(str);JSONArray jsonArray = JSONArray.fromObject(json.optString("data"));net.sf.json.JSONObject jsonObject = jsonArray.getJSONObject(0);net.sf.json.JSONObject jsonCert = net.sf.json.JSONObject.fromObject(jsonObject.optString("encrypt_certificate"));String certKeyString =   decryptToString1(jsonCert.getString("associated_data").getBytes(),jsonCert.getString("nonce").getBytes(), jsonCert.getString("ciphertext"));return certKeyString;} catch (Exception e) {e.printStackTrace();}return null;}public static String decryptToString1(byte[] associatedData, byte[] nonce, String ciphertext) throws Exception {try {Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");SecretKeySpec key = new SecretKeySpec(aesKey, "AES");GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);cipher.init(Cipher.DECRYPT_MODE, key, spec);cipher.updateAAD(associatedData);return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {throw new IllegalStateException(e);} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {throw new IllegalArgumentException(e);}}/*** POST请求*/public static String sendPost(String body) {String url = host + APPLY_PATH;try {/*** 获取HTTP请求头中Wechatpay-Serial证书序列号: 需要注意不是 账户中心-》API安全-》申请API证书 里面的证书序列号。需要通过接口获取*/JSONObject jsonObject = JSONObject.parseObject(sendGet());com.alibaba.fastjson.JSONArray objects = com.alibaba.fastjson.JSONArray.parseArray(jsonObject.get("data").toString());Object str = objects.get(0);Object serial_no = JSONObject.parseObject(str.toString()).get("serial_no");String authorization = getToken(POST, url, body);WebClient client = WebClient.create(host);client.reset();client.header("Content-Type", "application/json; charset=UTF-8");client.header("Accept", "application/json");client.header("user-agent", "application/json");client.header("Wechatpay-Serial",serial_no);client.header("Authorization", authorization);client.path(APPLY_PATH);Response r = client.post(body);return r.readEntity(String.class);} catch (Exception e) {return null;}}/*** get请求 获取HTTP请求头中Wechatpay-Serial* json中返回的serial_no 为需要的数据*/public static String sendGet() {// 请求URLString url = host + CERT_PATH;try {String authorization = getToken(GET, url, "");WebClient client = WebClient.create(host);client.reset();client.header("Content-Type", "application/json; charset=UTF-8");client.header("Accept", "application/json");client.header("User-Agent", "application/json");client.header("Authorization", authorization);client.path(CERT_PATH);Response r = client.get();return r.readEntity(String.class);} catch (Exception e) {e.printStackTrace();return null;}}/*** get请求*/public static String sendGet(String applymentId) {// 请求URLString url = host + APPLY_QUERY_PATH + applymentId;try {String authorization = getToken(GET, url, "");WebClient client = WebClient.create(host);client.reset();client.header("Content-Type", "application/json; charset=UTF-8");client.header("Accept", "application/json");client.header("User-Agent", "application/json");client.header("Authorization", authorization);client.path(APPLY_QUERY_PATH + applymentId);Response r = client.get();if(r.getStatus()==200){return r.readEntity(String.class);}else {return null;}} catch (Exception e) {e.printStackTrace();return null;}}/*** 获取加密串** @param method* @param url* @param body* @return*/public static String getToken(String method, String url, String body) {String nonceStr = String.valueOf(UUID.randomUUID());long timestamp = System.currentTimeMillis() / 1000;HttpUrl httpUrl = HttpUrl.parse(url);String message = buildMessage(method, httpUrl, timestamp, nonceStr, body);String signature = null;String certificateSerialNo = null;try {signature = sign(message.getBytes("utf-8"));/*** 此处是证书编号* apiclient_cert.pem文件中获取*/certificateSerialNo = CertUtil.getSerialNo();//证书序列号} catch (Exception e) {e.printStackTrace();}return SCHEMA + " mchid=\"" + merchantId + "\"," + "nonce_str=\"" + nonceStr + "\"," + "timestamp=\"" + timestamp + "\"," + "serial_no=\""+ certificateSerialNo + "\"," + "signature=\"" + signature + "\"";}/*** 得到签名字符串*/public static String sign(byte[] message) throws Exception {Signature sign = Signature.getInstance("SHA256withRSA");PrivateKey privateKey = getPrivateKey(privateKeyFile);sign.initSign(privateKey);sign.update(message);return Base64.getEncoder().encodeToString(sign.sign());}/*** 获取私钥。** @param filename 私钥文件路径  (required)* @return 私钥对象*/public static PrivateKey getPrivateKey(String filename) throws IOException {String content = new String(Files.readAllBytes(Paths.get(filename)), "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.getDecoder().decode(privateKey)));} catch (NoSuchAlgorithmException e) {throw new RuntimeException("当前Java环境不支持RSA", e);} catch (InvalidKeySpecException e) {throw new RuntimeException("无效的密钥格式");}}public static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {String canonicalUrl = url.encodedPath();if (url.encodedQuery() != null) {canonicalUrl += "?" + url.encodedQuery();}return method + "\n" + canonicalUrl + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";}
}

import org.apache.commons.codec.binary.Base64;import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;/*** 证书工具类*/
public class CertUtil {/*** 【需要设置】* 微信证书私钥路径(从微信商户平台下载,保存在本地)*/public static String APICLIENT_KEY = "C:/cert/apiclient_key.pem";/**【需要设置】*  微信商户证书路径(从微信商户平台下载,保存在本地)*/public static String APICLIENT_CERT = "C:/cert/apiclient_cert.pem";/*** 获取私钥。** @param* @return 私钥对象*/public static PrivateKey getPrivateKey() throws IOException {String content = new String(Files.readAllBytes(Paths.get(APICLIENT_KEY)), 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  // 证书文件路径 (required)* @return X509证书*/public static X509Certificate getCertificate() throws IOException {InputStream fis = new FileInputStream(APICLIENT_CERT);try (BufferedInputStream bis = new BufferedInputStream(fis)) {CertificateFactory cf = CertificateFactory.getInstance("X509");X509Certificate cert = (X509Certificate) cf.generateCertificate(bis);cert.checkValidity();return cert;} catch (CertificateExpiredException e) {throw new RuntimeException("证书已过期", e);} catch (CertificateNotYetValidException e) {throw new RuntimeException("证书尚未生效", e);} catch (CertificateException e) {throw new RuntimeException("无效的证书文件", e);}}public static X509Certificate getCertificate(String path) throws IOException {InputStream fis = new FileInputStream(path);try (BufferedInputStream bis = new BufferedInputStream(fis)) {CertificateFactory cf = CertificateFactory.getInstance("X509");X509Certificate cert = (X509Certificate) cf.generateCertificate(bis);cert.checkValidity();return cert;} catch (CertificateExpiredException e) {throw new RuntimeException("证书已过期", e);} catch (CertificateNotYetValidException e) {throw new RuntimeException("证书尚未生效", e);} catch (CertificateException e) {throw new RuntimeException("无效的证书文件", e);}}/*** 获取商户证书序列号** @param   //获取商户证书序列号 传递商号证书路径 apiclient_cert* @return* @throws IOException*/public static String getSerialNo() throws IOException {X509Certificate certificate = getCertificate();return certificate.getSerialNumber().toString(16).toUpperCase();}}

JAVA 特约商户进件对接相关推荐

  1. 微信特约商户进件 JAVA 案例dome

    前一段时间,小微进件接口突然关闭,根据公司业务只能对接一下微信特约商户进件接口,发现V3接口坑还是蛮多的,但是网上的例子都不是很多,抽了点时间整理了一下,欢迎个位大佬点评. 1.对应的三个证书 商户证 ...

  2. v3特约商户进件-Java版本

    这里写自定义目录标题 记那些年特约商户进件踩过的坑 1. 微信平台证书下载 2. 图片上传 3. 申请的坑 4. 待补充(还有查询没有踩坑) 记那些年特约商户进件踩过的坑 公司要做特约商户进件,折腾了 ...

  3. 微信V3接口:特约商户进件 提交申请单API 提示证书错误.

    ||–查看的码友,在不麻烦的情况,如果文章有用,烦请点个赞.如果没用可以留言讨论哦–|| 特约商户进件 提交申请单API 提示证书错误 最终排查弄清楚 原来证书的使用应该是: 签名中使用的证书: Au ...

  4. 微信服务商商户进件php,关于微信服务商特约商户进件的问题

    我提交了特约商户进件信息,提交成功,并且返回了applyment_id正常,但是在用business_code 查询进件状态时返回: {"code":"PARAM_ERR ...

  5. 微信支付服务商,可视化进件特约商户

    服务商拓展特约商户(子商户),可能出现如下问题: 1.人工录入大量商户资料,耗时耗力. 2.商户对标准费率不满意,无法说服商户先签约再帮其调整费率. 针对以上问题,微信支付面向服务商开放"特 ...

  6. 平台业务收款分账产品设计 - 进件

    概述 进件这个词在金融行业用的比较多,简单来说就是商户提供相关资料申请或者办理业务,本文中的进件是指商家提供工商资料来开通在三方支付平台的二级账户(前提是要电商平台已经在三方支付平台进件对接好了) 2 ...

  7. 微信服务商快速进件,商户自己提交资料,减少工作量

    大家好,我是小悟 用好技术,让经营更高效.为了减少服务商工作量,移动端服务商进件来了,分为移动端和管理端. 移动端 包括四大模块,主体资料.经营资料.法人资料和银行账户. 点击顶部步骤条可以切换,进入 ...

  8. 银联进件渠道教程-云闪付收银台最新方法(可对接易支付)

    用户可以直接注册激活,邮箱内会有秘钥,可以对接网站,APP,公众号等 银联进件教程.zip - 蓝奏云文件大小:3.6 M|https://ch-h-cn.lanzoum.com/i3t0D0cyds ...

  9. JAVA车辆进出厂预报-物流门禁系统对接开发-王大师王文峰开发(去年已完成)

    本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,<Java王大师王天师>作者 公众号:山峯草堂,非技术多篇文章,专注于天道酬勤的 Java 开发问题.中国国学.传统文化和代 ...

最新文章

  1. mysql不能改路径到d盘_Windows Server 2008 R2修改MySQL 5.5数据库目录为D盘示例
  2. java数组遍历 删除remove
  3. Silverlight学习笔记清单
  4. Linux和optee双系统中1020-1023号的中断号的使用
  5. 阅读《Google成功七堂课》
  6. (转)git 忽略规则
  7. spring boot 2.0.3+spring cloud (Finchley)1、搭建服务注册和发现组件Eureka 以及构建高可用Eureka Server集群...
  8. oracle11g打补丁故障_针对Oracle11g补丁修补说明.docx
  9. [51nod 1051 最大子矩阵和]前缀和+dp
  10. 2021 年 VS Code 主题推荐
  11. 大型在线考试答题系统源码 B/S架构
  12. 共享服务器文件溢出,文件共享软件Samaba中发现缓冲区溢出漏洞
  13. 购物系统 java代码_java购物系统源代码
  14. docker语句及SQL查询
  15. 2021年中国马铃薯种植生产情况及机械化程度分析:单产面积不断扩大,四川省产量居全国首位[图]
  16. 第一行代码-android-第三版-pdf扫描-思维导图-课件-源码
  17. 高通Android平台开发
  18. Tensorflow创建循环神经网络
  19. 函数的返回值,C语言函数返回值详解
  20. IC-CAD IC 设计流程及 EDA 工具

热门文章

  1. 伦茨服务器显示IMP,浅谈伦茨变频器的常见故障和维护
  2. JAVA计算机毕业设计校园共享单车管理系统(附源码、数据库)
  3. ArcGIS 实验理论基础二十六 中国人口密度图的制作
  4. 方形图片 圆形图片 各种形状
  5. 阿里云全国快递物流查询api接口
  6. 大数据5v指的是什么?——以沃尔玛为例
  7. hexo next 文章添加分类
  8. 微信小程序文章详情页跳转案例
  9. 【转载】SARscape5.4/5.4.1新功能
  10. hdu计算机学院大学生程序设计竞赛(2015’11)1003 玩骰子