微信企业付款至银行卡 详细Demo

微信企业付款至银行卡 详细Demo 独立封装
大家好,我是梦辛工作室的灵,在最近的开发项目中,需要用到微信的企业付款至银行卡,在有过之前的企业付款到零钱包的封装好,就变的简单了许多,不过我还是在采用RSA加密银行卡 和 真实姓名的步骤上卡了许久,经过我不断地尝试还是搞定了这个功能,为了以后方便使用 顺便封装了下,WxPayUtilV1.0.2版,下面是如何使用:

/**
 * 企业付款到银行卡示例
 */
public static void compayWxPayBank() {

	try {
		// 获取公钥
		String key = getWxPayPublicKey();

		CompanyWxPayBankBuilder wxPayBankBuilder = new CompanyWxPayBankBuilder("证书路径", key); // key 为微信返回的公钥

		wxPayBankBuilder.setMch_id("商户号");
		wxPayBankBuilder.setAPI_KEY("APIKEY");
		wxPayBankBuilder.setAmount(200); // 支付金额
		wxPayBankBuilder.setDesc("支付描述");
		wxPayBankBuilder.setEnc_bank_no("银行卡卡号");
		wxPayBankBuilder.setEnc_true_name("真实姓名");
		wxPayBankBuilder.setBank_code("银行编码");

		wxPayBankBuilder.build();// 验证数据
		System.out.println(wxPayBankBuilder.hand());// 发送处理
	} catch (LackParamExceptions e) {
		e.printStackTrace();
	}
}
/**
 * 获取公钥
 */
public static String getWxPayPublicKey() {

	try {
		GetPublicKeyBuilder builder = new GetPublicKeyBuilder("证书路径");
		builder.setAPI_KEY("APIKEY");
		builder.setmch_id("微信商户号");
		builder.build();// 验证数据
		JSONObject result = builder.hand();
		System.out.println(result);// 发送处理
		return result.getString("pub_key");
	} catch (LackParamExceptions e) {
		e.printStackTrace();
	}
	return null;
}
/**
 * 企业付款到银行卡查询示例
 */
public static void compayWxPayBankQuery() {

	try {

		CompanyWxPayBankQueryBuilder wxPayBankQueryBuilder = new CompanyWxPayBankQueryBuilder("支付证书路径",
				"交易订单号(商家,不是微信的)");

		wxPayBankQueryBuilder.setMch_id("商户号");
		wxPayBankQueryBuilder.setAPI_KEY("APIKEY");

		wxPayBankQueryBuilder.build();// 验证数据
		System.out.println(wxPayBankQueryBuilder.hand());// 发送处理
	} catch (LackParamExceptions e) {
		e.printStackTrace();
	}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
有了这个我集成好的工具后,是不是就简单了很多,没有其余更多的复杂逻辑,hand()后就可以拿到对应的处理数据,该工具项目 我还集成了 微信JSAPI付款 发送模板消息 微信退款 微信退款查询 微信企业付款至零钱包 付款至银行卡 等功能,
下面讲一下我企业付款至银行卡步骤(不感兴趣的同学可直接到底部,github去下载源代码):

在拿到商户号秘钥和支付证书的基础上,需先获取到公钥

将以上信息按照ASCII码顺序拼接成以下格式:

mch_id=&nonce_str=&key=
1
然后MD5拿到sign,最后拼接成xml格式:

最后带证书访问值地址:https://fraud.mch.weixin.qq.com/risk/getpublickey
带证书访问代码如下:

public static String httpClientResultGetPublicKey(String url, String xml, String mch_id, String path)
throws Exception {

	StringBuffer reultBuffer = new StringBuffer();

	KeyStore keyStore = KeyStore.getInstance("PKCS12");

	FileInputStream instream = new FileInputStream(new File(path));
	try {

		keyStore.load(instream, mch_id.toCharArray());
	} finally {
		instream.close();
	}

	SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mch_id.toCharArray()).build();

	SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
			SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

	HttpPost httpPost = new HttpPost(url);
	CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
	StringEntity myEntity = new org.apache.http.entity.StringEntity(xml);
	myEntity.setContentType("text/xml;charset=UTF-8");
	myEntity.setContentEncoding("utf-8");
	httpPost.setHeader("Content-Type", "text/xml; charset=UTF-8");
	httpPost.setEntity(myEntity);

	CloseableHttpResponse response = null;
	InputStream inputStream = null;
	InputStreamReader inputStreamReader = null;
	BufferedReader bufferedReader = null;
	try {
		response = httpclient.execute(httpPost);
		HttpEntity entity = response.getEntity();
		if (entity != null) {
			inputStream = entity.getContent();
			inputStreamReader = new InputStreamReader(inputStream);
			bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				reultBuffer.append(str);
			}
		}
	} catch (ClientProtocolException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} finally {

		httpclient.close();
		response.close();
		bufferedReader.close();
		inputStreamReader.close();
		inputStream.close();
		inputStream = null;
	}

	return reultBuffer.toString();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
