Spring Boot版本:2.3.4.RELEASE
在# Spring Boot整合支付宝沙箱支付中实现了支付宝沙箱支付的付款流程,这里完善一下,将交易查询和退款都做了。
其实调通沙箱支付不难,只是调用支付宝的接口。现在在原来demo的基础上,就不事无巨细的贴完整代码了,只展示关键的调用模块,具体可以看源码:
交易查询
优化一下代码,将AlipayClient对象的创建封装出来:
private AlipayClient getAlipayClient() {
// 支付宝网关
String serverUrl = alipayProperties.getGatewayUrl();
// APPID
String appId = alipayProperties.getAppId();
// 私钥
String privateKey = alipayProperties.getPrivateKey();
// 格式化为 json 格式
String format = "json";
// 字符编码格式
String charset = alipayProperties.getCharset();
// 公钥,对应APPID的那个
String alipayPublicKey = alipayProperties.getPublicKey();
// 签名方式
String signType = alipayProperties.getSignType();
return new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);
}
/**
* 交易查询
* 传入任意参数即可:商户订单系统的唯一订单号 或 支付宝交易号
*/
public AlipayTradeQueryResponse query(AlipayQueryVo vo) throws AlipayApiException {
// 获得初始化的AlipayClient
AlipayClient client = getAlipayClient();
// 设置请求参数
AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
// 商户订单号,商户网站订单系统中唯一订单号
// 支付宝交易号
// 请二选一设置
String orderNo = vo.getOrderNo();
String tradeNo = vo.getTradeNo();
JSONObject bizContent = new JSONObject();
if (!StringUtils.isEmpty(orderNo)) {
bizContent.put("out_trade_no", orderNo);
} else if (!StringUtils.isEmpty(tradeNo)) {
bizContent.put("trade_no", tradeNo);
} else {
throw new RuntimeException("订单号和交易号不能都为空");
}
alipayRequest.setBizContent(bizContent.toString());
// 请求
AlipayTradeQueryResponse response = client.execute(alipayRequest);
return response;
}
退款
/**
* 退款
*/
public AlipayTradeRefundResponse refund(AlipayRefundVo vo) throws AlipayApiException {
// 获得初始化的AlipayClient
AlipayClient client = getAlipayClient();
// 设置请求参数
AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
//商户订单号,商户网站订单系统中唯一订单号
String out_trade_no = vo.getOrderNo();
// 支付宝交易号
String trade_no = vo.getTradeNo();
// 请二选一设置
// 需要退款的金额,该金额不能大于订单金额,必填
String refund_amount = vo.getRefundAmount();
// 退款的原因说明
String refund_reason = vo.getRefundReason();
// 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
String out_request_no = vo.getOutRequestNo();
JSONObject bizContent = new JSONObject();
if (!StringUtils.isEmpty(out_trade_no)) {
bizContent.put("out_trade_no", out_trade_no);
} else if (!StringUtils.isEmpty(trade_no)) {
bizContent.put("trade_no", trade_no);
} else {
throw new RuntimeException("订单号和交易号不能都为空");
}
bizContent.put("refund_amount", refund_amount);
if (!StringUtils.isEmpty(refund_reason)) {
bizContent.put("refund_reason", refund_reason);
}
if (!StringUtils.isEmpty(out_request_no)) {
bizContent.put("out_request_no", out_request_no);
}
alipayRequest.setBizContent(bizContent.toString());
// 请求
AlipayTradeRefundResponse response = client.execute(alipayRequest);
return response;
}
交易查询和退款接口
// 交易查询
@PostMapping("/query")
public AlipayTradeQueryResponse query(@RequestBody AlipayQueryVo vo) throws AlipayApiException {
return alipayService.query(vo);
}
// 退款
@PostMapping("/refund")
public AlipayTradeRefundResponse refund(@RequestBody AlipayRefundVo vo) throws AlipayApiException {
return alipayService.refund(vo);
}
查询页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
</head>
<body>
<h3>交易查询页面</h3>
<label>订单号:</label><input id="orderNo" name="orderNo" type="text" value="123"><br>
<label>交易号:</label><input id="tradeNo" name="tradeNo" type="text" value="订单1号"><br>
<button onclick="query()">查询</button>
<script>
function query() {
var orderNo = $("#orderNo").val();
var tradeNo = $("#tradeNo").val();
var params = {
"orderNo": orderNo,
"tradeNo": tradeNo
}
console.log(JSON.stringify(params))
$.ajax({
url: 'http://localhost:8888/query',
type: 'post',
headers: { "Content-Type": "application/json" },
data: JSON.stringify(params),
success: function (result) {
console.log(result)
},
error: function (e) {
console.log("ajax请求出现错误: ");
console.log(e);
},
});
}
</script>
</body>
</html>
退款界面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
</head>
<body>
<h3>退款页面</h3>
<label>订单号:</label><input id="orderNo" name="orderNo" type="text" value="123"><br>
<label>交易号:</label><input id="tradeNo" name="tradeNo" type="text" value="订单1号"><br>
<label>退款金额:</label><input id="refundAmount" name="refundAmount" type="text" value="1"><br>
<label>退款理由:</label><input id="refundReason" name="refundReason" type="text" value="这里是退款理由"><br>
<label>退款请求标识:</label><input id="outRequestNo" name="outRequestNo" type="text" value="退款请求标识"><br>
<button onclick="refund()">退款</button>
<script>
function refund() {
var orderNo = $("#orderNo").val();
var tradeNo = $("#tradeNo").val();
var refundAmount = $("#refundAmount").val();
var refundReason = $("#refundReason").val();
var outRequestNo = $("#outRequestNo").val();
var params = {
"orderNo": orderNo,
"tradeNo": tradeNo,
"refundAmount": refundAmount,
"refundReason": refundReason,
"outRequestNo": outRequestNo,
}
console.log(JSON.stringify(params))
$.ajax({
url: 'http://localhost:8888/refund',
type: 'post',
headers: { "Content-Type": "application/json" },
data: JSON.stringify(params),
success: function (result) {
console.log(result)
},
error: function (e) {
console.log("ajax请求出现错误: ");
console.log(e);
},
});
}
</script>
</body>
</html>