|
|
@@ -35,6 +35,7 @@ import shop.alien.util.common.constant.PaymentEnum;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
import java.nio.file.Files;
|
|
|
import java.nio.file.Path;
|
|
|
import java.util.Date;
|
|
|
@@ -75,7 +76,16 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
if (storeId == null || orderId == null) {
|
|
|
return R.fail("门店ID和订单ID不能为空");
|
|
|
}
|
|
|
- if (StringUtils.isBlank(amountYuan) || new BigDecimal(amountYuan).compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
+ if (StringUtils.isBlank(amountYuan)) {
|
|
|
+ return R.fail("支付金额不能为空");
|
|
|
+ }
|
|
|
+ BigDecimal amountYuanBD;
|
|
|
+ try {
|
|
|
+ amountYuanBD = new BigDecimal(amountYuan).setScale(2, RoundingMode.HALF_UP);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ return R.fail("支付金额格式不正确");
|
|
|
+ }
|
|
|
+ if (amountYuanBD.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
return R.fail("支付金额必须大于0");
|
|
|
}
|
|
|
if (StringUtils.isBlank(subject)) {
|
|
|
@@ -101,6 +111,11 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
if (order.getPaymentStatus() != null && order.getPaymentStatus() == 1) {
|
|
|
return R.fail("订单已支付");
|
|
|
}
|
|
|
+ // 校验支付金额与订单订金金额一致(考虑精度,保留2位小数)
|
|
|
+ BigDecimal depositAmount = order.getDepositAmount() != null ? order.getDepositAmount() : BigDecimal.ZERO;
|
|
|
+ if (amountYuanBD.compareTo(depositAmount.setScale(2, RoundingMode.HALF_UP)) != 0) {
|
|
|
+ return R.fail("支付金额与订单订金金额不一致");
|
|
|
+ }
|
|
|
|
|
|
// 再次调用时优先从 Redis 获取已生成的预支付信息(未过期则直接返回)
|
|
|
String redisKey = REDIS_PREPAY_KEY_PREFIX + orderId;
|
|
|
@@ -125,7 +140,6 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
}
|
|
|
|
|
|
String outTradeNo = UniqueRandomNumGenerator.generateUniqueCode(19);
|
|
|
- BigDecimal amount = new BigDecimal(amountYuan);
|
|
|
|
|
|
MerchantPaymentOrder paymentOrder = new MerchantPaymentOrder();
|
|
|
paymentOrder.setPaymentNo(merchantPaymentOrderService.generatePaymentNo());
|
|
|
@@ -135,7 +149,7 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
paymentOrder.setStoreId(storeId);
|
|
|
paymentOrder.setPayType(PaymentEnum.ALIPAY.getType());
|
|
|
paymentOrder.setOutTradeNo(outTradeNo);
|
|
|
- paymentOrder.setPayAmount(amount);
|
|
|
+ paymentOrder.setPayAmount(amountYuanBD);
|
|
|
paymentOrder.setPayStatus(0);
|
|
|
paymentOrder.setPayerUserId(userId);
|
|
|
paymentOrder.setSubject(subject);
|
|
|
@@ -149,7 +163,7 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
|
|
|
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
|
|
|
model.setOutTradeNo(outTradeNo);
|
|
|
- model.setTotalAmount(amountYuan);
|
|
|
+ model.setTotalAmount(amountYuanBD.toPlainString());
|
|
|
model.setSubject(subject);
|
|
|
// 预支付单有效时间 15 分钟(相对超时,格式 1m~15d)
|
|
|
model.setTimeoutExpress("15m");
|
|
|
@@ -196,6 +210,10 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
|
|
|
if (order == null) {
|
|
|
return R.fail("预订订单不存在");
|
|
|
}
|
|
|
+ // 本地已标记已支付,直接返回成功,不再调用支付宝
|
|
|
+ if (order.getPaymentStatus() != null && order.getPaymentStatus() == 1) {
|
|
|
+ return R.success("支付成功");
|
|
|
+ }
|
|
|
try {
|
|
|
com.alipay.api.AlipayConfig alipayConfig = buildAlipayConfigFromStore(config);
|
|
|
AlipayClient client = new DefaultAlipayClient(alipayConfig);
|