前期准备
H5支付V2版本
官方文档
需要的参数
-
app_id:公众号或者小程序申请
-
mch_id:在微信商户平台申请
-
支付密钥:申请后在商户平台中设置支付密钥和证书。这个记得保存,因为证书让进行二次下载,找不到了只能重新设置。
-
SDK下载:官方SDK下载地址
官方流程图
Java后台编写WXPayConfig的实现类进行必要参数配置
/**
* 微信支付参数配置
*/
public class IWXPayConfig extends WXPayConfig {
private byte[] certData;
private String app_id = "自己的appid";
private String wx_pay_key = "自己的支付密钥";
private String wx_pay_mch_id = "自己的商户号";
/**
* 构造方法读取证书, 通过getCertStream 可以使sdk获取到证书
*/
public IWXPayConfig() throws Exception {
String certPath = "证书的路径";
File file = new File(certPath);
InputStream certStream = new FileInputStream(file);
this.certData = new byte[(int) file.length()];
certStream.read(this.certData);
certStream.close();
}
@Override
protected String getAppID() {
return app_id;
}
@Override
public String getMchID() {
return wx_pay_mch_id;
}
@Override
protected String getKey() {
return wx_pay_key;
}
@Override
protected InputStream getCertStream() {
return new ByteArrayInputStream(this.certData);
}
@Override
protected IWXPayDomain getWXPayDomain() { // 这个方法需要这样实现, 否则无法正常初始化WXPay
IWXPayDomain iwxPayDomain = new IWXPayDomain() {
@Override
public void report(String domain, long elapsedTimeMillis, Exception ex) {
}
@Override
public DomainInfo getDomain(WXPayConfig config) {
return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);
}
};
return iwxPayDomain;
}
}
进行调用微信官方的SDK下单
public static Map placeAnOrder() throws Exception {
IWXPayConfig wxPayConfig = new IWXPayConfig();
WXPay wxPay = new WXPay(wxPayConfig);
Map<String, String> data = new HashMap<>();
data.put("body", "商品描述");
data.put("total_fee", "1"); // 订单金额, 单位分
data.put("spbill_create_ip", "114.114.114.114"); // 下单ip
data.put("notify_url", "http://xxxxxxxx/payCallback"); // 订单结果通知, 微信主动回调此接口
data.put("out_trade_no", "2016090910595900000028"); // 订单唯一编号, 不允许重复
data.put("trade_type", "MWEB"); // 交易类型 MWEB--H5支付、JSAPI--小程序支付 每个类型需要参数不同
return wxPay.unifiedOrder(data);
}
订单通知地址需要外网可以访问,如果没有可以用映射的方式映射本地的端口让外网访问。这里推荐免费的映射软件:闪库 这个软件也是我开发时用的,主要是免费
调用后会返回数据这些数据官方文档都有介绍不多说了。
其中最重要的一个就是mweb_url这个参数,这个就是支付地址了。如果直接访问这个地址就会出现下方的错误信息:
这个官方也有解释是因为请求头中的referer为空导致的。
这个值是自己在商户平台进行配置的地址。
这里面有个授权域名这个就是referer的值。这个值的意思就是告诉微信从哪里跳转过来的。
在浏览器通过工具改以下这个值就可以正常访问,但是如果是pc浏览器访问的可能是空白页面,这个时候F12看下应该是提示没有解析什么的东西。这个是因为pc浏览器无法拉起微信客户端进行支付。
在手机浏览器没有办法设置请求头,所以只能进入自己设置的那个域名服务器设置个标签进行跳转了。然后就能进行支付了。这个真的会支付掉,我开发没有找到如何微信的沙盒。
设置回调方法
/**
* 支付结果回调
*/
@RequestMapping(value = "/payCallback")
public String payCallback(HttpServletRequest request) {
Map<String, String> back = new HashMap(); // 校验结果
String backXml = ""; // 校验结果XML
try {
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
String result = new String(outSteam.toByteArray());
Map<String, String> map = WXPayUtil.xmlToMap(result);//xml转map 微信SDK自带
// 判断签名是否正确
if (WXPayUtil.isSignatureValid(data, wxPayConfig.getKey(), WXPayConstants.SignType.HMACSHA256)) { // 这里记得指定加密方式,因为下单默认的是h256方式,校验默认是MD5方式
back.put("return_code", "SUCCESS");
if (BusinessStatus.SUCCESS.equals(map.get("result_code")));{ // 判断支付成功
// 进行自己的业务处理
}
} else {
back.put("return_code", "FAIL");
back.put("return_msg", "参数格式校验错误");
}
backXml = WXPayUtil.mapToXml(back);
} catch (Exception e) {
e.printStackTrace();
} finally {
return backXml;
}
}
这个方法微信可能多次调用,这个官方也有说明自己做好处理。
参考文章
本人开发后写的博客,其中可能有遗漏的地方。有问题欢迎指出