|
|
@@ -4,6 +4,11 @@ import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.date.DateTime;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
+import com.alipay.api.AlipayClient;
|
|
|
+import com.alipay.api.domain.AlipayTradeRefundModel;
|
|
|
+import com.alipay.api.internal.util.AlipaySignature;
|
|
|
+import com.alipay.api.request.AlipayTradeRefundRequest;
|
|
|
+import com.alipay.api.response.AlipayTradeRefundResponse;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.cyksj.common.exception.BusinessRuntimeException;
|
|
|
@@ -12,6 +17,9 @@ import com.cyksj.common.util.Codec;
|
|
|
import com.cyksj.common.util.Jsons;
|
|
|
import com.cyksj.common.util.Xmls;
|
|
|
import com.cyksj.config.WeChatConfig;
|
|
|
+import com.cyksj.config.zfb.AliPayClientFactory;
|
|
|
+import com.cyksj.config.zfb.BaseZfbConfig;
|
|
|
+import com.cyksj.config.zfb.ZfbProductCode;
|
|
|
import com.cyksj.dto.RedisKey;
|
|
|
import com.cyksj.dto.Result;
|
|
|
import com.cyksj.enums.GatewayResponse;
|
|
|
@@ -21,14 +29,17 @@ import com.cyksj.mapper.SpotifyUnLimitRecordMapper;
|
|
|
import com.cyksj.mapper.UserMapper;
|
|
|
import com.cyksj.mapper.channel.ShopConfigMapper;
|
|
|
import com.cyksj.mapper.manage.coupon.CouponMapper;
|
|
|
+import com.cyksj.model.dto.AliPayParams;
|
|
|
import com.cyksj.model.dto.H5JsPayParams;
|
|
|
import com.cyksj.model.entity.*;
|
|
|
import com.cyksj.model.manage.request.RegisterReq;
|
|
|
+import com.cyksj.model.request.AlipayOrderDonReq;
|
|
|
import com.cyksj.model.request.OrderAttach;
|
|
|
import com.cyksj.model.request.OrderRefundReq;
|
|
|
import com.cyksj.model.views.CouponUserView;
|
|
|
import com.cyksj.redis.RedisService;
|
|
|
import com.cyksj.service.mange.coupon.CouponCommonService;
|
|
|
+import com.cyksj.service.pay.AliPayCommonService;
|
|
|
import com.cyksj.service.register.RegisterOrderDonService;
|
|
|
import com.cyksj.service.register.SpotifyService;
|
|
|
import com.cyksj.service.sys.SysConfigService;
|
|
|
@@ -45,6 +56,8 @@ import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
+import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Optional;
|
|
|
|
|
|
@@ -89,6 +102,8 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
|
|
|
|
|
|
private final ShopConfigMapper shopConfigMapper;
|
|
|
|
|
|
+ private final AliPayCommonService aliPayCommonService;
|
|
|
+
|
|
|
private static final Long EXPIRY_TIME = 1000 * 60 * 5L;
|
|
|
|
|
|
/**
|
|
|
@@ -133,6 +148,8 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
|
|
|
orderDon.setIsFree(isFree);
|
|
|
orderDon.setMoney(isFree ? BigDecimal.ZERO : BigDecimal.valueOf(("apple".equals(req.getPlatform()) && "auto".equals(req.getAppleRegisterType())) ? map.get("appleAuto") : map.get(req.getPlatform())));
|
|
|
orderDon.setStatus(isFree ? RegisterOrderDon.Status.hasPayment : RegisterOrderDon.Status.noPayment);
|
|
|
+ String shopId = sysConfigService.getDefaultShopConfigByType("zfb");
|
|
|
+ orderDon.setShopId(shopId);
|
|
|
save(orderDon);
|
|
|
//apple
|
|
|
handleAppleIdAuto(userId, req, orderDon);
|
|
|
@@ -181,11 +198,11 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
|
|
|
appleAutoRegisterData.setUserId(0l);
|
|
|
appleAutoRegisterData.setOrderId(0l);
|
|
|
appleAutoRegisterDataMapper.updateById(appleAutoRegisterData);
|
|
|
- //订单关闭
|
|
|
- registerOrderDon.setStatus(RegisterOrderDon.Status.close);
|
|
|
- registerOrderDonMapper.updateById(registerOrderDon);
|
|
|
log.info("未支付appleID自动注册订单:{},修改appleID使用状态", orderId);
|
|
|
}
|
|
|
+ //订单关闭
|
|
|
+ registerOrderDon.setStatus(RegisterOrderDon.Status.close);
|
|
|
+ registerOrderDonMapper.updateById(registerOrderDon);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -245,6 +262,79 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
|
|
|
return couponUserView;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void unifiedRefund(OrderRefundReq refundReq) throws Exception {
|
|
|
+ Long orderId = refundReq.getOrderId();
|
|
|
+ RegisterOrderDon registerOrderDon = this.getById(orderId);
|
|
|
+ if (registerOrderDon == null) throw BusinessRuntimeException.getInstance("订单不存在");
|
|
|
+ if (registerOrderDon.getStatus() == RegisterOrderDon.Status.refund) throw BusinessRuntimeException.getInstance("该订单已退款");
|
|
|
+
|
|
|
+ if (registerOrderDon.getStatus() != RegisterOrderDon.Status.error && registerOrderDon.getStatus() != RegisterOrderDon.Status.hasPayment) {
|
|
|
+ throw BusinessRuntimeException.getInstance("该订单状态不允许退款");
|
|
|
+ }
|
|
|
+ if (registerOrderDon.getMoney().compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
+ throw BusinessRuntimeException.getInstance("该订单金额为0,无需退款");
|
|
|
+ }
|
|
|
+ if (!redisService.setNx(String.format("%s", refundReq.getOrderId()), refundReq.getOrderId(), 10l)) {
|
|
|
+ throw BusinessRuntimeException.getInstance("请勿重复点击,正在退款中..");
|
|
|
+ }
|
|
|
+ RegisterOrderDon.Type type = registerOrderDon.getType();
|
|
|
+ if (type == RegisterOrderDon.Type.WeChat) {
|
|
|
+ wxRefund(refundReq, registerOrderDon);
|
|
|
+ }
|
|
|
+ if (type == RegisterOrderDon.Type.ALI_PAY) {
|
|
|
+ zfbRefund(refundReq, registerOrderDon);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public AliPayParams zfbUnifiedPay(AlipayOrderDonReq re) throws Exception {
|
|
|
+ String productCode = StrUtil.EMPTY;
|
|
|
+ if (re.getType() == 1) {
|
|
|
+ productCode = ZfbProductCode.MOBILE_WEB.getProductCode();
|
|
|
+ }
|
|
|
+ if (re.getType() == 2) {
|
|
|
+ productCode = ZfbProductCode.PC_WEB.getProductCode();
|
|
|
+ }
|
|
|
+ return aliPayCommonService.unifiedPayRegister(re.getOrderId(), productCode, re.getPayMode(), re.getReturnUrl());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void aliPayNotify(Map<String, String> params) throws Exception {
|
|
|
+ //调用SDK验证签名
|
|
|
+ String body = Codec.DoBase64.custom().setData(params.get("body")).decodeAsText();
|
|
|
+ OrderAttach orderAttach = Jsons.parseObject(body, OrderAttach.class);
|
|
|
+ Long oderId = orderAttach.getO();
|
|
|
+ RegisterOrderDon orderDon = getById(oderId);
|
|
|
+ if (null == orderDon) {
|
|
|
+ throw BusinessRuntimeException.getInstance("订单不存在.");
|
|
|
+ }
|
|
|
+ String appId = params.get("app_id");
|
|
|
+ boolean signVerified = AlipaySignature.rsaCheckV1(params, shopConfigMapper.getByAppId(appId).getPublicKey(), BaseZfbConfig.charset, BaseZfbConfig.signType);
|
|
|
+ if (!signVerified) {
|
|
|
+ log.error("支付宝回调校验签名错误,自定义入参:{}", params.get("body"));
|
|
|
+ throw BusinessRuntimeException.getInstance("支付宝回调校验签名错误");
|
|
|
+ }
|
|
|
+ String transactionId = params.get("trade_no");
|
|
|
+ String payTimeStr = params.get("gmt_payment");
|
|
|
+ if (!orderDon.getStatus().equals(RegisterOrderDon.Status.noPayment) && !orderDon.getStatus().equals(RegisterOrderDon.Status.close)) {
|
|
|
+ log.info("支付宝已回调,重复修改状态 id:{}", orderDon.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更改订单状态
|
|
|
+ orderDon.setTransactionId(transactionId);
|
|
|
+ orderDon.setStatus(RegisterOrderDon.Status.hasPayment);
|
|
|
+ AppleAutoRegisterData appleAutoRegisterData = appleAutoRegisterDataMapper.selectOne(Wrappers.lambdaQuery(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getOrderId, orderDon.getId()).eq(AppleAutoRegisterData::getStatus, true));
|
|
|
+ if (appleAutoRegisterData != null) {
|
|
|
+ orderDon.setStatus(RegisterOrderDon.Status.complete);
|
|
|
+ }
|
|
|
+ if (StrUtil.isNotBlank(payTimeStr)) {
|
|
|
+ orderDon.setPayTime(DateUtil.parse(payTimeStr, "yyyy-MM-dd HH:mm:ss"));
|
|
|
+ }
|
|
|
+ this.updateById(orderDon);
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public H5JsPayParams pay(Long orderId) throws Exception {
|
|
|
log.info("注册 账号调起微信支付[start] orderId:{}", orderId);
|
|
|
@@ -332,30 +422,16 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public Result<String> wxRefund(OrderRefundReq refundReq) throws Exception {
|
|
|
- RegisterOrderDon registerOrderDon = this.getById(refundReq.getOrderId());
|
|
|
- if (registerOrderDon == null) {
|
|
|
- throw BusinessRuntimeException.getInstance("该订单不存在");
|
|
|
- }
|
|
|
- if (registerOrderDon.getStatus() == RegisterOrderDon.Status.refund) {
|
|
|
- throw BusinessRuntimeException.getInstance("该订单已退款");
|
|
|
- }
|
|
|
- if (registerOrderDon.getStatus() != RegisterOrderDon.Status.error && registerOrderDon.getStatus() != RegisterOrderDon.Status.hasPayment) {
|
|
|
- throw BusinessRuntimeException.getInstance("该订单状态不允许退款");
|
|
|
- }
|
|
|
- if (registerOrderDon.getMoney().compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
- throw BusinessRuntimeException.getInstance("该订单金额为0,无需退款");
|
|
|
- }
|
|
|
- if (!redisService.setNx(String.format("%s", refundReq.getOrderId()), refundReq.getOrderId(), 10l)) {
|
|
|
- throw BusinessRuntimeException.getInstance("请勿重复点击,正在退款中..");
|
|
|
- }
|
|
|
+ public Result<String> wxRefund(OrderRefundReq refundReq,RegisterOrderDon registerOrderDon) throws Exception {
|
|
|
long time = System.currentTimeMillis();
|
|
|
//退款订单号
|
|
|
String outRefundNo = Codec.DoDigest.custom()
|
|
|
.setAlgorithm(Codec.DoDigest.Algorithm.MD5)
|
|
|
.setStringData(time + String.valueOf(registerOrderDon.getId()))
|
|
|
.toHexString();
|
|
|
- refundReq.setRefundMoney(registerOrderDon.getMoney());
|
|
|
+ if (refundReq.getRefundMoney() == null) {
|
|
|
+ refundReq.setRefundMoney(registerOrderDon.getMoney());
|
|
|
+ }
|
|
|
weChatService.refundWxOrder(weChatConfig.getAppid(),
|
|
|
Optional.ofNullable(registerOrderDon.getShopId()).orElse(ShopConfig.WX_DEFAULT_APP_ID),
|
|
|
registerOrderDon.getTransactionId(),
|
|
|
@@ -365,6 +441,7 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
|
|
|
weChatConfig.getDomain() + "manage/register/wx/refund/notify");
|
|
|
//修改订单状态
|
|
|
registerOrderDon.setStatus(RegisterOrderDon.Status.refund);
|
|
|
+ registerOrderDon.setRefundMoney(refundReq.getRefundMoney());
|
|
|
this.updateById(registerOrderDon);
|
|
|
return GatewayResponse.SUCCESS.newBuilder().toResult("退款成功");
|
|
|
}
|
|
|
@@ -395,4 +472,39 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
|
|
|
}
|
|
|
log.info("微信退款: 退款单号[{}] 退款成功.", outRefundNo);
|
|
|
}
|
|
|
+
|
|
|
+ public void zfbRefund(OrderRefundReq refundReq, RegisterOrderDon registerOrderDon) throws Exception {
|
|
|
+ AlipayTradeRefundResponse response;
|
|
|
+ //支付宝退款
|
|
|
+ AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(Optional.ofNullable(registerOrderDon.getShopId()).orElse(ShopConfig.ZFB_DEFAULT_APP_ID));
|
|
|
+ AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
|
|
|
+ AlipayTradeRefundModel model = new AlipayTradeRefundModel();
|
|
|
+ //支付宝交易号
|
|
|
+ model.setTradeNo(registerOrderDon.getTransactionId());
|
|
|
+ if (refundReq.getRefundMoney() == null) {
|
|
|
+ refundReq.setRefundMoney(registerOrderDon.getMoney());
|
|
|
+ }
|
|
|
+ model.setRefundAmount(refundReq.getRefundMoney().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_EVEN).toString());
|
|
|
+ model.setQueryOptions(List.of("gmt_refund_pay"));
|
|
|
+ long time = System.currentTimeMillis();
|
|
|
+ //退款订单号
|
|
|
+ String outRefundNo = Codec.DoDigest.custom()
|
|
|
+ .setAlgorithm(Codec.DoDigest.Algorithm.MD5)
|
|
|
+ .setStringData(time + String.valueOf(registerOrderDon.getId()))
|
|
|
+ .toHexString();
|
|
|
+ //退款请求号
|
|
|
+ model.setOutRequestNo(outRefundNo);
|
|
|
+ request.setBizModel(model);
|
|
|
+ String shopId = registerOrderDon.getShopId();
|
|
|
+ ShopConfig shopConfig = shopConfigMapper.selectOne(Wrappers.lambdaQuery(ShopConfig.class).eq(ShopConfig::getAppId, registerOrderDon.getShopId()));
|
|
|
+ if (shopId != null && shopConfig != null && shopConfig.getIsCert()) {
|
|
|
+ response = alipayClient.certificateExecute(request);
|
|
|
+ } else {
|
|
|
+ response = alipayClient.execute(request);
|
|
|
+ }
|
|
|
+ if (!response.isSuccess()) throw BusinessRuntimeException.getInstance("退款失败,e:{0}", response.getSubMsg());
|
|
|
+ registerOrderDon.setStatus(RegisterOrderDon.Status.refund);
|
|
|
+ registerOrderDon.setRefundMoney(refundReq.getRefundMoney());
|
|
|
+ registerOrderDonMapper.updateById(registerOrderDon);
|
|
|
+ }
|
|
|
}
|