访问成功后可以拿到公钥,格式如下:

需要注意的是,这里获取到的秘钥格式是PKCS#1, 我们在用JAVA代码进行RSA加密的时候回报错,这是因为需要将格式转换为PKCS#8才可以,等下后面会讲到

进行企业付款至银行卡
在我们拿到公钥后,就按照以下参数请求,请求格式和加密方法和上面的一样,所需参数为:

这里需要对 银行卡 和真实姓名进行RSA加密,JAVA需要采用 " RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING" 填充方式,(需要将公钥格式转换为PKCS#8),加密代码如下(注意,这里的公钥需将头和尾去掉,即不要 “-----BEGIN RSA PUBLIC KEY-----” 和 “-----END RSA PUBLIC KEY-----”),需要为UTF-8格式:

try {
		enc_bank_no_pwd = RSAEncryp.encrypt(enc_bank_no.getBytes("utf-8"), pub_key, 11,
				"RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING");
	} catch (Exception e) {
		e.printStackTrace();
		enc_bank_no_pwd = "";
	}
	try {
		enc_true_name_pwd = RSAEncryp.encrypt(enc_true_name.getBytes("utf-8"), pub_key, 11,
				"RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING");
	} catch (Exception e) {
		e.printStackTrace();
		enc_true_name_pwd = "";
	}
	public static String encrypt(byte[] plainBytes, String pub_Key, int reserveSize, String cipherAlgorithm)
		throws Exception {
	PublicKey publicKey = getPublicKey(pub_Key, "RSA");
	byte[] estr = encrypt(plainBytes, publicKey, pub_Key.length(), reserveSize, cipherAlgorithm);
	return new String(Base64.getEncoder().encode(estr));
}

public static PublicKey getPublicKey(String key, String keyAlgorithm) throws Exception {
try {
//在这里做的秘钥格式转换
org.bouncycastle.asn1.pkcs.RSAPublicKey rsaPublicKey = org.bouncycastle.asn1.pkcs.RSAPublicKey
.getInstance(org.bouncycastle.util.encoders.Base64.decode(key));
java.security.spec.RSAPublicKeySpec publicKeySpec = new java.security.spec.RSAPublicKeySpec(
rsaPublicKey.getModulus(), rsaPublicKey.getPublicExponent());
KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

		return publicKey;
	} catch (Exception e) {
		throw new Exception("READ PUBLIC KEY ERROR:", e);
	} finally {

	}
}

public static byte[] encrypt(byte[] plainBytes, PublicKey publicKey, int keyLength, int reserveSize,
String cipherAlgorithm) throws Exception {
int keyByteSize = keyLength / 8;
int encryptBlockSize = keyByteSize - reserveSize;
int nBlock = plainBytes.length / encryptBlockSize;
if ((plainBytes.length % encryptBlockSize) != 0) {
nBlock += 1;
}
ByteArrayOutputStream outbuf = null;
try {
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);

		outbuf = new ByteArrayOutputStream(nBlock * keyByteSize);
		for (int offset = 0; offset < plainBytes.length; offset += encryptBlockSize) {
			int inputLen = plainBytes.length - offset;
			if (inputLen > encryptBlockSize) {
				inputLen = encryptBlockSize;
			}
			byte[] encryptedBlock = cipher.doFinal(plainBytes, offset, inputLen);
			outbuf.write(encryptedBlock);
		}
		outbuf.flush();
		return outbuf.toByteArray();
	} catch (Exception e) {
		throw new Exception("ENCRYPT ERROR:", e);
	} finally {
		try {
			if (outbuf != null) {
				outbuf.close();
			}
		} catch (Exception e) {
			outbuf = null;
			throw new Exception("CLOSE ByteArrayOutputStream ERROR:", e);
		}
	}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
然后将这些参数按照ASCII码顺序排序凭借为以下字符串:

amount=&bank_code=&desc=&enc_bank_no=&enc_true_name=&mch_id=&nonce_str=&partner_trade_no=&key=
1
然后MD5拿到sign
然后拼接为以下格式:

然后带证书post到接口地址:https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank
然后就可以啦,企业付款到银行卡查询比较简单,且没有什么需要注意的,我就不说啦,格式和 获取公钥一样,仅是参数不同而已

github入口,记得打个start https://github.com/wintton/MxWxPayUtil

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值