结合官方文档和本篇博客,你在对接微信支付过程中将一路通畅,如果遇到问题可以评论或私信我,我给你解答。
文章目录
1. 前提条件
已经注册了微信支付商户号。
2. 微信支付对接
官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/index.shtml
微信支付方式包含如下几种:
- JSAPI支付
- APP支付
- H5支付
- Native支付
- 小程序支付
- 合单支付
- 付款码支付
我们根据我们自己的使用场景选择支付方式,大部分的接入方式都是差不多的,核心部分都是初始化微信支付提供的SDK的httpclient,因为他给我们封装了签名生成,签名的验证,敏感信息的加密,接下来我以jsapi的支付方式来讲如何接入微信支付。
3. jsapi支付整体对接流程
4. 核心问题处理,httpclient初始化
4.1 httpclient初始化代码
/**
* wechatPayKey 下载的微信平台证书
* privateKey 商户平台对应商户号号的私钥
* mchId 商户号id
* mchSerialNo 证书序列号
* apiV3Key 商户平台设置的apikey
*/
public WechatHttpClient() throws UnsupportedEncodingException {
//加载事先下载的微信支付平台证书
X509Certificate certificate = PemUtil.loadCertificate(new ByteArrayInputStream(wechatPayKey.getBytes("utf-8")));
List<X509Certificate> certificateList = new ArrayList<>();
certificateList.add(certificate);
// 加载商户私钥(privateKey:私钥字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 自动加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
// 初始化httpClient
this.httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
//自动下载微信平台证书方式
.withValidator(new WechatPay2Validator(verifier)).build();
//手动下载微信支付平台证书方式
// .withWechatpay(certificateList).build();
}
4.2 下载微信支付平台证书
加载微信支付平台的公钥证书有两种方式,一种是sdk封装的AutoUpdateCertificatesVerifier自动下载证书方式,还有一种是下载jar包CertificateDownloader,自己主动去下载平台证书,下面要说的是如何自主下载支付平台证书。
- 首先下载CertificateDownloaderjar包:点击前往下载
- 其次按说明执行以下命令下载证:
这里,必需参数有:java -jar CertificateDownloader.jar -k ${apiV3key} -m ${mchId} -f ${mchPrivateKeyFilePath} -s ${mchSerialNo} -o ${outputFilePath} -c ${wechatpayCertificateFilePath}
- 商户的私钥文件,即 -f
- 证书解密的密钥,即 -k
- 商户号,即 -m
- 保存证书的路径,即 -o
- 商户证书的序列号,即 -s
非必需参数有: - 微信支付证书,用于验签,即 -c
5. 接入微信支付常见问题
- javax.crypto.AEADBadTagException: Tag mismatch
- 应答的微信支付签名验证失败
- 微信支付凭证中文描述乱码
- 时间保存入库多了八个钟
- 问题1:由于apiv3Key密码错误,建议登录微信商户平台修改密码;
- 问题2:微信支付平台证书错误,导致结果校验失败,当时出现这个问题时我是错误的将商户平台的公钥当做微信支付平台证书使用了,所以解决办法是参考4.2下载微信支付平台证书。
- 问题3:参考如下代码,方案是设置请求参数body字符集utf-8
//请求URL HttpPost httpPost = new HttpPost(WeChatPayConstants.transactionUrl); //处理支付凭证中文乱码,设置参数body字符集utf-8 StringEntity entity = new StringEntity(reqParam, Charsets.toCharset("UTF-8")); entity.setContentType("application/json"); httpPost.setEntity(entity); httpPost.setHeader("Accept", "application/json");
- 问题4:更改DatePattern值为UTC_SIMPLE_PATTERN,代码如下,详情看注释
//订单完成时间 String successTime = jsonObject.getString("success_time"); logger.info("处理前完成时间:" + successTime); //微信给回的时间格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE的字符串 //我们需要将字符串转换成时间类型,然后存库,注意这里采用的DatePattern, //如果使用UTC_SIMPLE_FORMAT则会在原基础时间上加8个钟 DateTime completeTime = DateUtil.parse(successTime, DatePattern.UTC_SIMPLE_PATTERN);