基础搭建
Springboot集成支付宝沙箱支付Easy版
Easy版SDK文档 示例DEMO
正式版本的SDK
-
通用版SDK文档 通用版SDK文档 -
maven依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.110.ALL</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
- AlipayConfig.java配置类中,只需要获取配置alipay的参数即可
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
private String appId;
private String merchantPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
}
4.支付宝参数实体类AliPay.java中,配置属性
package com.qingge.springboot.entity;
import lombok.Data;
@Data
public class AliPay {
private String subject;
private String tradeNo;
private String totalAmount;
private String aliPayTradeNo;
}
4.配置接口 ,在AliPayController.java中配置以下接口
- 支付接口 ‘/alipay/pay’ ,
- 支付成功回调 ‘/alipay/notify’
- 退款接口 ‘/alipay/returnPay’
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.qingge.springboot.config.AliPayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.qingge.springboot.common.Result;
import com.qingge.springboot.entity.AliPay;
import com.qingge.springboot.entity.Orders;
import com.qingge.springboot.service.IOrdersService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/alipay")
public class AliPayController {
private Logger logger = LoggerFactory.getLogger(AliPayController.class);
private static final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
private static final String SIGN_TYPE = "RSA2";
private static final String CHARSET = "UTF-8";
private static final String FORMAT = "JSON";
@Resource
private AliPayConfig aliPayConfig;
@Resource
private IOrdersService ordersService;
@GetMapping("/pay")
public void pay(AliPay aliPay, HttpServletResponse response) throws Exception {
AlipayClient alipayClient = new DefaultAlipayClient(
GATEWAY_URL, aliPayConfig.getAppId(),aliPayConfig.getMerchantPrivateKey(),
FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl(aliPayConfig.getNotifyUrl());
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no",aliPay.getTradeNo());
bizContent.put("total_amount",aliPay.getTotalAmount());
bizContent.put("subject",aliPay.getSubject());
bizContent.put("product_code","FAST_INSTANT_TRADE_PAY");
request.setBizContent(bizContent.toJSONString());
String form;
try {
form = alipayClient.pageExecute(request).getBody();
} catch (AlipayApiException e) {
System.err.println("调用遭遇异常,原因:" + e.getMessage());
throw new RuntimeException(e.getMessage(), e);
}
response.setContentType("text/html;charset=" + CHARSET);
PrintWriter out = response.getWriter();
out.write(form);
out.flush();
out.close();
}
@PostMapping("/notify")
public Result payNotify(HttpServletRequest request) throws Exception {
if("TRADE_SUCCESS".equals(request.getParameter("trade_status"))){
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));
}
String orderNo = params.get("out_trade_no");
String payTime = params.get("gmt_payment");
String alipayNo = params.get("trade_no");
String sign = params.get("sign");
String content = AlipaySignature.getSignCheckContentV1(params);
Boolean checkSignature = AlipaySignature.rsa256CheckContent(content,sign,aliPayConfig.getAlipayPublicKey(),CHARSET);
if(checkSignature){
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"));
Orders orders = ordersService.getOrderByNo(orderNo);
orders.setState(1);
orders.setPayTime(payTime);
orders.setAlipayNo(alipayNo);
System.out.println("更新后的订单信息" + orders);
ordersService.updateById(orders);
}
}
return Result.success();
}
@PostMapping("/returnPay")
public Result returnPay(AliPay aliPay) throws AlipayApiException{
Orders ord = ordersService.getOrderByNo(aliPay.getTradeNo());
if(ord != null){
long between = DateUtil.between(
DateUtil.parseDateTime(ord.getPayTime()),
DateUtil.parseDateTime(DateUtil.now()),
DateUnit.DAY);
if(between > 7){
return Result.error("-1","该订单已超过7天,不支持退款!");
}
}
System.out.println("aliPay参数==>" + aliPay);
AlipayClient alipayClient = new DefaultAlipayClient(
GATEWAY_URL, aliPayConfig.getAppId(),aliPayConfig.getMerchantPrivateKey(),
FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
JSONObject bizContent = new JSONObject();
bizContent.put("trade_no",aliPay.getAliPayTradeNo());
bizContent.put("refund_amount", aliPay.getTotalAmount());
bizContent.put("out_request_no",aliPay.getTradeNo());
request.setBizContent(bizContent.toJSONString());
AlipayTradeRefundResponse response = alipayClient.execute(request);
if(response.isSuccess()){
logger.info("退款成功!");
Orders orders = ordersService.getOrderByNo(aliPay.getTradeNo());
orders.setState(2);
orders.setPaybackTime(DateUtil.now());
ordersService.updateById(orders);
return Result.success();
}else {
logger.info(response.getBody());
return Result.error(response.getCode(),response.getBody());
}
}
}
注意
在订单表中,新增一个字段 payback_time 退款时间。 在退款接口中。退款成功后更新订单状态
模拟7天无理由退款
在退款接口中,添加业务逻辑,判断请求退款时间 与 订单支付时间 是否间隔7天以上
Orders ord = ordersService.getOrderByNo(aliPay.getTradeNo());
if(ord != null){
long between = DateUtil.between(
DateUtil.parseDateTime(ord.getPayTime()),
DateUtil.parseDateTime(DateUtil.now()),
DateUnit.DAY);
if(between > 7){
return Result.error("-1","该订单已超过7天,不支持退款!");
}
}
前端发送请求,调用接口:
- 订单支付
pay (order) {
let url = `http://localhost:9090/alipay/pay?subject=${order.name}&tradeNo=${order.orderNo}&totalAmount=${order.total}`
console.log('-------',url)
window.open(url)
},
- 订单退款
payBack(order){
console.log('正在发送退款请求')
let payback_url = `http://localhost:9090/alipay/returnPay?tradeNo=${order.orderNo}&totalAmount=${order.total}&aliPayTradeNo=${order.alipayNo}`
this.request.post(payback_url).then( res => {
if (res.code === '200') {
this.$message.success("退款成功")
this.load()
}else{
console.log('退款失败',res)
this.$message.error(res.msg)
}
})
},
|