1.引入依赖
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
2.配置类
此处用到是前锋教育的商户
public class MyPayConfig implements WXPayConfig {
@Override
public String getAppID() {
//应用ID
return "wx632c8f211f8122c6";
}
@Override
public String getMchID() {
//直连商户号
return "1497984412";
}
@Override
public String getKey() {
//- 商户Key:sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC
return "sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC";
}
@Override
public InputStream getCertStream() {
return null;
}
@Override
public int getHttpConnectTimeoutMs() {
return 0;
}
@Override
public int getHttpReadTimeoutMs() {
return 0;
}
}
3.使用Native下单
@RestController
@RequestMapping("orders")
@CrossOrigin
@Api(value = "提供订单详情接口", tags = "订单管理")
public class OrdersController {
@Autowired
private OrdersService ordersService;
@ApiOperation("添加订单")
@PostMapping("/add")
public ResultVo addOrders(String cids, @RequestBody Orders orders) {
ResultVo ok = ResultVo.ok();
try {
Map<String, String> orderInfo = ordersService.addOrders(orders, cids);
WXPay wxPay = new WXPay(new MyPayConfig());
HashMap<String, String> map = new HashMap<>();
map.put("body", orderInfo.get("productNames")); // 商品描述
map.put("trade_type", "CNY"); // 支付币种
map.put("out_trade_no", orderInfo.get("orderId")); //使用当前用户订单的编号作为当前支付交易的交易号
map.put("total_fee","1"); //支付金额 orders.getActualAmount()*100+""
map.put("trade_type", "NATIVE"); //交易类型
map.put("notify_url","https://3ad6-120-216-179-100.jp.ngrok.io/pay/callback"); //设置支付完成时返回的地址
Map<String, String> res = wxPay.unifiedOrder(map);
ok.data("payUrl",res.get("code_url")).data("productNames",orderInfo.get("productNames")).data("orderId",orderInfo.get("orderId"));
} catch (SQLException e) {
return ResultVo.error().message("提交订单失败");
} catch (Exception e) {
return ResultVo.error().message("库存不足或提交订单失败");
}
return ok;
}
@ApiOperation("查询商品支付状态")
@GetMapping("/orderStatus/{oid}")
public ResultVo getOrderStatus(@PathVariable("oid") String orderId){
return ordersService.getOrderById(orderId);
}
}
4.微信支付回调接口
1.使用内网穿透ngrok进行回调
@RestController
@RequestMapping("pay")
@CrossOrigin
public class PayController {
@Autowired
private OrdersService ordersService;
@ApiOperation("微信支付成功回调接口")
@PostMapping("/callback")
public String success(HttpServletRequest request) throws Exception {
ServletInputStream is = request.getInputStream();
byte[] bytes = new byte[1024];
int len = -1;
StringBuilder stringBuilder = new StringBuilder();
while ((len = is.read(bytes)) != -1){
stringBuilder.append(new String(bytes,0,len));
}
String s = stringBuilder.toString();
//使用帮助类 将xml接口的字符转换成map
// 不是json格式不能用json转
Map<String, String> map = WXPayUtil.xmlToMap(s);
if(map != null && "success".equalsIgnoreCase(map.get("result_code"))){
// 支付成功
// 修改订单状态为“代发货/已支付/
String orderId = map.get("out_trade_no");
int i = ordersService.updateOrderStatus(orderId,"2");
WebSocketService.sendMessage(orderId,"1");
if (i > 0){
//响应微信支付平台 否则微信一直响应
HashMap<String, String> resp = new HashMap<>();
resp.put("return_code","success");
resp.put("return_msg","OK");
resp.put("appid",map.get("appid"));
return WXPayUtil.mapToXml(resp);
}
}
return null;
}
}
5.前端详情
1.订单详情
doSubmit: function() {
//将订单信息提交到:添加订单接口
//1.准备订单数据
var address = this.addrs[this.addrIndex].province + " " + this.addrs[this.addrIndex].city +
" " +
+this.addrs[this.addrIndex].area + " " + this.addrs[this.addrIndex].addr;
var orders = {
"actualAmount": this.totalPrice,
"orderRemark": this.orderRemark,
"payType": this.payType,
"receiverAddress": address,
"receiverMobile": this.addrs[this.addrIndex].receiverMobile,
"receiverName": this.addrs[this.addrIndex].receiverName,
"totalAmount": this.totalPrice,
"userId": getCookieValue("userId")
};
//2.提交订单
var url3 = baseUrl + "orders/add";
axios({
url: url3,
method: "post",
headers: {
token: getCookieValue("token")
},
params: {
cids: this.cartIds
},
data: orders
}).then((res) => {
if (res.data.code == 200) {
//跳转到支付页面显示支付二维码
var orderInfo = res.data.data; // {orderId:"123123",productNames:"aseraer",payUrl:"weixin://...."}
orderInfo.totalPrice = this.totalPrice; // {orderId:"123123",productNames:"aseraer",payUrl:"weixin://....",totalPrice:18.8}
localStorage.setItem("orderInfo", JSON.stringify(orderInfo));
window.location.href = "order-pay.html";
} else if (res.data.code == 2001 || res.data.code == 2002) {
window.location.href = "login.html";
} else {
alert(res.data.msg);
}
}).catch((err)=>{
console.log(err)
});
}
2.支付详情
1.使用qrcode.makeCode(this.orderInfo.payUrl);生成二维码
<script type="text/javascript">
var baseUrl = "http://localhost:8080/"
var webSocketBaseUrl = "ws://localhost:8080/"
var vm = new Vue({
el: "#container",
data: {
orderInfo: {}
},
created() {
var jsonstr = localStorage.getItem("orderInfo");
if (jsonstr != null) {
localStorage.removeItem("orderInfo");
}
var orderInfo = eval("(" + jsonstr + ")")
this.orderInfo = eval("(" + jsonstr + ")");
},
mounted() {
var qrcode = new QRCode($("#payQrcodeDiv")[0], {
width: 200,
height: 200
});
qrcode.makeCode(this.orderInfo.payUrl);
// 前端发送websocket连接请求
var websocket = null;
var webSocketUrl = webSocketBaseUrl + "webSocket/" + this.orderInfo.orderId;
websocket = new WebSocket(webSocketUrl);
// 只要后端通过websocket向此连接发送消息就会触发onmessage事件
websocket.onmessage = function(event) {
console.log(event)
var msg = event.data;
if (msg == "1") {
$("#div1").html("<label style='font-size:20px; color:green'>订单支付完成!</label>")
}
}
}
// var oid = this.orderInfo.orderId;
// var i = setInterval(function(){
// console.log("=========")
// var url = baseUrl + "orders/orderStatus/" + oid
// axios({
// url:url,
// method:"get",
// headers:{
// token:getCookieValue("token")
// }
// }).then((res) => {
// if (res.data.data.orderStatus == "1") {
// // 订单未支付
// } else if (res.data.data.orderStatus == "2") {
// $("#div1").html("<label style='font-size:20px; color:green'>订单支付完成!</label>")
// clearInterval(i);
// }
// })
// },1000);
})
</script>