大家好, 我是上白书妖!
知识源于积累,登峰造极源于自律
今天我根据以前所以学的一些文献,笔记等资料整理出一些小知识点
1、API:查询订单接口文档
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_2
定时调用controller方法查询订单状态,当返回状态为success时,controller方法返回结果。前端代码收到结果后跳转到成功页面。
2、辅助业务方法
WeixinPayService:updateOrderStatus
接口:
/**
* 更改订单状态
* @param map
*/
void updateOrderStatus(Map<String, String> map);
实现:
/**
* 支付成功更改订单状态
* @param map
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void updateOrderStatus(Map<String, String> map) {
String orderNo = map.get("out_trade_no");
Order order = orderService.getOrderByOrderNo(orderNo);
order.setStatus(1);
orderService.updateById(order);
//记录支付日志
PayLog payLog=new PayLog();
payLog.setOrderNo(order.getOrderNo());//支付订单号
payLog.setPayTime(new Date());
payLog.setPayType(1);//支付类型
payLog.setTotalFee(order.getTotalFee());//总金额(分)
payLog.setTradeState(map.get("trade_state"));//支付状态
payLog.setTransactionId(map.get("transaction_id"));
payLog.setAttr(new Gson().toJson(map));
payLogMapper.insert(payLog);//插入到支付日志表
//更改课程购买数量
courseFeignClient.updateBuyCountById(order.getCourseId());
}
3、查询支付状态业务
WeixinPayService:queryPayStatus
接口:
/**
* 根据订单号去微信服务器查询支付状态
* @param orderNo
* @return
*/
Map<String, String> queryPayStatus(String orderNo);
实现:
@Override
public Map<String, String> queryPayStatus(String orderNo) {
try {
//1、封装参数
Map<String, String> m = new HashMap<>();
m.put("appid", weixinPayProperties.getAppid());
m.put("mch_id", weixinPayProperties.getPartner());
m.put("out_trade_no", orderNo);
m.put("nonce_str", WXPayUtil.generateNonceStr());
//2、设置请求
HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
client.setXmlParam(WXPayUtil.generateSignedXml(m, weixinPayProperties.getPartnerkey()));
client.setHttps(true);
client.post();
//3、返回第三方的数据
String xml = client.getContent();
Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
// System.out.println(xml);
// System.out.println(resultMap.get("return_code"));
// System.out.println(resultMap.get("return_msg"));
// System.out.println(resultMap.get("err_code"));
// System.out.println(resultMap.get("err_code_des"));
if("FAIL".equals(resultMap.get("return_code")) || "FAIL".equals(resultMap.get("result_code")) ){
log.error("查询支付结果错误 - " +
"return_msg: " + resultMap.get("return_msg") + ", " +
"err_code: " + resultMap.get("err_code") + ", " +
"err_code_des: " + resultMap.get("err_code_des"));
throw new GuliException(ResultCodeEnum.PAY_ORDERQUERY_ERROR);
}
//4、返回map
return resultMap;
} catch (Exception e) {
log.error(ExceptionUtils.getMessage(e));
throw new GuliException(ResultCodeEnum.PAY_ORDERQUERY_ERROR);
}
}
4、查询支付状态接口
ApiWeixinPayController:queryPayStatus
/**
* 查询支付状态
* @param orderNo
* @return
*/
@GetMapping("/queryPayStatus/{orderNo}")
public R queryPayStatus(@PathVariable String orderNo) {
//调用查询接口
Map<String, String> map = weixinPayService.queryPayStatus(orderNo);
if ("SUCCESS".equals(map.get("trade_state"))) {//支付成功
//更改订单状态
weixinPayService.updateOrderStatus(map);
return R.ok().message("支付成功");
}
return R.setResult(ResultCodeEnum.PAY_RUN);//支付中
}
二、前端整合
1、api
api/pay.js
queryPayStatus(out_trade_no) {
return request({
baseURL: 'http://localhost:8170',
url: `${apiPath}/queryPayStatus/${out_trade_no}`,
method: 'get'
})
}
2、支付页面
pages/pay/_id.vue
mounted() {
const timer = setInterval(() => {
console.log('执行定时器 ' + this.payObj.out_trade_no)
this.queryPayStatus()
}, 3000)
// vue中清除定时器
this.$once('hook:beforeDestroy', () => {
console.log('清除定时器')
clearInterval(timer)
})
},
methods: {
// 查询订单状态
queryPayStatus() {
console.log('查询订单状态 ' + this.payObj.out_trade_no)
pay.queryPayStatus(this.payObj.out_trade_no).then(response => {
if (response.data.success) {
this.$message({
type: 'success',
message: '支付成功!'
})
// 离开页面,触发hook:beforeDestroy,清除定时器
// 跳转到课程详情页面观看视频
this.$router.push({ path: '/course/' + this.payObj.course_id })
}
})
}
}