微信native支付同样调用微信统一下单api,返回prepay_id (支付订单id) 和code_url(扫码支付的链接),把code_url返回给前端,前端生成二维码,用户扫码支付,也可以后端生成
@PostMapping("/nativePayOrder")
@ApiOperation("微信Native支付")
public R nativePayOrder(@RequestBody PayOrderForm form, @RequestHeader HashMap<String,Object> map) {
ValidatorUtils.validateEntity(form);
String token = map.get("token").toString();
Integer userId = Integer.parseInt(jwtUtils.getClaimByToken(token).getSubject());
LambdaQueryWrapper<UserEntity> uew = new LambdaQueryWrapper<>();
uew.eq(UserEntity::getUserId, userId);
UserEntity user = userService.getOne(uew);
if (user == null) {
return R.error("用户不存在!");
}
LambdaQueryWrapper<Order> oew = new LambdaQueryWrapper<>();
Integer orderId = form.getOrderId();
oew.eq(Order::getId, orderId);
Order order = orderService.getOne(oew);
if (order == null) {
return R.error("该用户没有此订单!");
}
if (!Objects.equals(order.getStatus(), EnumUtil.PAY_STATUS_NO_PAY.getCode())) {
return R.error("该订单已支付!");
}
//判断优惠券是否过期
//判断活动是否过期
//向微信平台发送创建支付订单的请求
try {
//微信支付的单位是分,要转换一下
String amount = String.valueOf(order.getAmount().multiply(BigDecimal.valueOf(100)).intValue());
WXPay wxPay = new WXPay(wxPayConfig);
Map<String, String> paramMap = new HashMap<>();
String nonceStr = WXPayUtil.generateNonceStr();
paramMap.put("nonce_str", nonceStr); //随机字符串
paramMap.put("body", "商品备注信息");
paramMap.put("out_trade_no", order.getCode()); //商品订单流水号,必须为一
paramMap.put("total_fee", amount); //订单金额
paramMap.put("spbill_create_ip", "127.0.0.1");
paramMap.put("notify_url", "127.0.0.1/notify"); //异步通知url 必须为外网地址
paramMap.put("trade_type", "NATIVE"); //交易类型
String sign = WXPayUtil.generateSignature(paramMap, wxConfiguration.getMchKey());
paramMap.put("sign", sign);
Map<String, String> result = wxPay.unifiedOrder(paramMap);
log.info("result:{}",result);
//支付订单Id
String prepayId = result.get("prepay_id");
String codeUrl = result.get("code_url");
if (StringUtils.isNotBlank(prepayId)) {
order.setPrepayId(prepayId);
orderService.updateById(order);
}else {
log.error("微信支付出现异常,订单号:{}",orderId);
return R.error("微信支付出现异常,订单号:{}" + orderId);
}
Map<String, Object> map1 = new HashMap<>();
map1.put("codeUrl", codeUrl);
return R.ok(map1);
} catch (Exception e) {
e.printStackTrace();
log.error("微信支付出现异常,订单号:{}",orderId);
return R.error("微信支付出现异常,订单号:{}" + orderId);
}
}
@GetMapping("/qrcode")
@ApiOperation("根据前端传过来的codeUrl生成二维码图片")
public void qrCode(HttpServletRequest request,HttpServletResponse response) throws IOException {
String codeUrl = request.getParameter("codeUrl");
QrConfig qrConfig = new QrConfig();
qrConfig.setHeight(250);
qrConfig.setWidth(250);
qrConfig.setMargin(2);
OutputStream outputStream = response.getOutputStream();
QrCodeUtil.generate(codeUrl,qrConfig,"jpg",outputStream);
outputStream.close();
}
前端代码使用jquery编写
用户扫码支付完成之后,前端使用定时器调用后端接口查询支付订单状态,然后刷新页面,或者用户点击<我已支付>按钮查询支付订单状态进行页面跳转刷新
$(function () {
//查询遍历订单
$.ajax({
url: wxUrl.searchUserOrderList,
type: 'post',
dataType: 'json',
contentType: 'application/json',
beforeSend: function (request) {
request.setRequestHeader('token', localStorage.getItem('token'));
},
data: JSON.stringify({
pageNum: 1,
pageSize: 20,
}),
success(res) {
let list = res.list;
console.log(list);
let temp = '';
for (let one of list) {
if (one.status === 1) {
one.status = '未付款';
} else if (one.status == 2) {
one.status = '已付款';
} else if (one.status == 3) {
one.status = '已发货';
} else if (one.status == 4) {
one.status = '已签收';
}
let button = '';
if (one.status == '未付款') {
button = '<input type="button" value="支付" class="pay-btn">';
}
temp += `
<div class="order" data-order-id=${one.id}>
<div class="row row-1">
<span>订单编号:${one.code}</span>
<span>${one.status}</span>
</div>
<div class="row row-2">
假设这里是商品订单概要信息
</div>
<div class="row row-3">
<div>
金额:<span>${one.amount}元</span>
</div>
${button}
</div>
</div>
`;
}
$('.order-list').append(temp);
// 给支付按钮绑定点击事件
$('.pay-btn').click(function () {
let orderId = $(this).parents('.order').data('order-id');
$.ajax({
url: wxUrl.nativePayOrder,
type: 'post',
dataType: 'json',
contentType: 'application/json',
beforeSend: function (request) {
request.setRequestHeader('token', localStorage.getItem('token'));
},
data: JSON.stringify({
orderId: orderId,
}),
success(res) {
console.log(res);
let codeUrl = res.codeUrl;
$('.qrcode').attr('src', wxUrl.qrcode + '?codeUrl=' + codeUrl);
// 添加自定义属性 orderId
$('.close-btn').attr('data-order-id', orderId);
$('#native').show();
/* 创建一个定时器,调用后端查询支付订单状态,最多执行5次 */
let num = 0;
let timer = setInterval(() => {
num++;
let result = searchOrderStatus(orderId);
if (result) {
clearInterval(timer);
location.reload();
} else {
if (num == 5) {
clearInterval(timer);
}
}
}, 5000);
},
});
});
},
});
/* 查询支付订单状态 */
function searchOrderStatus(orderId) {
let flag = false;
$.ajax({
url: wxUrl.searchOrderStatus,
type: 'post',
dataType: 'json',
contentType: 'application/json',
// 使用同步
async: false,
beforeSend: function (request) {
request.setRequestHeader('token', localStorage.getItem('token'));
},
data: JSON.stringify({
orderId: orderId,
}),
success(res) {
if (res.msg == '微信支付成功') {
flag = true;
}
},
});
return flag;
}
/* 点击<我已支付>按钮主动查询支付订单状态 */
$('.close-btn').click(function () {
let orderId = $(this).data('order-id');
let result = searchOrderStatus(orderId);
if (result) {
location.reload();
}
});
/* 关闭弹出图层事件 */
$('.close-icon').click(function () {
$('#native').hide();
});
});