|
@@ -1,31 +1,17 @@
|
|
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
|
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
|
|
|
|
|
-import cn.hutool.core.bean.BeanUtil;
|
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
import cn.hutool.core.date.DateUtil;
|
|
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
|
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
|
-import cn.iocoder.yudao.framework.pay.core.client.dto.*;
|
|
|
|
-import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
|
|
|
|
|
+import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO;
|
|
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
|
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
|
-import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum;
|
|
|
|
-import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum;
|
|
|
|
import com.alipay.api.AlipayApiException;
|
|
import com.alipay.api.AlipayApiException;
|
|
-import com.alipay.api.AlipayConfig;
|
|
|
|
-import com.alipay.api.DefaultAlipayClient;
|
|
|
|
-import com.alipay.api.domain.AlipayTradeRefundModel;
|
|
|
|
import com.alipay.api.domain.AlipayTradeWapPayModel;
|
|
import com.alipay.api.domain.AlipayTradeWapPayModel;
|
|
-import com.alipay.api.request.AlipayTradeRefundRequest;
|
|
|
|
import com.alipay.api.request.AlipayTradeWapPayRequest;
|
|
import com.alipay.api.request.AlipayTradeWapPayRequest;
|
|
-import com.alipay.api.response.AlipayTradeRefundResponse;
|
|
|
|
import com.alipay.api.response.AlipayTradeWapPayResponse;
|
|
import com.alipay.api.response.AlipayTradeWapPayResponse;
|
|
-import lombok.SneakyThrows;
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
-import java.net.SocketTimeoutException;
|
|
|
|
-import java.util.Map;
|
|
|
|
import java.util.Objects;
|
|
import java.util.Objects;
|
|
|
|
|
|
-import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* 支付宝【手机网站】的 PayClient 实现类
|
|
* 支付宝【手机网站】的 PayClient 实现类
|
|
* 文档:https://opendocs.alipay.com/apis/api_1/alipay.trade.wap.pay
|
|
* 文档:https://opendocs.alipay.com/apis/api_1/alipay.trade.wap.pay
|
|
@@ -33,22 +19,13 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
|
|
* @author 芋道源码
|
|
* @author 芋道源码
|
|
*/
|
|
*/
|
|
@Slf4j
|
|
@Slf4j
|
|
-public class AlipayWapPayClient extends AbstractPayClient<AlipayPayClientConfig> {
|
|
|
|
|
|
+public class AlipayWapPayClient extends AbstractAlipayClient {
|
|
|
|
|
|
- private DefaultAlipayClient client;
|
|
|
|
|
|
|
|
public AlipayWapPayClient(Long channelId, AlipayPayClientConfig config) {
|
|
public AlipayWapPayClient(Long channelId, AlipayPayClientConfig config) {
|
|
super(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), config, new AlipayPayCodeMapping());
|
|
super(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), config, new AlipayPayCodeMapping());
|
|
}
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
|
- @SneakyThrows
|
|
|
|
- protected void doInit() {
|
|
|
|
- AlipayConfig alipayConfig = new AlipayConfig();
|
|
|
|
- BeanUtil.copyProperties(config, alipayConfig, false);
|
|
|
|
- this.client = new DefaultAlipayClient(alipayConfig);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
@Override
|
|
@Override
|
|
public PayCommonResult<AlipayTradeWapPayResponse> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
|
public PayCommonResult<AlipayTradeWapPayResponse> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
|
// 构建 AlipayTradeWapPayModel 请求
|
|
// 构建 AlipayTradeWapPayModel 请求
|
|
@@ -69,6 +46,7 @@ public class AlipayWapPayClient extends AbstractPayClient<AlipayPayClientConfig>
|
|
request.setBizModel(model);
|
|
request.setBizModel(model);
|
|
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
|
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
|
request.setReturnUrl(reqDTO.getReturnUrl());
|
|
request.setReturnUrl(reqDTO.getReturnUrl());
|
|
|
|
+
|
|
// 执行请求
|
|
// 执行请求
|
|
AlipayTradeWapPayResponse response;
|
|
AlipayTradeWapPayResponse response;
|
|
try {
|
|
try {
|
|
@@ -87,85 +65,11 @@ public class AlipayWapPayClient extends AbstractPayClient<AlipayPayClientConfig>
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
- /**
|
|
|
|
- * 从支付宝通知返回参数中解析 PayOrderNotifyRespDTO, 通知具体参数参考
|
|
|
|
- * //https://opendocs.alipay.com/open/203/105286
|
|
|
|
- * @param data 通知结果
|
|
|
|
- * @return 解析结果 PayOrderNotifyRespDTO
|
|
|
|
- * @throws Exception 解析失败,抛出异常
|
|
|
|
- */
|
|
|
|
- @Override
|
|
|
|
- public PayOrderNotifyRespDTO parseOrderNotify(PayNotifyDataDTO data) throws Exception {
|
|
|
|
- Map<String, String> params = data.getParams();
|
|
|
|
- return PayOrderNotifyRespDTO.builder().orderExtensionNo(params.get("out_trade_no"))
|
|
|
|
- .channelOrderNo(params.get("trade_no")).channelUserId(params.get("seller_id"))
|
|
|
|
- .tradeStatus(params.get("trade_status"))
|
|
|
|
- .successTime(DateUtil.parse(params.get("notify_time"), "yyyy-MM-dd HH:mm:ss"))
|
|
|
|
- .data(data.getBody()).build();
|
|
|
|
- }
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
- protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
|
|
|
- AlipayTradeRefundModel model=new AlipayTradeRefundModel();
|
|
|
|
- model.setTradeNo(reqDTO.getChannelOrderNo());
|
|
|
|
- model.setOutTradeNo(reqDTO.getPayTradeNo());
|
|
|
|
- model.setOutRequestNo(reqDTO.getRefundReqNo());
|
|
|
|
- model.setRefundAmount(calculateAmount(reqDTO.getAmount()).toString());
|
|
|
|
- model.setRefundReason(reqDTO.getReason());
|
|
|
|
- AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest();
|
|
|
|
- refundRequest.setBizModel(model);
|
|
|
|
- PayRefundUnifiedRespDTO respDTO = new PayRefundUnifiedRespDTO();
|
|
|
|
- try {
|
|
|
|
- AlipayTradeRefundResponse response = client.execute(refundRequest);
|
|
|
|
- log.info("[doUnifiedRefund][response({}) 发起退款 渠道返回", toJsonString(response));
|
|
|
|
- if (response.isSuccess()) {
|
|
|
|
- //退款成功,更新为PROCESSING_NOTIFY, 而不是 SYNC_SUCCESS 通过支付宝回调接口处理。退款导致触发的异步通知,
|
|
|
|
- //退款导致触发的异步通知是发送到支付接口中设置的notify_url
|
|
|
|
- //TODO 沙箱环境 返回 的tradeNo(渠道退款单号) 和 订单的tradNo 是一个值,是不是理解不对?
|
|
|
|
- respDTO.setRespEnum(PayChannelRespEnum.PROCESSING_NOTIFY);
|
|
|
|
- }else{
|
|
|
|
- //特殊处理 sub_code ACQ.SYSTEM_ERROR(系统错误), 需要调用重试任务
|
|
|
|
- //沙箱环境返回的貌似是”aop.ACQ.SYSTEM_ERROR“, 用contain
|
|
|
|
- if (response.getSubCode().contains("ACQ.SYSTEM_ERROR")) {
|
|
|
|
- respDTO.setRespEnum(PayChannelRespEnum.RETRY_FAILURE)
|
|
|
|
- .setChannelErrMsg(response.getSubMsg())
|
|
|
|
- .setChannelErrCode(response.getSubCode());
|
|
|
|
- }else{
|
|
|
|
- //其他当做不可以重试的错误
|
|
|
|
- respDTO.setRespEnum(PayChannelRespEnum.CAN_NOT_RETRY_FAILURE)
|
|
|
|
- .setChannelErrCode(response.getSubCode())
|
|
|
|
- .setChannelErrMsg(response.getSubMsg());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return respDTO;
|
|
|
|
- } catch (AlipayApiException e) {
|
|
|
|
- //TODO 记录异常日志
|
|
|
|
- log.error("[doUnifiedRefund][request({}) 发起退款失败,网络读超时,退款状态未知]", toJsonString(reqDTO), e);
|
|
|
|
- Throwable cause = e.getCause();
|
|
|
|
- //网络 read time out 异常, 退款状态未知
|
|
|
|
- if (cause instanceof SocketTimeoutException) {
|
|
|
|
- respDTO.setExceptionMsg(e.getMessage())
|
|
|
|
- .setRespEnum(PayChannelRespEnum.READ_TIME_OUT_EXCEPTION);
|
|
|
|
- }else{
|
|
|
|
- respDTO.setExceptionMsg(e.getMessage())
|
|
|
|
- .setChannelErrCode(e.getErrCode())
|
|
|
|
- .setChannelErrMsg(e.getErrMsg())
|
|
|
|
- .setRespEnum(PayChannelRespEnum.CALL_EXCEPTION);
|
|
|
|
- }
|
|
|
|
- return respDTO;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
- public PayRefundNotifyDTO parseRefundNotify(PayNotifyDataDTO notifyData) {
|
|
|
|
- Map<String, String> params = notifyData.getParams();
|
|
|
|
- PayRefundNotifyDTO notifyDTO = PayRefundNotifyDTO.builder().channelOrderNo(params.get("trade_no"))
|
|
|
|
- .tradeNo(params.get("out_trade_no"))
|
|
|
|
- .reqNo(params.get("out_biz_no"))
|
|
|
|
- .status(PayNotifyRefundStatusEnum.SUCCESS)
|
|
|
|
- .refundSuccessTime(DateUtil.parse(params.get("gmt_refund"), "yyyy-MM-dd HH:mm:ss"))
|
|
|
|
- .build();
|
|
|
|
- return notifyDTO;
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
|
|
}
|
|
}
|