yml的相关配置(这三个路径,一定是要用绝对路径,因为我用的公钥证书方式,)com.alipay.sdk alipay-sdk-java4.16.50.ALL
支付宝的签名方式有两种(普通公钥方式、公钥证书方式),一般最常用的就是普通公钥方式,也相对比较简单,我做的时候用的是公钥证书方式;这个证书方式是现在支付宝支付官方文档上面推荐的签名方式.
申请步骤可以参照官方文档:
参考链接:https://docs.open.alipay.com/291/105971/
public R aliPrePay( BigDecimal totalAmount,String orderNo,String notifyUrl){
CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
certAlipayRequest.setServerUrl(getwayUrl);//设置网关地址
certAlipayRequest.setAppId(appId);//设置应用Id
certAlipayRequest.setPrivateKey(merchantPrivateKey); //设置应用私钥
certAlipayRequest.setFormat("json"); //设置请求格式,固定值json
certAlipayRequest.setCharset(charset);//设置字符集
certAlipayRequest.setSignType(signType); //设置签名类型
certAlipayRequest.setCertPath(certPath);//设置应用公钥证书路径 ,一定是本地的绝对路径
certAlipayRequest.setAlipayPublicCertPath(alipayPublicCertPath); //设置支付宝公钥证书路径,一定是本地的绝对路径
certAlipayRequest.setRootCertPath(rootCertPath);//设置支付宝根证书路径,一定是本地的绝对路径
//获得初始化的alipayClient,构造client
AlipayClient alipayClient = null;
String result = "";
try {
//公钥证书,一定要使用这个构造方法
alipayClient = new DefaultAlipayClient(certAlipayRequest);
//实例化具体API对应的request类,
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//按照需要传入参数,以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setSubject(bodyMall);//订单标题
model.setOutTradeNo(orderNo);//商户订单号,商家自定义
model.setTotalAmount(totalAmount+"");//金额,string类型
request.setBizModel(model);
request.setNotifyUrl(notifyUrl);//异步回调地址
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
result = response.getBody();
return R.success(result);
} catch (AlipayApiException e) {
e.printStackTrace();
return R.fail("预下单失败!");
}
}
@Override
public R aliPayMallOrder(Integer memberId, BigDecimal totalAmount,Integer orderId) {
String orderNo = OrderNoUtil.getOrderId();
R pay = aliPrePay(totalAmount, orderNo,notifyUrlMallOrder);
if(!pay.getIsSuccess()){ //失败直接返回上一级返回的内容
return pay;
}
//生成支付宝的预下单对象
ALPrePay prePay = new ALPrePay();
prePay.setMemberId(memberId);//用户id
prePay.setOrderNo(orderNo);//订单编号
prePay.setOrderId(orderId);//订单id
prePay.setOrderType(MallEmums.PRE_PAY_TYPE_MALL.getCode());//订单支付类别
prePay.setTotalAmount(totalAmount.multiply(new BigDecimal(100)).intValue());//金额已分展示
baseMapper.insert(prePay);
return pay;
}
拉起支付宝的回调以后,就要用写回调方法
public R verification(HttpServletRequest request){
//回调的待验签字符串
String resultInfo = convertRequestParamsToString(request).toString();
//对待签名字符串数据通过&进行拆分
String [] temp = resultInfo.split("&");
linkedHashMap map = new linkedHashMap();
//把拆分数据放在map集合内
for (int i = 0; i < temp.length; i++) {
String[] arr = temp[i].split("=", 2); //通过"="号分割成2个数据
String[] tempAagin = new String[arr.length]; //再开辟一个数组用来接收分割后的数据
for (int j = 0; j < arr.length; j++) {
tempAagin[j] = arr[j];
}
map.put(tempAagin[0], tempAagin[1]);
}
System.out.println(map);
//验签方法
boolean signVerified= false;
try {
signVerified = AlipaySignature.rsaCertCheckV1(map, alipayPublicCertPath, charset,signType);
if(signVerified){
System.out.println("支付宝回调签名认证成功");
String outTradeNo = map.get("out_trade_no");//商户自定义的订单编号
String tradeNo = map.get("trade_no");//支付宝交易凭证号
String buyerLogonId = map.get("buyer_logon_id");//支付宝交易凭证号
System.out.println("买家支付宝账号:"+buyerLogonId);
ALPrePay prePay = prePayService.getALPrePayByOutTradeNo(outTradeNo);
prePay.setTradeNo(tradeNo);
prePayMapper.updateById(prePay);
return R.success(outTradeNo).setMsg("支付成功");
}else{
System.out.println("支付宝回调签名认证失败");
return R.fail("支付失败");
}
} catch (AlipayApiException e) {
e.printStackTrace();
return R.fail("支付失败");
}
}
// 将request中的参数转换成Map
private StringBuffer convertRequestParamsToString(HttpServletRequest request) {
StringBuffer info = new StringBuffer();
Set> entrySet = request.getParameterMap().entrySet();
for (Map.Entry entry : entrySet) {
String name = entry.getKey();
String[] values = entry.getValue();
int valLen = values.length;
if (valLen == 1) {
info.append(name).append("=").append(values[0]).append("&");
} else if (valLen > 1) {
StringBuilder sb = new StringBuilder();
for (String val : values) {
sb.append(",").append(val);
}
info.append(name).append("=").append(sb.toString().substring(1)).append("&");
} else {
info.append(name).append("=").append("").append("&");
}
}
return info;
}
@Override
public R aliPayMallOrderCallBack(HttpServletRequest request) {
R verification = verification(request);
Boolean isSuccess = verification.getIsSuccess();
if(isSuccess){
//验证签名正确,开始处理订单的业务逻辑
//1.取出outTradeNo
String outTradeNo= verification.getData().toString();
//2.根据outTradeNo从预下单中取出orderId
ALPrePay prePay = prePayService.getALPrePayByOutTradeNo(outTradeNo);
//订单id
Integer orderId = prePay.getOrderId();
//订单no
String orderNo = prePay.getOrderNo();
//因为回调会依次调用很多次,所有每一次更改订单状态要判断他是否支付过,如果支付过了,就不可以在支付了
Boolean b = orderFeignService.hasPayByOrderId(orderId).getData();
if (!b) { //false,已支付
return R.success().setMsg("支付成功");
}
//支付成功,调用更改订单的状态等数据
AyjMallOrder order = orderFeignService.getOrder(orderId).getData();
if (order.getOrderStatus() == MallEmums.ORDER_STATUS_NOT.getCode()) { //订单未支付
orderFeignService.updatePaymentOrder(orderId, orderNo, MallEmums.ORDER_PAY_TYPE_ALIPAY.getCode()).getData();
} else { //优惠买单未支付
orderFeignService.updatePaymentDiscounts(orderId, orderNo, MallEmums.ORDER_PAY_TYPE_ALIPAY.getCode());
}
return R.success().setMsg("支付成功");
}else{
return verification;
}
}



