废话不多说,直接上代码。
pom
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.10.140.ALL</version>
</dependency>
AliPayConfig:支付宝支付配置项
public class AliPayConfig {
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数
public static String notify_url = "localhost:8080/aliPay/notify";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数
public static String return_url = "localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";
// 签名方式
public static String sign_type = "RSA2";
// 字符编码格式
public static String charset = "utf-8";
// 数据格式
public static String format = "json";
// 支付宝网关
public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";
// 日志路径
public static String log_path = "C:\\";
// 超时时间
public static String timeout_express = "10m";
}
公钥、密钥生成链接:https://opendocs.alipay.com/open/291/105971#LDsXr
应用ID的位置
商户私钥
支付宝公钥
AliPayDTO:支付实体对象
@Data
@Accessors(chain = true)
public class AliPayDTO {
/*商户订单号,必填*/
private String out_trade_no;
/*订单名称,必填*/
private String subject;
/*付款金额,必填*/
private String total_amount;
/*商品描述,可空*/
private String body;
/*超时时间参数*/
private String timeout_express="10m";
private Long userId;
}
AliWithdrawDTO:提现实体对象
@Data
@Accessors(chain = true)
public class AliWithdrawDTO {
/**
* 商户转账唯一订单号(必填)
*/
private String out_biz_no;
/**
* 收款方账户类型(必填,ALIPAY_LOGONID:支付宝登录号,支持邮箱和手机号格式。)
*/
private String payee_type;
/**
* 收款方账户(必填)
*/
private String payee_account;
/**
* 收款方真实姓名(如果本参数不为空,则会校验该账户在支付宝登记的实名是否与收款方真实姓名一致。咱们必填,不然转错了麻烦)
*/
private String payee_real_name;
/**
* 金额(必填)
*/
private String amount;
/**
* 付款方姓名
*/
private String payer_show_name;
/**
* 转账备注
*/
private String remark;
}
AliPayUtil:APP支付宝支付
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Slf4j
@Component
public class AliPayUtil {
@Autowired
private UserInfoController userInfoController;
@Autowired
private RedisService redisService;
/**
* APP支付宝下单支付(充值)
*/
public String aliPay(AliPayDTO aliPayDTO){
// 实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.gatewayUrl,
AliPayConfig.app_id, AliPayConfig.merchant_private_key, AliPayConfig.format,
AliPayConfig.charset, AliPayConfig.alipay_public_key, AliPayConfig.sign_type);
// 创建一个支付请求,设置请求参数
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
Long aLong = SnowFlakeGenerator.generateId();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setTotalAmount(aliPayDTO.getTotal_amount());
model.setSubject(aliPayDTO.getSubject());
model.setOutTradeNo(aLong.toString());
model.setBody(aliPayDTO.getBody());
model.setTimeoutExpress(aliPayDTO.getTimeout_express());
request.setBizModel(model);
request.setNotifyUrl(AliPayConfig.notify_url);
// 将用户id存入redis中,aLong:aliPayDTO.getUserId()
redisService.set(aLong.toString(), aliPayDTO.getUserId(), 60*10);
log.info("请求数据:{},回调地址:{}",request.getBizModel(),request.getNotifyUrl());
AlipayTradeAppPayResponse response = null;
try {
response = alipayClient.sdkExecute(request);
//就是orderString 可以直接给客户端请求,无需再做处理。
log.info("支付宝返回数据:{}",response.getBody());
} catch (AlipayApiException e) {
e.printStackTrace();
}
return response.getBody();
}
/**
* APP支付宝支付成功后,回调该接口
*/
@Transactional
public String notifyData(HttpServletRequest request, HttpServletResponse response){
Map<String, String> params = new HashMap<>();
// 从支付宝回调的request域中取值
Map<String, String[]> requestParams = request.getParameterMap();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
String name = iter.next();
String[] values = requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
// try {
// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
params.put(name, valueStr);
}
for (Map.Entry<String, String> entry : params.entrySet()) {
log.info("key:{}, value:{}",entry.getKey(),entry.getValue());
}
// 封装必须参数 商户订单号 订单内容 交易状态(TRADE_SUCCESS)total_amount
String outTradeNo = request.getParameter("out_trade_no");
String orderType = request.getParameter("body");
String tradeStatus = request.getParameter("trade_status");
String totalAmount = request.getParameter("total_amount");
log.info("商户订单号:{},订单内容:{},交易状态:{}",outTradeNo,orderType,tradeStatus);
// 签名验证(对支付宝返回的数据验证,确定是支付宝返回的)
try {
boolean signVerified = AlipaySignature.rsaCheckV1(params, AliPayConfig.alipay_public_key, AliPayConfig.charset, AliPayConfig.sign_type);
if (signVerified) {
//验签成功
log.info("*******验签成功******");
//TODO 付款成功后,自己的业务处理
return "success";
} else {
// 验签失败
log.info("*******验签失败******");
return "fail";
}
} catch (AlipayApiException e) {
e.printStackTrace();
return "fail";
}
}
/**
* 提现
*/
public String withdraw(AliWithdrawDTO aliWithdrawDTO){
//提现
//TODO 1、实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.gatewayUrl,
AliPayConfig.app_id, AliPayConfig.merchant_private_key, AliPayConfig.format,
AliPayConfig.charset, AliPayConfig.alipay_public_key, AliPayConfig.sign_type);
//TODO 2、实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayFundTransToaccountTransferRequest alipayRequest = new AlipayFundTransToaccountTransferRequest();
/* "\"out_biz_no\":\"3142321423432\"," +
"\"payee_type\":\"ALIPAY_LOGONID\"," +
"\"payee_account\":\"abc@sina.com\"," +
"\"amount\":\"12.23\"," +
"\"payer_show_name\":\"上海交通卡退款\"," +
"\"payee_real_name\":\"张三\"," +
"\"remark\":\"转账备注\"" +
" }"*/
//商户转账唯一订单号
aliWithdrawDTO.setOut_biz_no(System.currentTimeMillis()+"");
aliWithdrawDTO.setPayee_type("ALIPAY_LOGONID");
aliWithdrawDTO.setPayee_account(aliWithdrawDTO.getPayee_account());
aliWithdrawDTO.setAmount(aliWithdrawDTO.getAmount());
aliWithdrawDTO.setPayee_real_name(aliWithdrawDTO.getPayee_real_name());
aliWithdrawDTO.setPayer_show_name(aliWithdrawDTO.getPayer_show_name());
aliWithdrawDTO.setRemark(aliWithdrawDTO.getRemark());
String jsonData = JSONObject.toJSONString(aliWithdrawDTO);
log.info("支付宝提现请求数据:{}",jsonData);
alipayRequest.setBizContent(jsonData);
//TODO 3、转账/提现
try {
AlipayFundTransToaccountTransferResponse response = alipayClient.execute(alipayRequest);
log.info("支付宝的响应:{}",JSONObject.toJSON(response));
if(response.isSuccess()){
//提现成功
return "success";
}else {
return "fail";
}
} catch (AlipayApiException e) {
e.printStackTrace();
return "fail";
}
}
/**
* 退款
*/
public String aliPayRefund(JSONObject jsonObject){
//TODO 1、实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.gatewayUrl,
AliPayConfig.app_id, AliPayConfig.merchant_private_key, AliPayConfig.format,
AliPayConfig.charset, AliPayConfig.alipay_public_key, AliPayConfig.sign_type);
AlipayTradeRefundRequest aliPayRequest = new AlipayTradeRefundRequest();
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
//订单支付时传入的商户订单号,不能和 trade_no同时为空
model.setOutTradeNo("b87267c8-435b-449b-9ebb-e12efe06a1dd");
//支付宝交易号,和商户订单号不能同时为空
model.setTradeNo("2020122122001400320501115255");
//需要退款的金额,该金额不能大于订单金额,单位为元,支持两位小数
model.setRefundAmount("93.80");
//退款的原因说明
model.setRefundReason("正常退款");
//标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。
model.setOutRequestNo(System.currentTimeMillis()+"");
aliPayRequest.setBizModel(model);
try {
AlipayTradeRefundResponse aliPayResponse = alipayClient.execute(aliPayRequest);
log.debug("aliPayResponse:{}", aliPayResponse);
if (!"10000".equals(aliPayResponse.getCode())) {
log.info("支付宝退款失败,支付宝交易号:{},状态码:{}", "2020122122001400320501115254", aliPayResponse.getCode());
return "fail";
}
return aliPayResponse.getMsg();
} catch (AlipayApiException e) {
e.printStackTrace();
return "fail";
}
}
}
service
@Service
@Slf4j
public class AliPayServiceImpl implements AliPayService {
@Autowired
private AliPayUtil aliPayUtil;
@Override
public String placeOrder(AliPayDTO aliPayDTO) {
String body = aliPayUtil.aliPay(aliPayDTO);
return body;
}
@Override
public String notifyData(HttpServletRequest request, HttpServletResponse response) {
return aliPayUtil.notifyData(request,response);
}
@Override
public void withdraw(HttpServletResponse response) {
AliWithdrawDTO withdrawBean = new AliWithdrawDTO();
String payResult = aliPayUtil.withdraw(withdrawBean);
response.setContentType("text/html;charset=utf-8");
try {
response.getWriter().write("<html>");
response.getWriter().write("<head>");
response.getWriter().write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
response.getWriter().write("<title>提现</title>");
response.getWriter().write("</head>");
response.getWriter().write("<body>");
if("success".equals(payResult)){
response.getWriter().write(" <div style=\"color: red;font-size: 50px;margin: auto;\">恭喜提现成功</div>");
}else{
response.getWriter().write(" <div style=\"color: red;font-size: 50px;margin: auto;\">提现失败</div>");
}
response.getWriter().write("</body>");
response.getWriter().write("</html>");
response.getWriter().flush();
response.getWriter().close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void refund(HttpServletResponse response) {
JSONObject jsonObject = new JSONObject();
String payResult = aliPayUtil.aliPayRefund(jsonObject);
response.setContentType("text/html;charset=utf-8");
try {
response.getWriter().write("<html>");
response.getWriter().write("<head>");
response.getWriter().write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
response.getWriter().write("<title>退款</title>");
response.getWriter().write("</head>");
response.getWriter().write("<body>");
if(StringUtil.isNotEmpty(payResult)){
response.getWriter().write(" <div style=\"color: red;font-size: 50px;margin: auto;\">恭喜退款成功</div>");
}else{
response.getWriter().write(" <div style=\"color: red;font-size: 50px;margin: auto;\">退款失败</div>");
}
response.getWriter().write("</body>");
response.getWriter().write("</html>");
response.getWriter().flush();
response.getWriter().close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
controller
@RestController
@RequestMapping("/aliPay")
@Api(value = "AliPayController", tags = "支付宝下单支付")
public class AliPayController {
@Autowired
private AliPayService aliPayService;
@Autowired
private HttpServletRequest request;
@AccessAuth
@PostMapping(value = "/order")
@ApiOperation(value = "支付宝下单支付")
public CommonResult placeOrder(@RequestBody AliPayDTO aliPayDTO) {
UserInfoDTO userInfoDTO = (UserInfoDTO) request.getAttribute(AuthConstant.USER_SESSION_KEY);
Long id = userInfoDTO.getId();
aliPayDTO.setUserId(id);
String s = aliPayService.placeOrder(aliPayDTO);
return CommonResult.success(s);
}
@RequestMapping(value="/notify",method={RequestMethod.POST})
@ApiOperation(value = "支付宝支付成功后,回调该接口")
public String notify(HttpServletRequest request, HttpServletResponse response) {
return aliPayService.notifyData(request,response);
}
@PostMapping(value = "/withdraw")
@ApiOperation(value = "支付宝提现")
public void withdraw(@RequestBody HttpServletResponse response) {
aliPayService.withdraw(response);
}
@PostMapping(value = "/refund")
@ApiOperation(value = "支付宝退款")
public void refund(@RequestBody HttpServletResponse response) {
aliPayService.refund(response);
}
}
~有写错的或者有更优雅的写法记得@ 我~