-
Notifications
You must be signed in to change notification settings - Fork 446
支付示例(JSAPI)
jinyu edited this page Mar 8, 2017
·
11 revisions
String openId = "用户的唯一标识,如owGBft_vbBbOaQOmpEUE4xDLeRSU";
String body = "支付描述,如订单费用";
String outTradeNo = "商户侧唯一订单号,如18789913341";
double totalFee = 1d; // 订单金额 单位元
String notifyUrl = "支付完成后的回调地址,如http://wx.xxx.com/pay/notify";
String createIp = "发起支付时的客户端IP地址,如192.168.1.1";
String attach = "支付时的附加信息,在回调时会原样带上,可为空";
// 发起一个JS支付请求,这里有个值得注意的地方:微信返回的预交易ID(payRequest.getPrePayId())是有2小时的时效性的,
//超过2小时将不能重新发起支付,需重新生成一个`outTradeNo`订单号再次调用createJSPayRequest接口。
//所以这里的`prePayId`有两种解决方案:1、每次发起支付都重新生成`outTradeNo`订单号,然后调用createJSPayRequest接口。
//2、把`prePayId`缓存起来,然后通过:MchPayRequest payRequest = new JSAPIPayRequest(prePayId,weixinPayProxy.getPayAccount());
//构建一个`MchPayRequest`支付对象。两种方式都有利有弊,请根据实际需求而定。
MchPayRequest payRequest = weixinPayProxy.createJSPayRequest(openId, body, outTradeNo, totalFee, notifyUrl, createIp, attach);
// 将支付JSON串放到request作用域
request.setAttribute("JSPAY", payRequest.toRequestString());
// model.addAttribute("JSPAY", payRequest.toRequestString());
// modelAndView.addObject("JSPAY", payRequest.toRequestString());
var jspay = ${jspay}; // 接收后台传递过来的支付串
// 调用微信支付JS接口
WeixinJSBridge.invoke('getBrandWCPayRequest',jspay,function(res){
if(res.err_msg == 'get_brand_wcpay_request:ok'){
// 支付已完成!,注意这里支付完成指的是前端JS发起支付的操作顺利完成,
//并不意味着真正的支付成功,强烈建议到支付回调中去校验支付成功与否。
} else if (res.err_msg == 'get_brand_wcpay_request:fail'){
// 支付出现问题,请稍后再试!
} else if (res.err_msg == 'get_brand_wcpay_request:cancel'){
// 已取消支付,请重新支付!
} else {
// 支付被拒绝了
}
});
/**
* 微信支付成功(前端)时的回调通知
*
* @param inputStream
* 订单回调
* @return <xml><br>
* <return_code>SUCCESS/FAIL</return_code><br>
* <return_msg>如非空,为错误 原因签名失败参数格式校验错误</return_msg><br>
* </xml>
* @throws IOException
* @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7">支付结果通知</a>
*/
@RequestMapping("/order/notify")
@ResponseBody
public String payNotify(InputStream input) throws IOException {
//获取订单信息
String content = StringUtil.newStringUtf8(IOUtil.toByteArray(input));
Order order = ListsuffixResultDeserializer.deserialize(content,
Order.class);
log.info("jsapi_notify_order_info:", order);
//验证签名
String sign = order.getSign();
String valid_sign = weixinPayProxy.getWeixinSignature().sign(order);
log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign);
if (!sign.equals(valid_sign)) {
return XmlStream.toXML(new XmlResult(Consts.FAIL, "签名错误"));
}
// TODO 处理业务逻辑,如没有特殊要求可以考虑单独启一个线程去处理自己的业务,对于微信签名过后就可以返回success了。
// 需要ajax的形式返回给微信,保证返回值能写到ResponseInputStream就行,Spring mvc使用 @ResponseBody注解,Servlet使用HttpServletResponse#getWrite#write
return XmlStream.toXML(new XmlResult(Consts.SUCCESS, ""));
}