帮朋友基于SpringBoot鲜花商城系统,订制开发了一套适用于高校餐厅缴费系统;添加的功能如下:
1.商品搜索功能
2.个人中心
3.购物车下单改造
4.支付宝功能接入
5.管理员板块校园卡管理功能
本系统涉及到的技术主要如下
后台:SpringBoot+JPA
前台:bootstrap+layui+thymeleaf模板引擎
数据库:MySQL8.0
有需要源代码的可以私信!
校园卡余额不足,不可以支付
商家端充值1000,就可以支付了;
商家端:充值后1100,消费750,剩余350,没毛病;
1.配置沙箱支付
第一步:
1)登陆支付宝:https://open.alipay.com/
2)首页找到进入管理中心 -> 开发工具推荐选择【沙箱】
3)下载安装支付宝开放平台开发助手:
https://opendocs.alipay.com/common/02kipk
4)打开本地支付宝开放平台助手 -> 密钥工具 -> 生成密钥 -> 以默认方式(RSA2和PKCS8)生成应用私钥和应用公钥
5)在沙箱应用的开发信息中选择自定义密钥生成支付宝公钥(基于应用公钥生成支付宝公钥)
第二步:配置沙箱账号(买家)并完成手动充值
https://open.alipay.com/develop/sandbox/account
第三步:下载沙箱支付宝(只支持安卓)
https://open.alipay.com/develop/sandbox/tool/alipayclint
沙箱工具 -> 支付宝客户端沙箱版 -> 请使用浏览器中的扫码功能扫描下载
注:请使用Android手机扫码下载支付宝客户端沙箱版;如需登录,请访问沙箱账号,在商家信息中获取帐密
实现思路
1.完成支付宝沙箱支付功能接入
2.支付成功后变更订单状态
1.完成支付宝沙箱支付功能接入
根据官方网站开发文档进行支付宝支付接入
https://opendocs.alipay.com/common/02kg69
AlipayConfig.java
package com.javaxl.config;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.javaxl.entity.Order;
/**
* 支付宝沙箱支付
*/
public class AlipayConfig {
public String goAlipay(Order order){
Integer orderid = order.getId();
String subject = order.getName();
double totalAmount = order.getTotal();
try {
// 1. 设置参数(全局只需设置一次)
Factory.setOptions(aliconfig());
// 2. 发起API调用(subject商品标题、outTradeNo订单编号、totalAmount总金额、returnUrl异步通知地址)
AlipayTradePagePayResponse response = Factory.Payment.Page()
.pay(subject+"",
orderid+"",
totalAmount+"",
// "http://localhost:8081/page/ok.html"); //支付成功之后的异步通知(跳出到自己系统的哪个位置)
"http://localhost:8080/mall/order/pay.do?orderId="+orderid); //支付成功之后的异步通知(跳出到自己系统的哪个位置)
System.out.println(response.body);
return response.body;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private Config aliconfig(){
Config config=new Config();
//沙箱支付宝地址
config.gatewayHost="openapi.alipaydev.com";
//协议https httpclients
config.protocol="https";
//应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
config.appId="2016093000634935";
//支付宝公钥
config.alipayPublicKey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy/NfwxWr2SfktLUekBR+3w/MUjz1mnW7/wzTOkN1WWIx4i4Ak2m7XDl+evV76FPCcj40HfqgLXxxSVW5a1cCwJ8Z9EgEd7dd1J0EW6slx0v1XMHoPQgOkEVijSWZLLjVhw9x88IWtPTr93YGHYWgR7T9S0M58ABrXPO5eoRxjDdkPCdzyDSmeVixzXZcrhCBHsUMJqipEr8NQA6Iz8QYRYBvQxtkv8j7NZcu+tFfWZ0EPswbsYp/ie+LFjFxTKsov27aduM466Q9ECOYRhCJvB0IbTyY/KYc/VT8TvZIyBA3JP1w2KYoUnKgc5sAGt7ifVXjH3jc8rrC4rWeUIGVFQIDAQAB";
//签名方式
config.signType="RSA2";
//商户私钥(应用私钥),您的PKCS8格式RSA2私钥
config.merchantPrivateKey="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvYd7rfO6O7P4ZdD7X/eqqr5J9fB08rGl7juyyn7c2/RAdjtg4Em4te6Jh4dLkHcQLIf5c4AQCfhqjlHX8fQbHt0MaQNIoeKtCOwJUd43XgaD+8CI+DFdFChA8ILL5KJYCZ6JonIbssayhjcIyLqnKi4D10cKJwekAV44YHHK51YGvn/OIMtOEzv+GglXDJeMjMEGBSWIjffZI2PTx8IP4eRTLSYbf7I6fo0y4vlxQrEqTpiSPGpBPjx/ws5A125UaEzkU6eNfnpC5AsHj7mV8JxXkObc9P0sxmC5jGr+zlG7UhY1ECgHnCioP8W0nwH2mmFuC9Tk7axkOtFGnROpRAgMBAAECggEAUBLdVqMpwDPQKAr9DlyuIdQbjBN4vdTyLCmrRDrLyd1s2DH54k/34ehK0WnrgZ9dfL++hOT6r7CntPv5ipgC2nh/uKLT0QqXFpweijYzmqtiuEMnPzEfPzRDCVDcpgmzw9FRQ3YD3FmaugAhJAxOFV3wOUvWCFNycGeJRtTmRJXHLSssMp4aCgM0ClwNsoxJFhTQGk/PHDWOoFH5apAzPLuesc6zU/zn7ooEpAyCjUfUUKVCjK0GQuNqQXJhDoEu48NcvGvkjNTWER//u2tZ77rzipLyF+UP6I7Zls/WsD/BNsq3JMGCjflpfuiwDK30HZ7VKAwNBg3CbOIhuEWV4QKBgQDUkDRzBPcnoaBRWRCJMjphkQLqDbuaTW2V6HWGST7fuBrEidtqeCr4KvoBx4sKowxPAOsBkkDzpTCDc3dlNOKgT5ScK6OoAAB3qvy1X8i46/KR5VDdQrhs4fxMFPybZS6mI9BUcZ/URGHQkmtBPWCive/8qK9LI5g1veh/bUamlQKBgQDTOJ8mHb6ILOu5VnWLwtDz55Rq6gyha+aRF9Cai2LCyXBEm5gOy8k4UJvILZwwLSavaEgoFl3OA8uVG17zXizGI0yggaTQZ81Mw9ig6LwAR2gcqmBVPX1xHF8jXVoAPDRjfX6sEfFhIJQyeWGzEJnJZAD/6ZPLM9hcAx+2R9MxzQKBgEoFZZ5gLklIyXFKmK2OJjJvsxoaaigTqoO3jaWTwCdcD0Y904DCFASTwrf36v1rRhAE+9FyQtgVwE0mWn+N6RV2YQP5VmZcic0iaBopHtb2o2QW/Q/v+hVApQFBla3vkE0ez594afYbUgy10E/Jtes2RWowu8povMqKNXqabS35AoGBAIYtUexEuOSIpLX31nQSLerDEeVZCO0CPlWtazbBlNtoW4k5zj6X9htwGYXwc2enRwvmku/kRXK5tnniCU9QY+D6S5MqyCgbyK8bOmH9dnA27ExJbyi3BxjzjPxKMQI1PJJ3BiEIxO2OZJYrxYSa5xaoEHqBRwGuzaKl2V9SATeBAoGAUKAXdBXBXSeoRnsZqi/N7sV1gSjpxkJV9nijqKYANE3RR8NnlWYh/mT+PiWR+UQhV3eUvBBGUmXg+uIL7xanhPVluWjWzGBwTKvpK06hMb/gN2RUR25FNizZDHzav1T86dbIFFoUTIsVbLtRDn4rZOIg/YHDbgmfVihgimbVtQE=";
return config;
}
}
web层
// 数据库修改订单状态
@RequestMapping("pay.do")
public String pay(int orderId, HttpServletResponse response) throws IOException {
orderService.pay(orderId);
return "mall/order/list";
}
// 接入支付宝完成支付功能
@RequestMapping("prePay.do")
@ResponseBody
public String prePay(int orderId, HttpServletRequest request, HttpServletResponse response) throws IOException {
Order order = orderService.findOne(orderId);
AlipayConfig ac = new AlipayConfig();
String goAlipay = ac.goAlipay(order);
// 获取当前登录用户
User user = (User) request.getSession().getAttribute("user");
User u = userService.findById(user.getId());
user.setMoney(u.getMoney() - order.getTotal());
// 修改余额
UserMapper userMapper = new UserMapper();
try {
userMapper.updateMoney(user);
} catch (Exception e) {
e.printStackTrace();
}
return goAlipay;
}
// 校验用户是否能够支付(如果是挂失状态、余额不足不可支付)
@PostMapping("checkUserPay.do")
@ResponseBody
public ResultBean checkUserPay(int orderId, HttpServletRequest request, HttpServletResponse response)
throws IOException {
// 检查挂失状态
UserMapper um = new UserMapper();
ResultBean rs = new ResultBean<>();
// 1.挂失状态 2.余额不足
try {
Map userInfo = um.queryUserByOrderId(orderId);
String state = userInfo.get("state").toString();
// 余额
double money = Double.parseDouble(userInfo.get("money").toString());
// 支付金额
double total = Double.parseDouble(userInfo.get("total").toString());
if (!"正常".equals(state)) {
rs.setState(1);
}else if (money < total) {
rs.setState(2);
}
} catch (Exception e) {
e.printStackTrace();
}
return rs;
}
前端order/list.html变更如下
支付会引发页面跳转,所以要将ajax请求换成页面跳转的方式
//付款
function pay(id) {
$.ajax({
type: "POST",
url: "checkUserPay.do",
data: "orderId=" + id,// 你的formid
async: false,
error: function (request) {
alert("Connection error");
},
success: function (result) {
debugger;
if (result.state == 1) {
alert("用户处于挂失状态,不可以进行消费!");
return;
} else if (result.state == 2) {
alert("用户余额不足,不可以进行消费!");
return;
}
location.href = "prePay.do?orderId=" + id;
}
});
// $.get("prePay.do?orderId=" + id, function (data) {
// if (data.state == 0) {
// layer.msg("付款成功!");
// window.setTimeout(function () {
// window.location.reload();
// },500);
// } else {
// layer.msg(data.message);
// }
// });
}
OrderController.java代码变更如下
@RequestMapping("/addOrder")
@ResponseBody
public String addOrder(User user,
HttpServletRequest req,
OrderDto orderDto){
//获取购物车
ShopCar shopCar = this.getShopCar(user.getId(), req);
//获取结算商品集合
List shopCarItems = this.getShopCarItems(shopCar, orderDto.getGids());
//生成订单及订单项
orderDto.setUserId(Long.parseLong(user.getId()));
orderService.addOrder(orderDto,shopCarItems);
//从购物车中删除已结算的商品
shopCar.delete(orderDto.getGids());
//跳转支付页面(下节课内容)
AlipayConfig alipayConfig = new AlipayConfig();
return alipayConfig.goAlipay(orderDto);
}