提交租赁订单支付接口
This commit is contained in:
@ -1,13 +1,84 @@
|
||||
package com.sczx.pay.controller;
|
||||
|
||||
import com.sczx.pay.service.AlipayRentService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
@Api(value = "支付宝租赁订单回调接口", tags = "支付宝租赁订单回调接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/alipay/rent/notify")
|
||||
public class AlipayRentNotifyController {
|
||||
|
||||
@Autowired
|
||||
private AlipayRentService alipayRentService;
|
||||
|
||||
/**
|
||||
* 支付宝租赁订单支付结果通知
|
||||
*/
|
||||
@ApiOperation(value = "支付宝租赁订单支付结果通知")
|
||||
@PostMapping("/pay")
|
||||
public String alipayNotify(HttpServletRequest request) {
|
||||
try {
|
||||
// 读取支付宝回调数据
|
||||
Map<String, String> params = new HashMap<>();
|
||||
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] + ",";
|
||||
}
|
||||
params.put(name, valueStr);
|
||||
}
|
||||
|
||||
String outTradeNo = params.get("out_trade_no");
|
||||
String companyIdStr = params.get("passback_params"); // 通过回传参数获取公司ID
|
||||
Long companyId = companyIdStr != null ? Long.parseLong(companyIdStr) : null;
|
||||
|
||||
log.info("收到支付宝租赁订单支付通知,数据: {}, 商户订单号: {}", params, outTradeNo);
|
||||
|
||||
// 验证签名
|
||||
// if (!alipayService.verifyNotifySign(companyId, params)) {
|
||||
// log.warn("支付宝支付通知签名验证失败,公司ID: {}", companyId);
|
||||
// return buildResponse("failure");
|
||||
// }
|
||||
|
||||
String tradeStatus = params.get("trade_status");
|
||||
if (!"TRADE_SUCCESS".equals(tradeStatus) && !"TRADE_FINISHED".equals(tradeStatus)) {
|
||||
log.warn("支付宝支付通知状态失败,商户订单号: {}: {}", outTradeNo, tradeStatus);
|
||||
return "success"; // 状态不是成功时也返回success,避免重复通知
|
||||
}
|
||||
|
||||
// 处理支付成功的业务逻辑
|
||||
String tradeNo = params.get("trade_no");
|
||||
String totalAmount = params.get("total_amount");
|
||||
|
||||
// 更新数据库中的订单状态
|
||||
boolean success = alipayRentService.processPaySuccessNotify(params);
|
||||
if (success) {
|
||||
log.info("支付宝支付成功,公司ID: {}, 订单号: {}, 支付宝交易号: {}, 金额: {}",
|
||||
companyId, outTradeNo, tradeNo, totalAmount);
|
||||
return "success";
|
||||
} else {
|
||||
log.error("更新支付宝支付状态失败,公司ID: {}, 订单号: {}", companyId, outTradeNo);
|
||||
return "failure";
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理支付宝支付通知异常", e);
|
||||
return "failure";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
package com.sczx.pay.dto.ali.rent;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel(value = "支付宝租赁订单支付请求")
|
||||
@Data
|
||||
public class AlipayRentPayReq {
|
||||
private Long companyId; // 公司ID
|
||||
private String outTradeNo; // 商户订单号
|
||||
private String orderId; //交易组件业务订单号
|
||||
private String payAmount; // 支付金额
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.sczx.pay.dto.ali.rent;
|
||||
|
||||
import com.sczx.pay.dto.AlipayResponse;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel(value = "支付宝租赁订单支付结果")
|
||||
@Data
|
||||
public class AlipayRentPayResponse extends AlipayResponse {
|
||||
|
||||
private String tradeNo; // 支付宝交易号
|
||||
private String outTradeNo; // 商户订单号
|
||||
private String orderId; //交易组件业务订单号
|
||||
private String payAmount; // 支付金额
|
||||
}
|
||||
@ -14,6 +14,7 @@ public class PaymentRecord {
|
||||
private BigDecimal totalFee; // 订单金额
|
||||
private String body; // 商品描述
|
||||
private String openid; // 用户标识(微信支付专用)
|
||||
private String tradeCompOrderId; // 支付宝交易组件订单号
|
||||
private String tradeState; // 交易状态
|
||||
private String tradeStateDesc; // 交易状态描述
|
||||
private Date createTime; // 创建时间
|
||||
@ -26,7 +27,8 @@ public class PaymentRecord {
|
||||
// 支付渠道枚举
|
||||
public enum PayChannel {
|
||||
WECHAT("微信支付"),
|
||||
ALIPAY("支付宝");
|
||||
ALIPAY("支付宝"),
|
||||
ALIPAY_RENT("支付宝租赁支付");
|
||||
|
||||
private final String description;
|
||||
|
||||
@ -164,4 +166,12 @@ public class PaymentRecord {
|
||||
public void setBuyerId(String buyerId) {
|
||||
this.buyerId = buyerId;
|
||||
}
|
||||
|
||||
public String getTradeCompOrderId() {
|
||||
return tradeCompOrderId;
|
||||
}
|
||||
|
||||
public void setTradeCompOrderId(String tradeCompOrderId) {
|
||||
this.tradeCompOrderId = tradeCompOrderId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,23 @@
|
||||
package com.sczx.pay.service;
|
||||
|
||||
import com.sczx.pay.dto.ali.rent.AlipayRentPayReq;
|
||||
import com.sczx.pay.dto.ali.rent.AlipayRentPayResponse;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface AlipayRentService {
|
||||
|
||||
/**
|
||||
* 租赁订单支付
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
AlipayRentPayResponse rentPay(AlipayRentPayReq request);
|
||||
|
||||
/**
|
||||
* 支付成功回调
|
||||
* @param notifyMap
|
||||
* @return
|
||||
*/
|
||||
boolean processPaySuccessNotify(Map<String, String> notifyMap);
|
||||
}
|
||||
|
||||
@ -1,10 +1,194 @@
|
||||
package com.sczx.pay.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alipay.api.domain.AlipayCommerceRentOrderPayModel;
|
||||
import com.alipay.api.domain.RentPayItemDTO;
|
||||
import com.alipay.api.request.AlipayCommerceRentOrderPayRequest;
|
||||
import com.alipay.api.response.AlipayCommerceRentOrderPayResponse;
|
||||
import com.sczx.pay.config.AlipayConf;
|
||||
import com.sczx.pay.dto.ali.rent.AlipayRentPayReq;
|
||||
import com.sczx.pay.dto.ali.rent.AlipayRentPayResponse;
|
||||
import com.sczx.pay.entity.OrderMain;
|
||||
import com.sczx.pay.entity.PayStatus;
|
||||
import com.sczx.pay.entity.PaymentRecord;
|
||||
import com.sczx.pay.mapper.OrderPayMapper;
|
||||
import com.sczx.pay.mapper.PaymentRecordMapper;
|
||||
import com.sczx.pay.mapper.RefundRecordMapper;
|
||||
import com.sczx.pay.service.AlipayRentService;
|
||||
import com.sczx.pay.utils.AlipaySdkUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class AlipayRentServiceImpl implements AlipayRentService {
|
||||
|
||||
@Autowired
|
||||
private AlipayConf alipayConf;
|
||||
|
||||
@Autowired
|
||||
private AlipaySdkUtil alipaySdkUtil;
|
||||
|
||||
@Value("${alipay.rent.payNotifyUrl}")
|
||||
private String notifyUrl;
|
||||
|
||||
@Autowired
|
||||
private PaymentRecordMapper paymentRecordMapper;
|
||||
|
||||
|
||||
@Autowired
|
||||
private RefundRecordMapper refundRecordMapper;
|
||||
|
||||
@Autowired
|
||||
private OrderPayMapper orderPayMapper;
|
||||
|
||||
@Override
|
||||
public AlipayRentPayResponse rentPay(AlipayRentPayReq alipayRentPayReq) {
|
||||
AlipayRentPayResponse response = new AlipayRentPayResponse();
|
||||
try {
|
||||
// 构造请求参数以调用接口
|
||||
AlipayCommerceRentOrderPayRequest request = new AlipayCommerceRentOrderPayRequest();
|
||||
AlipayCommerceRentOrderPayModel model = new AlipayCommerceRentOrderPayModel();
|
||||
|
||||
// 设置租金支付外部请求号
|
||||
model.setOutTradeNo(alipayRentPayReq.getOutTradeNo());
|
||||
|
||||
// 设置业务订单号
|
||||
model.setOrderId(alipayRentPayReq.getOrderId());
|
||||
|
||||
// 设置支付方式,pay_method还可以选择:PRE_AUTH 预授权支付。部分支付场景不可使用租赁代扣 RENT_DEDUCT
|
||||
model.setPayMethod("JSAPI");
|
||||
|
||||
// 设置支付金额
|
||||
model.setPayAmount(alipayRentPayReq.getPayAmount());
|
||||
|
||||
// 设置订单费用项明细列表
|
||||
List<RentPayItemDTO> payItems = new ArrayList<RentPayItemDTO>();
|
||||
RentPayItemDTO payItems0 = new RentPayItemDTO();
|
||||
payItems0.setType("RENT");
|
||||
payItems0.setPayAmount(alipayRentPayReq.getPayAmount());
|
||||
payItems.add(payItems0);
|
||||
model.setPayItems(payItems);
|
||||
|
||||
//二级商户信息
|
||||
// RentSubMerchantDTO rentSubMerchantDTO = new RentSubMerchantDTO();
|
||||
// rentSubMerchantDTO.setMerchantId(alipayConf.getCompanyAppid(alipayRentPayReq.getCompanyId()));
|
||||
// model.setSubMerchant(rentSubMerchantDTO);
|
||||
|
||||
// 设置支付结果通知地址
|
||||
model.setPayNotifyUrl(notifyUrl);
|
||||
|
||||
// 设置支付超时时间
|
||||
model.setPayTimeoutExpress("15m");
|
||||
|
||||
request.setBizModel(model);
|
||||
|
||||
// 第三方代调用模式下请设置app_auth_token
|
||||
// request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
|
||||
|
||||
|
||||
|
||||
// 第三方代调用模式下请设置app_auth_token
|
||||
// request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
|
||||
log.info("支付宝租赁订单下单请求:{}", JSONObject.toJSONString(request));
|
||||
AlipayCommerceRentOrderPayResponse rentOrderPayResponse = alipaySdkUtil.execute(request);
|
||||
log.info("支付宝租赁订单下单下单返回:{}", JSONObject.toJSONString(rentOrderPayResponse));
|
||||
if (rentOrderPayResponse.isSuccess()) {
|
||||
response.setSuccess(true);
|
||||
response.setOutTradeNo(rentOrderPayResponse.getOutTradeNo());
|
||||
response.setTradeNo(rentOrderPayResponse.getTradeNo());
|
||||
response.setCode("SUCCESS");
|
||||
response.setMessage("下单成功");
|
||||
//保存支付单
|
||||
recordPaymentInfo(alipayRentPayReq);
|
||||
|
||||
} else {
|
||||
response.setSuccess(false);
|
||||
response.setCode("FAIL");
|
||||
response.setMessage("下单失败: " + rentOrderPayResponse.getMsg() + ":" + rentOrderPayResponse.getSubMsg());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("支付宝下单异常,公司ID: {}, 订单号: {}", alipayRentPayReq.getCompanyId(), alipayRentPayReq.getOutTradeNo(), e);
|
||||
response.setSuccess(false);
|
||||
response.setCode("FAIL");
|
||||
response.setMessage("下单异常: " + e.getMessage());
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processPaySuccessNotify(Map<String, String> notifyMap) {
|
||||
try {
|
||||
// 这里实现您的业务逻辑
|
||||
// 例如:更新订单状态、发送通知等
|
||||
|
||||
String outTradeNo = notifyMap.get("out_trade_no");
|
||||
String tradeNo = notifyMap.get("trade_no");
|
||||
String totalAmount = notifyMap.get("total_amount");
|
||||
|
||||
log.info("处理支付宝租赁订单支付成功通知,订单号: {}, 交易号: {}, 金额: {}",
|
||||
outTradeNo, tradeNo, totalAmount);
|
||||
|
||||
// 更新支付记录状态
|
||||
int updated = paymentRecordMapper.updateToSuccess(
|
||||
outTradeNo,
|
||||
tradeNo,
|
||||
new Date(), // 支付时间
|
||||
new Date() // 更新时间
|
||||
);
|
||||
if (updated > 0) {
|
||||
log.info("支付宝支付记录状态已更新,订单号: {}, 支付宝交易号: {}", outTradeNo, tradeNo);
|
||||
//更新主订单状态
|
||||
OrderMain orderMain = orderPayMapper.getOrderStatusByOrderNo(outTradeNo);
|
||||
String OrderStatus = orderMain.getOrderStatus();
|
||||
|
||||
if(OrderStatus.equals("WAIT_PAY")){
|
||||
orderPayMapper.updateOrderStatus(orderMain.getOrderNo(),"WAIT_PICK");
|
||||
}else if (OrderStatus.equals("RERENT_WAIT_PAY")){
|
||||
orderPayMapper.updateOrderStatus(orderMain.getOrderNo(),"RENT_ING");
|
||||
}
|
||||
orderPayMapper.updateSubOrderPaymentStatus(outTradeNo,"ZFB_PAY", PayStatus.SUCCESS.getCode(),tradeNo);
|
||||
return true;
|
||||
} else {
|
||||
log.warn("未找到对应的支付宝支付记录,订单号: {}", outTradeNo);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("处理支付宝支付成功通知异常", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录支付信息到数据库
|
||||
*/
|
||||
private void recordPaymentInfo(AlipayRentPayReq alipayRentPayReq) {
|
||||
try {
|
||||
PaymentRecord paymentRecord = new PaymentRecord();
|
||||
paymentRecord.setCompanyId(alipayRentPayReq.getCompanyId());
|
||||
paymentRecord.setOutTradeNo(alipayRentPayReq.getOutTradeNo());
|
||||
paymentRecord.setTotalFee(new BigDecimal(alipayRentPayReq.getPayAmount())); // 转换为元
|
||||
paymentRecord.setTradeCompOrderId(alipayRentPayReq.getOrderId());
|
||||
paymentRecord.setTradeState("NOTPAY"); // 未支付
|
||||
paymentRecord.setTradeStateDesc("未支付");
|
||||
paymentRecord.setCreateTime(new Date());
|
||||
paymentRecord.setUpdateTime(new Date());
|
||||
// paymentRecord.setAttach(request.getAttach());
|
||||
paymentRecord.setPayChannel(PaymentRecord.PayChannel.ALIPAY_RENT.name()); // 设置支付渠道为支付宝支付
|
||||
|
||||
paymentRecordMapper.insertPaymentRecord(paymentRecord);
|
||||
log.info("支付记录已保存,订单号: {}", alipayRentPayReq.getOutTradeNo());
|
||||
} catch (Exception e) {
|
||||
log.error("保存支付记录异常,订单号: {}", alipayRentPayReq.getOutTradeNo(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,3 +91,6 @@ alipay:
|
||||
alipay-root-cert-path: /root/cert/alipayRootCert.crt
|
||||
notify-url: http://115.190.8.52:8019/alipay/pay/notify
|
||||
refund-notify-url: http://115.190.8.52:8019/alipay/refund/notify
|
||||
|
||||
rent:
|
||||
payNotifyUrl: http://115.190.8.52:8019/alipay/rent/notify/pay
|
||||
|
||||
Reference in New Issue
Block a user