简单几步实现商城订单支付!!!!
首先,在我们的pom.xml里面引入依赖
<!-- 沙箱支付-->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
<version>2.2.0</version>
</dependency>
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.20</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
依次导入我们需要的编码,编码用到Lombok简化了代码
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
下面是我们的文件位置
1.新建一个AlipayConfig.java
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
private String appId;
private String appPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
@PostConstruct
public void init() {
// 设置参数(全局只需设置一次)
Config config = new Config();
config.protocol = "https";
config.gatewayHost = "openapi.alipaydev.com";
config.signType = "RSA2";
config.appId = this.appId;
config.merchantPrivateKey = this.appPrivateKey;
config.alipayPublicKey = this.alipayPublicKey;
config.notifyUrl = this.notifyUrl;
Factory.setOptions(config);
System.out.println("=======支付宝SDK初始化成功=======");
}
}
2.放入我们的alipay实体类
import lombok.Data;
@Data
public class AliPay {
private String traceNo;
private String totalAmount;
private String subject;
// private String alipayTraceNo;
}
3.然后是我们的控制层Controller
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.example.demo.controller.dto.AliPay;
import com.example.demo.mapper.OrdersMapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/alipay")
public class AliPayController {
@Resource
private OrdersMapper ordersMapper;
@GetMapping("/pay") // &subject=xxx&traceNo=xxx&totalAmount=xxx
public String pay(AliPay aliPay) {
AlipayTradePagePayResponse response;
try {
// 发起API调用(以创建当面付收款二维码为例)
response = Factory.Payment.Page()
.pay(aliPay.getSubject(), aliPay.getTraceNo(), aliPay.getTotalAmount(), "");
} catch (Exception e) {
System.err.println("调用遭遇异常,原因:" + e.getMessage());
throw new RuntimeException(e.getMessage(), e);
}
return response.getBody();
}
@PostMapping("/notify") // 注意这里必须是POST接口
public String payNotify(HttpServletRequest request) throws Exception {
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
System.out.println("=========支付宝异步回调========");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
// System.out.println(name + " = " + request.getParameter(name));
}
String tradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
// 支付宝验签
if (Factory.Payment.Common().verifyNotify(params)) {
// 验签通过
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
// 更新订单未已支付
ordersMapper.updateState(tradeNo, "已支付", gmtPayment, alipayTradeNo);
}
}
return "success";
}
}
然后是我们的数据库
订单表:
CREATE TABLE `orders` (
`id` int NOT NULL AUTO_INCREMENT,
`user_id` int DEFAULT NULL COMMENT '用户ID',
`alipay_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_turkish_ci DEFAULT NULL COMMENT '支付宝流水号',
`name` varchar(255) COLLATE utf8mb4_turkish_ci DEFAULT NULL COMMENT '名称',
`no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_turkish_ci DEFAULT NULL COMMENT '编号',
`total_price` decimal(10,2) DEFAULT NULL COMMENT '总金额',
`state` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_turkish_ci DEFAULT '待付款' COMMENT '状态',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '订单创建时间',
`pay_time` varchar(255) COLLATE utf8mb4_turkish_ci DEFAULT NULL COMMENT '订单付款时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_turkish_ci;
做完这些我们就开始进行支付,在支付之前我们要先到支付宝平台申请一下开放
进入到界面,我们登录然后进行获取
以上内容按照步骤进行就可以,然后是我们的配置application.yml
alipay:
appId: 你的AppId
appPrivateKey: 应用私钥
alipayPublicKey: 应用公钥
notifyUrl: natapp获取
然后我们还需要一个工具natapp,内网穿透:https://natapp.cn/
申请一个免费的隧道然后进行配置
本地端口号就是你的后台的端口号,我这里是9090
然后下好工具之后,复制我们的authtoken
在外面的bat里面换成我们自己的这个authtoken
当你看见下面的内容时就说明连接成功了
然后将我们的这个http放入刚刚的配置里面
记住,一定要加上/alipay/notify !!!!!!!!!!!!!!!!!
然后我们就配置成功了,就可以进行支付
前台页面
<template>
<div style="width: 1300px; padding-left: 200px">
<div style="margin: 10px 0">
<el-button type="primary" @click="$router.push('/home')" style="float: left; margin-right: 20px">首页</el-button>
</div>
<el-table style="top: 10px" :data="tableData" border stripe :header-cell-class-name="headerBg" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="name" label="商品名称" ></el-table-column>
<el-table-column prop="no" label="订单编号" ></el-table-column>
<el-table-column prop="totalPrice" label="总金额" ></el-table-column>
<el-table-column prop="phone" label="联系方式" ></el-table-column>
<el-table-column prop="username" label="收件人" ></el-table-column>
<el-table-column prop="address" label="收货地址"></el-table-column>
<el-table-column prop="state" label="订单状态"></el-table-column>
<el-table-column label="我的快递">
<template v-slot="scope">
<el-button type="success" slot="reference" @click="changeState(scope.row, '收货')" :disabled="scope.row.state !== '发货'">收货</el-button>
</template>
</el-table-column>
<el-table-column label="查看商品">
<template slot-scope="scope">
<el-button type="primary" slot="reference" style="margin-left: 5px" @click="viewGoods(scope.row.id)">查看商品</el-button>
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<template slot-scope="scope">
<el-popconfirm
class="ml-5"
confirm-button-text='确认'
cancel-button-text='取消'
icon="el-icon-info"
icon-color="red"
title="您确定取消该笔订单吗?"
@confirm="del(scope.row.id)">
<el-button type="danger" slot="reference" style="margin-left: 5px">取消</el-button>
<el-button type="primary" slot="reference" style="margin-left: 5px" @click="pay(scope.row)">支付</el-button>
<!-- <el-button type="success" slot="reference" @click="changeState(scope.row, '确认收货')" :disabled="scope.row.state !== '发货'">确认收货</el-button>-->
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<div style="padding: 10px 0">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[ 5, 10]"
:page-size="pageSize"
layout="total, prev, pager, next"
:total="total">
</el-pagination>
</div>
<el-dialog title="商品信息" :visible.sync="dialogFormVisible1" width="50%" :close-on-click-model="false">
<el-table :data="goodsList" border stripe >
<el-table-column prop="name" label="商品名称" width="80"></el-table-column>
<el-table-column prop="url" label="商品图片">
<template slot-scope="scope">
<el-image :src="scope.row.url" :preview-src-list="[scope.row.id]"></el-image>
</template>
</el-table-column>
<el-table-column prop="price" label="单价" width="80"></el-table-column>
<el-table-column prop="num" label="库存" width="80" ></el-table-column>
<el-table-column prop="type" label="类型" width="80"></el-table-column>
<el-table-column prop="number" label="购买数量" width="80"></el-table-column>
<el-table-column prop="refer" label="描述" width="500"></el-table-column>
<el-table-column prop="creatTime" label="上架时间" width="120"></el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script>
const baseUrl = "http://localhost:9090"
export default {
name: "Orders",
data() {
return {
tableData: [],
goodsList: [],
total: 0,
pageNum: 1,
pageSize: 5,
username: "",
form: {},
dialogFormVisible: false,
dialogFormVisible1: false,
multipleSelection: [],
headerBg: "headerBg",
roles: [],
user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {}
}
},
created() {
this.load()
},
methods: {
viewGoods(orderId) {
this.request.get("orders/getGoodsById/" + orderId).then(res => {
this.goodsList = res.data
this.dialogFormVisible1 = true
setTimeout(() => {
this.dialogFormVisible1 = false
}, 5000)
})
},
load: function () {
this.request.get("/orders/page", {
params: {
pageNum: this.pageNum,
pageSize: this.pageSize,
name: this.name,
}
}).then(res => {
this.tableData = res.data.records
this.total = res.data.total
})
this.request.get("/role").then(res => {
this.roles = res.data
})
},
changeState(row, state) {
this.form = JSON.parse(JSON.stringify(row))
this.form.state = state;
this.save();
},
del(id) {
this.request.delete("/orders/" + id).then(res => {
if (res.code === '200') {
this.$message.success("取消订单成功")
this.load()
} else {
this.$message.error("取消订单失败")
}
})
},
save() {
this.request.post("/orders", this.form).then(res => {
if (res.code === '200') {
this.$message.success("保存成功")
this.dialogFormVisible = false
this.load()
} else {
this.$message.error("保存失败")
}
})
},
pay(row) {
// window.open('http://localhost:9090/alipay/pay?subject=${row.name}&traceNo=${row.no}&totalAmount=${row.totalPrice}');
window.open("http://localhost:9090/alipay/pay?subject=" + row.name + "&traceNo=" + row.no + "&totalAmount=" + row.totalPrice)
this.load()
},
handleSelectionChange(val) {
console.log(val)
this.multipleSelection = val;
},
reset() {
this.name = ""
this.load()
},
handleSizeChange(pageSize) {
console.log(pageSize)
this.pageSize = pageSize
this.load()
},
handleCurrentChange(pageNum) {
console.log(pageNum)
this.pageNum = pageNum
this.load()
},
}
}
</script>
<style>
.headerBg {
background: #eee!important;
}
</style>
核心代码:进行调用我们的支付宝沙箱支付接口
pay(row) {
// window.open('http://localhost:9090/alipay/pay?subject=${row.name}&traceNo=${row.no}&totalAmount=${row.totalPrice}');
window.open("http://localhost:9090/alipay/pay?subject=" + row.name + "&traceNo=" + row.no + "&totalAmount=" + row.totalPrice)
this.load()
},
然后我们访问URL进行测试,测试的url格式:http://localhost:9090/alipay/pay?subject=商品名称&traceNo=一个订单号&totalAmount=1000
(totalAmount为订单支付价格)
如何我们的账号在我们的页面有提供
输入账号和密码就可以进行付款了
然后我们就可以看见有一个接口回调:
代码回调在我们的Controller里面有:
@PostMapping("/notify") // 注意这里必须是POST接口
public String payNotify(HttpServletRequest request) throws Exception {
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
System.out.println("=========支付宝异步回调========");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
// System.out.println(name + " = " + request.getParameter(name));
}
String tradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
// 支付宝验签
if (Factory.Payment.Common().verifyNotify(params)) {
// 验签通过
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
// 更新订单未已支付
ordersMapper.updateState(tradeNo, "已支付", gmtPayment, alipayTradeNo);
}
}
return "success";
}
最后在我们的数据库就可以看见信息了
然后我们的前台页面也可以看见信息
用户:
然后用户就可以进行操作啦!!!
管理员:
就可以进行订单操作,用户也可以看见信息啦!!!!