概述
WechatPay-API-v3接口规则
目录
1、官方文档
2、下面是Java 接入过程:
3、敏感信息加解密
4、demo参考
5、回调通知解密算法(AEAD_AES_256_GCM)
1、官方文档
https://wechatpay-api.gitbook.io/wechatpay-api-v3/
2、下面是Java 接入过程:
第一步: 阅读微信支付分给的接口规则 说明: https://wechatpay-api.gitbook.io/wechatpay-api-v3/
第二步: 微信支付API v3要用第三方CA的证书 所以涉及到 API证书升级
新接入商户请参考什么是API证书?如何获取API证书?。
已经接入并使用微信支付颁发证书的商户请参考微信支付API证书升级指引(技术人员)。
API v3已不支持使用微信支付颁发的证书。
商户升级API证书时,需要完成三个步骤:
①:商户号的超级管理员到商户平台升级证书,获取到权威CA颁发的API证书。 (查看指引)
②:超级管理员将权威CA颁发的API证书(共包含三个文件: 证书pkcs12格式、证书pem格式、证书密钥pem格式)转交给技术人员。
③:技术人员用新证书文件替换服务器上原微信支付颁发的API证书,无需对现有系统进行代码修改。
(注意)这里升级API证书不影响原有的 API 密钥 代码不需要做改动直接替换 apiclient_cert.p12文件即可
第三步: 拿到API证书和密钥文件.
第四步: 引入微信支付API v3的Apache HttpClient装饰器: GitHub 地址
注意: 微信支付API v3的Apache HttpClient扩展,实现了请求签名的生成和应答签名的验证。如不想使用次封装客户端 可自己实现 签名和应答解密过程.
相关maven依赖
<dependency>
<groupId>com.xiaomi.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.1.6</version>
</dependency>
第五步: 请求微信支付分API前准备
//微信支付商户开通后 微信会提供appid
public String appId;
//微信支付商户开通后 微信会提供appSecret
public String appSecret;
//商户号
public String mchId;
//32位的api密钥,微信商户平台-账户设置-安全设置-api安全 密钥 用于拉起支付签名
public String partnerkey;
//openId 是微信用户针对公众号的标识,授权的部分这里不解释
public String openId;
//微信支付成功后异步通知地址 必须要求80端口并且地址不能带参数
public String notifyUrl;
//微信支付成功后同步通知地址 必须要求80端口并且地址不能带参数
public String returnUrl;
//证书apiclient_cert.p12文件位置 可加载
public String certPath;
//微信支付分 分配的服务 ID
public String serviceId;
//v3接口 CA证书 apiclient_key.pem私钥内容
public String privateKey;
//v3接口 CA证书 apiclient_cert.pem证书内容
public String certificate;
// APIv3密钥 32 位
public String AES_KEY = "xxx";
//商户证书序列号 CA证书 可查看微信商户平台-账户设置-安全设置-api安全密钥
public String MC_HSERIAL_NO = "xxxxx";
3、敏感信息加解密
https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/min-gan-xin-xi-jia-mi
使用AES-256-GCM,对回调中的关键信息进行加密保护
建议从Verifier中获得微信支付平台证书,或使用预先下载到本地的平台证书文件中
X509Certificate wechatpayCertificate = verifier.getValidCertificate();
privateKey 为 v3接口 CA证书 apiclient_key.pem私钥内容
将String类型的privateKey 转化为PrivateKey类型
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
4、demo参考
构建httpClient,需要设置微信支付平台证书。
CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withWechatpay(wechatpayCertificates) // 加载证书
.build();
在第一次下载平台证书时,按照下述方法临时"跳过”应答签名的验证
CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(response -> true) // NOTE: 设置一个空的应答签名验证器,**不要**用在业务请求
.build();
get请求
URIBuilder uriBuilder = new URIBuilder(USER_SERVICE_STATE_URL);
uriBuilder.setParameter("service_id", yourServiceIdxxx);
uriBuilder.setParameter("appid", yourAppIdxxx);
uriBuilder.setParameter("openid", userOpenIdxxx);
CloseableHttpResponse response=null;
try {
HttpGet httpGet = new HttpGet(uriBuilder.build());
httpGet.addHeader("Accept", "application/json");
// NOTE: 建议指定charset=utf-8。低于4.4.6版本的HttpCore,不能正确的设置字符集,可能导致签名错误
response = getHttpDefaultClient().execute(httpGet);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
String result = EntityUtils.toString(response.getEntity());// 返回json格式:
return JSONObject.parseObject(result);
}else {
String result = EntityUtils.toString(response.getEntity());// 返回json格式:
log.info("微信支付V3 url={} result={} responseEntity={}",uriBuilder.build(), result,JSON.toJSONString(response.getEntity()));
}
} catch (Exception e) {
log.error("微信支付V3 请求url={}异常 ",uriBuilder.build());
}finally {
if(null!=response){
response.close();
}
}
post请求
HttpPost httpPost = new HttpPost(PAYSCORE_PAYAFTER_ORDERS_URL);
StringEntity reqEntity = new StringEntity(JSONObject.toJSONString(payAfterOrdersModel), ContentType.create("application/json", "utf-8"));
httpPost.setEntity(reqEntity);
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-Type", "application/json");
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
String result = EntityUtils.toString(response.getEntity());// 返回json格式:
log.info("微信支付V3 url={} result={} ",url,result);
return JSONObject.parseObject(result);
}else {
String result = EntityUtils.toString(response.getEntity());// 返回json格式:
log.info("微信支付V3 url={} result={} response.getEntity()={}",url,result,JSON.toJSONString(response.getEntity()));
}
} catch (Exception e) {
log.error("微信支付V3 请求url={} 参数={} 异常 e={}",url, JSON.toJSONString(json),e.getMessage());
}finally {
response.close();
}
官方DEMO参考: https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient/blob/master/src/test/java/com/wechat/pay/contrib/apache/httpclient/HttpClientBuilderTest.java
5、回调通知解密算法(AEAD_AES_256_GCM)
我们已一个实际接口为例,进行讲解:
下面我们对resource部分进行解密,解密算法如下:
package com.wsw.sdk.utils;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class WxAPIV3AesUtil {
static final int KEY_LENGTH_BYTE = 32;
static final int TAG_LENGTH_BIT = 128;
private final byte[] aesKey;
public WxAPIV3AesUtil(byte[] key) {
if (key.length != KEY_LENGTH_BYTE) {
throw new IllegalArgumentException("无效的ApiV3Key,长度必须为32个字节");
}
this.aesKey = key;
}
public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)
throws GeneralSecurityException, IOException {
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);
}
}
}
调用示例:
//解密回调信息
byte[] key = SystemConst.WX_KEY.getBytes("UTF-8");
WxAPIV3AesUtil aesUtil = new WxAPIV3AesUtil(key);
String decryptToString = aesUtil.decryptToString(assc.getBytes("UTF-8"),noce.getBytes("UTF-8"),cip);
最后
以上就是安详春天为你收集整理的WechatPay-API-v3接口规则 WechatPay-API-v3接口规则1、官方文档2、下面是Java 接入过程: 3、敏感信息加解密4、demo参考 5、回调通知解密算法(AEAD_AES_256_GCM)的全部内容,希望文章能够帮你解决WechatPay-API-v3接口规则 WechatPay-API-v3接口规则1、官方文档2、下面是Java 接入过程: 3、敏感信息加解密4、demo参考 5、回调通知解密算法(AEAD_AES_256_GCM)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复