Java微信H5支付实现流程及代码解析
1. 整体流程
Java微信H5支付的实现流程可以简单分为以下几个步骤:
- 获取微信支付配置信息:包括商户号、AppID、AppSecret、商户密钥等;
- 用户发起支付请求:用户在H5页面选择支付方式,并填写支付金额等信息;
- 统一下单:开发者后台通过微信支付接口生成预支付订单,并返回支付参数给H5页面;
- 唤起微信支付:H5页面通过调用微信支付JSAPI唤起微信支付界面;
- 用户支付完成:用户在微信支付界面中输入密码完成支付;
- 支付结果通知:微信服务器将支付结果通知给开发者后台;
- 校验支付结果:开发者后台校验支付结果的有效性,并进行相应的业务处理;
- 返回支付结果:开发者后台将支付结果返回给H5页面。
下面将逐步解析每一步需要做的事情,并给出相应的代码示例。
2. 获取微信支付配置信息
首先,你需要在微信支付商户平台注册账号,并获取到以下配置信息:
- 商户号(mchId):商户在微信支付平台的唯一标识;
- AppID:微信公众号或小程序的唯一标识;
- AppSecret:用于生成AccessToken的密钥;
- 商户密钥(key):商户用于生成签名和校验签名的密钥。
3. 用户发起支付请求
用户在H5页面选择支付方式,并填写支付金额等信息。这一步主要由前端实现,后端需要提供接口用于接收支付请求数据。
4. 统一下单
开发者后台通过微信支付接口生成预支付订单,并返回支付参数给H5页面。
// 发起统一下单请求
String url = "
String xmlData = generateXmlData(); // 生成请求参数的XML格式数据
String responseXml = sendPostRequest(url, xmlData); // 发送POST请求,获取响应结果
// 解析响应结果
Map<String, String> resultMap = parseXmlData(responseXml);
String prepayId = resultMap.get("prepay_id"); // 获取预支付订单ID
// 构造支付参数
String timestamp = String.valueOf(System.currentTimeMillis() / 1000); // 时间戳
String nonceStr = generateNonceStr(); // 随机字符串
String packageStr = "prepay_id=" + prepayId; // 预支付订单ID
String signType = "MD5"; // 签名类型
String sign = generateSign(appId, timestamp, nonceStr, packageStr, signType); // 生成签名
// 构造返回给H5页面的支付参数
Map<String, String> payParams = new HashMap<>();
payParams.put("appId", appId);
payParams.put("timeStamp", timestamp);
payParams.put("nonceStr", nonceStr);
payParams.put("package", packageStr);
payParams.put("signType", signType);
payParams.put("paySign", sign);
// 返回支付参数给H5页面
return payParams;
其中,generateXmlData()
方法用于生成请求参数的XML格式数据,sendPostRequest()
方法用于发送POST请求并获取响应结果,parseXmlData()
方法用于解析响应结果的XML数据,generateNonceStr()
方法用于生成随机字符串,generateSign()
方法用于生成签名。
5. 唤起微信支付
H5页面通过调用微信支付JSAPI唤起微信支付界面。
function onBridgeReady() {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
"appId": "${appId}", // 从后台获取的AppID
"timeStamp": "${timeStamp}", // 从后台获取的时间戳
"nonceStr": "${nonceStr}", // 从后台获取的随机字符串
"package": "${package}", // 从后台获取的支付参数
"signType": "${signType}", // 从后台获取的签名类型
"paySign": "${paySign}" // 从后台获取的签名
}, function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 支付成功后的处理逻辑
} else {
// 支付失败后的