Foreword
Micro-channel pay - micro letter H5 external browser payments
micro-channel pay - micro letter H5 internal browser payments
micro-channel pay -PC end of the scan code to pay " article "
Benpian is the third in a series of micro-channel payment, PC scan code end payment.
Development Environment: Java + SpringBoot + Vue + WxJava (open source SDK)
Process added: on micro-channel PC side scan code to pay, first of all front-end to back-end transfer the amount of goods to pay two-dimensional code generated contents, "two-dimensional code generated by the front end of this case," get the content returned by the backend, front-end based on two-dimensional content generation code and then presented to the user, the user scan code successful payment, micro-channel official pushed to the back-end user interfaces result disbursement letter, and then update order information database based on the results.
The following is a body part.
1, to obtain two-dimensional code content
Back-end interfaces need to create two-dimensional code, the specific code as follows:
/**
* 创建二维码
*/
@RequestMapping(value = "createQRCode", method = {RequestMethod.POST})
@ApiOperation(value = "创建二维码")
public Result<Object> createQRCode(@RequestBody WechatOrderRequest obj) {
Orders orders = null;
if (StringUtils.isNotBlank(obj.getOrderId())) {
orders = ordersService.searchOrder(obj.getUserId, obj.getOrderId());
} else {
orders = ordersService.createOrder(obj.getUserId, obj.getTotal_fee(), "new");
}
WechatOrderResponse wechatOrderResponse = new WechatOrderResponse();
wechatOrderResponse.setCodeUrl(wechatService.createOrderInfo(orders);
wechatOrderResponse.setOrderId(orders.getOrderId());
return ResultUtil.success(wechatOrderResponse);
}
About above method, WechatOrderRequest entity containing the amount of front-end merchandise, as well as the user information, the way to create an order "is a new order, an order to pay or not to pay again," etc. In short, the main role is to create an order entity, determine what the reason OrderId , because interface to share an order to pay again calls not paid.
About createOrder () method to create an order, as follows:
public Orders createOrder(String userId,String total_fee){
String orderId=ToolUtils.makeUUID();
Orders orders=new Orders();
orders.setOrderId(orderId);
orders.setOrderStatus("0");
orders.setAmount(new BigDecimal(total_fee));
orders.setCreateTime(new Date());
orders.setUserId(userId);
orders.setInvoice("0");
orders.setAppType(appType);
orders.setNonceStr(ToolUtils.makeUUID().toUpperCase());
ordersDao.insertOrders(orders);
return orders;
}
searchOrder () interface to query the order entity will not put out, it is simply query the database.
We then look at the main method, wechatService.createOrderInfo () :
@Transactional
public String createOrderInfo(Orders orders) {
WxPayMwebOrderResult result = null;
try {
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
orderRequest.setOutTradeNo(orders.getOrderId());
orderRequest.setBody("我是商品描述");
orderRequest.setTotalFee(orders.getAmount().multiply(new BigDecimal("100")).intValue());
orderRequest.setSpbillCreateIp(DispatchParams.getInstance().getWechatSpbillCreateIp());
orderRequest.setProductId(orders.getOrderId());
orderRequest.setTradeType(WxPayConstants.TradeType.NATIVE);
result = wxPayService.createOrder(orderRequest);
return result.getCodeUrl();
} catch (WxPayException e) {
logger.error("[微信支付异常] 异常", e);
throw 自定义异常;
}
}
补充:由于使用了 WxJava,所以接口相对是非常简洁的,赋予 WxPayUnifiedOrderRequest 对象必须的参数,比如支付金额,商品描述,ip,支付类型等,然后调动 createOrder() 方法就能得到二维码内容了,具体请求过程可以自己进入源码查看。
返回的内容格式:weixin://wxpay/bizpayurl?pr=1RhYbXa
ok,我们再回到最开始的方法,我们将获得的二维码内容、订单id,返回给前端,二维码内容供前端生成二维码,而订单id的作用则是,在当前支付界面,前端根据订单id不停地请求后端订单查询接口,如果后端返回结果,给出响应的提示,比如支付成功,支付失败等。
2、前端生成二维码
前端生成二维码有许多方式,本文采用 qrcodejs2 生成,package.json 加入以下依赖:
"dependencies": {
"qrcodejs2": "0.0.2"
}
代码中使用,如下代码精简过了,就两个主要方法,看个热闹就行哈,具体的自行实现:
<template>
<div>
<div id="qrcode" class="wechat_code"></div>
</div>
</template>
<script>
import QRCode from 'qrcodejs2'
export default {
methods:{
qrCode(){
if( this.codeUrl && this.codeUrl!==''){
if(this.qrcode !== null){
this.qrcode.clear();
this.qrcode.makeCode(this.codeUrl);
}else{
this.qrcode = new QRCode('qrcode', {
width: 200,
height: 200, // 高度
text: this.codeUrl // 二维码内容
})
}
this.setTimeout=setTimeout(this.queryOrder,3000)
}
},
queryOrder(){
if(this.orderId !== null && this.orderId !== ""){
定时查询后端,请自行修改接口
this.getRequest("请求路径", this.orderId).then(res => {
this.loading = false;
if (res.success) {
clearTimeout(this.setTimeout);
this.visible = false;
this.$Modal.success({
title: this.$t('global.prompt'),
content: this.$t('recharge.paySuccess',{ amount:this.money })
});
this.$emit('search-orders');
}else{
this.setTimeout=setTimeout(this.queryOrder,1500)
}
});
}
}
},
</script>
简单说一下这两个方法,qrCode() 用于根据后端返回的内容 codeUrl 创建二维码;
queryOrder() 方法永不不停地请求后端接口查询订单信息,如果返回数据,就不再继续调用自身,这块这样做就是为了给用户有好的提示,比如下方是一个支付二维码的弹窗,用户支付成功了,不但没有提示,窗口还一直打开着,想想用户体验是多么的不好。
3、微信推送支付结果
用户扫码支付后,微信会自动回调后端 notify 接口,具体如下「代码仅供参考」:
@RequestMapping(value = "/notify")
@ResponseBody
public String notify(@RequestBody String body) throws Exception {
WxPayOrderNotifyResult result = null;
try {
result = wxPayService.parseOrderNotifyResult(body);
} catch (WxPayException e) {
logger.error("[微信解析回调请求] 异常", e);
return WxPayNotifyResponse.fail(e.getMessage());
}
logger.info("处理微信支付平台的订单支付");
logger.info(JSONObject.toJSONString(result));
String appid = result.getAppid();//应用ID
String attach = result.getAttach();//商家数据包
String bank_type =result.getBankType();//付款银行
Integer cash_fee = result.getCashFee();//现金支付金额
String fee_type = result.getFeeType();//货币种类
String is_subscribe = result.getIsSubscribe();//是否关注公众账号
String mch_id = result.getMchId();//商户号
String nonce_str = result.getNonceStr();//随机字符串
String openid = result.getOpenid();//用户标识
String out_trade_no = result.getOutTradeNo();// 获取商户订单号
String result_code = result.getResultCode();// 业务结果
String return_code = result.getReturnCode();// SUCCESS/FAIL
String sign = result.getSign();// 获取签名
String time_end = result.getTimeEnd();//支付完成时间
Integer total_fee = result.getTotalFee();// 获取订单金额
String trade_type = result.getTradeType();//交易类型
String transaction_id = result.getTransactionId();//微信支付订单号
//如果成功写入数据库
if("SUCCESS".equals(return_code)) {// 如果微信返回的结果是success,则修改订单状态
Orders orders = ordersDao.selectByOrderId(out_trade_no);
// 验证签名
if(orders != null){
if(!"1".equals(orders.getOrderStatus())){//判断是否订单已经完成了
// 判断金额是否跟数据库订单金额一致,放置人为修改
if(orders.getAmount().multiply(new BigDecimal("100")).compareTo(new BigDecimal(total_fee)) == 0){
//更新订单状态
业务逻辑处理部分...
return WxPayNotifyResponse.success("订单已经处理成功!");
}else{
logger.error("微信:金额不一致!");
return WxPayNotifyResponse.fail("订单金额不一致");
}
}else {
return WxPayNotifyResponse.success("订单已经处理成功!");
}
}else{
return WxPayNotifyResponse.fail("商户订单号不匹配");
}
}
System.out.println("回调成功");
System.out.println("----返回给微信的xml:" + result);
return WxPayNotifyResponse.success("支付成功!");
}
最后
博客地址:https://www.cgblog.com/niceyoo
如果觉得这篇文章有丶东西,不放关注一下我,关注是对我最大的鼓励~
18年专科毕业后,期间一度迷茫,最近我创建了一个公众号用来记录自己的成长。