This commit is contained in:
menxipeng
2025-11-08 11:55:59 +08:00
parent 185eb4fcca
commit 41c0c36134
9 changed files with 149 additions and 149 deletions

View File

@@ -1,5 +1,7 @@
package com.ruoyi.common.core.domain.dto; package com.ruoyi.common.core.domain.dto;
import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
/** /**
@@ -8,6 +10,7 @@ import java.io.Serializable;
* @author ruoyi * @author ruoyi
* @date 2025-01-27 * @date 2025-01-27
*/ */
@Data
public class OrderCreateRequest implements Serializable { public class OrderCreateRequest implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -16,7 +19,7 @@ public class OrderCreateRequest implements Serializable {
private String orderName; private String orderName;
/** 金额(分) */ /** 金额(分) */
private Long amount; private String amount;
/** 支付方式 aliPay/wechatPay/applePay */ /** 支付方式 aliPay/wechatPay/applePay */
private String payType; private String payType;
@@ -30,51 +33,4 @@ public class OrderCreateRequest implements Serializable {
/** 客户端IP */ /** 客户端IP */
private String clientIp; private String clientIp;
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public Long getAmount() {
return amount;
}
public void setAmount(Long amount) {
this.amount = amount;
}
public String getPayType() {
return payType;
}
public void setPayType(String payType) {
this.payType = payType;
}
public String getPackageType() {
return packageType;
}
public void setPackageType(String packageType) {
this.packageType = packageType;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public String getClientIp() {
return clientIp;
}
public void setClientIp(String clientIp) {
this.clientIp = clientIp;
}
} }

View File

@@ -1,5 +1,6 @@
package com.ruoyi.common.core.domain.entity; package com.ruoyi.common.core.domain.entity;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
@@ -36,7 +37,7 @@ public class OrderInfo extends BaseEntity
/** 金额 分 */ /** 金额 分 */
@Excel(name = "金额 分") @Excel(name = "金额 分")
private Long amount; private BigDecimal amount;
/** 支付方式 aliPay / wechatPay / applePay */ /** 支付方式 aliPay / wechatPay / applePay */
@Excel(name = "支付方式 aliPay / wechatPay / applePay ") @Excel(name = "支付方式 aliPay / wechatPay / applePay ")

View File

@@ -7,15 +7,15 @@ import java.util.List;
/** /**
* 【请填写功能名称】Mapper接口 * 【请填写功能名称】Mapper接口
* *
* @author ruoyi * @author ruoyi
* @date 2025-08-03 * @date 2025-08-03
*/ */
public interface OrderInfoMapper public interface OrderInfoMapper
{ {
/** /**
* 查询【请填写功能名称】 * 查询【请填写功能名称】
* *
* @param id 【请填写功能名称】主键 * @param id 【请填写功能名称】主键
* @return 【请填写功能名称】 * @return 【请填写功能名称】
*/ */
@@ -23,7 +23,7 @@ public interface OrderInfoMapper
/** /**
* 查询【请填写功能名称】列表 * 查询【请填写功能名称】列表
* *
* @param orderInfo 【请填写功能名称】 * @param orderInfo 【请填写功能名称】
* @return 【请填写功能名称】集合 * @return 【请填写功能名称】集合
*/ */
@@ -31,7 +31,7 @@ public interface OrderInfoMapper
/** /**
* 新增【请填写功能名称】 * 新增【请填写功能名称】
* *
* @param orderInfo 【请填写功能名称】 * @param orderInfo 【请填写功能名称】
* @return 结果 * @return 结果
*/ */
@@ -39,7 +39,7 @@ public interface OrderInfoMapper
/** /**
* 修改【请填写功能名称】 * 修改【请填写功能名称】
* *
* @param orderInfo 【请填写功能名称】 * @param orderInfo 【请填写功能名称】
* @return 结果 * @return 结果
*/ */
@@ -47,7 +47,7 @@ public interface OrderInfoMapper
/** /**
* 删除【请填写功能名称】 * 删除【请填写功能名称】
* *
* @param id 【请填写功能名称】主键 * @param id 【请填写功能名称】主键
* @return 结果 * @return 结果
*/ */
@@ -55,7 +55,7 @@ public interface OrderInfoMapper
/** /**
* 批量删除【请填写功能名称】 * 批量删除【请填写功能名称】
* *
* @param ids 需要删除的数据主键集合 * @param ids 需要删除的数据主键集合
* @return 结果 * @return 结果
*/ */
@@ -63,7 +63,7 @@ public interface OrderInfoMapper
/** /**
* 根据订单号查询订单 * 根据订单号查询订单
* *
* @param orderId 订单号 * @param orderId 订单号
* @return 订单信息 * @return 订单信息
*/ */
@@ -71,9 +71,11 @@ public interface OrderInfoMapper
/** /**
* 查询订单列表(包含用户信息和套餐信息) * 查询订单列表(包含用户信息和套餐信息)
* *
* @param orderInfo 查询条件 * @param orderInfo 查询条件
* @return 订单列表 * @return 订单列表
*/ */
public List<OrderInfoVO> selectOrderInfoVOList(OrderInfo orderInfo); public List<OrderInfoVO> selectOrderInfoVOList(OrderInfo orderInfo);
OrderInfo selectByTradeNo(String transactionId);
} }

View File

@@ -15,4 +15,6 @@ public interface ShopUserService {
* @param type 1 - 月 2-季 3-半年 4-年 * @param type 1 - 月 2-季 3-半年 4-年
*/ */
ShopUser updateShopUserVipTime(Long userId, String type); ShopUser updateShopUserVipTime(Long userId, String type);
ShopUser selectUserById(Long userId);
} }

View File

@@ -205,6 +205,11 @@ public class CShopUserServiceImpl implements ShopUserService {
} }
} }
@Override
public ShopUser selectUserById(Long userId) {
return shopUserMapper.selectShopUserByUserId(userId);
}
public ShopUser loginAndRegis(ShopUserResq shopUser) { public ShopUser loginAndRegis(ShopUserResq shopUser) {
ShopUser member = shopUserMapper.selectShopUserByPhone(shopUser.getPhone()); ShopUser member = shopUserMapper.selectShopUserByPhone(shopUser.getPhone());
if (shopUser.getPhone() != null && StringUtils.isNull(member)) { if (shopUser.getPhone() != null && StringUtils.isNull(member)) {

View File

@@ -6,6 +6,7 @@ import com.ruoyi.common.core.domain.dto.PaymentRequest;
import com.ruoyi.common.core.domain.dto.RefundRequest; import com.ruoyi.common.core.domain.dto.RefundRequest;
import com.ruoyi.common.core.domain.entity.OrderInfo; import com.ruoyi.common.core.domain.entity.OrderInfo;
import com.ruoyi.common.core.domain.entity.PayStatusEnum; import com.ruoyi.common.core.domain.entity.PayStatusEnum;
import com.ruoyi.common.core.domain.entity.ShopUser;
import com.ruoyi.common.core.domain.vo.OrderInfoVO; import com.ruoyi.common.core.domain.vo.OrderInfoVO;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
@@ -19,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*; import java.util.*;
/** /**
@@ -115,7 +117,7 @@ public class OrderInfoServiceImpl implements IOrderInfoService
public AjaxResult createOrder(OrderCreateRequest request) { public AjaxResult createOrder(OrderCreateRequest request) {
try { try {
// 参数校验 // 参数校验
if (StringUtils.isEmpty(request.getOrderName()) || request.getAmount() == null || request.getAmount() <= 0) { if (StringUtils.isEmpty(request.getOrderName()) || request.getAmount() == null || new BigDecimal(request.getAmount()).compareTo(BigDecimal.ZERO) < 0 ) {
return AjaxResult.error("订单信息不完整"); return AjaxResult.error("订单信息不完整");
} }
@@ -131,7 +133,7 @@ public class OrderInfoServiceImpl implements IOrderInfoService
orderInfo.setOrderId(System.currentTimeMillis()); // 使用时间戳作为订单号 orderInfo.setOrderId(System.currentTimeMillis()); // 使用时间戳作为订单号
orderInfo.setOrderName(request.getOrderName()); orderInfo.setOrderName(request.getOrderName());
orderInfo.setUserId(loginUser.getUserId()); orderInfo.setUserId(loginUser.getUserId());
orderInfo.setAmount(request.getAmount()); orderInfo.setAmount(new BigDecimal(request.getAmount()));
orderInfo.setPayType(request.getPayType()); orderInfo.setPayType(request.getPayType());
orderInfo.setPackageType(request.getPackageType()); orderInfo.setPackageType(request.getPackageType());
orderInfo.setDeviceType(request.getDeviceType()); orderInfo.setDeviceType(request.getDeviceType());
@@ -175,17 +177,14 @@ public class OrderInfoServiceImpl implements IOrderInfoService
// 检查用户权限 // 检查用户权限
LoginUser loginUser = SecurityUtils.getLoginUser(); LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null || !loginUser.getUserId().equals(orderInfo.getUserId())) { if (loginUser == null || !loginUser.getUserId().equals(orderInfo.getUserId())) {
// return AjaxResult.error("无权限操作此订单"); return AjaxResult.error("无权限操作此订单");
// } }
// 调用第三方支付接口 TODO// 待修改 // 调用第三方支付接口 TODO// 待修改
processPayment(orderInfo, request); ShopUser shopUser = processPayment(orderInfo, request);
if (shopUser != null){
boolean paymentResult = true; return AjaxResult.success(shopUser);
if (paymentResult){
return AjaxResult.success("支付请求成功");
}else { }else {
return AjaxResult.error("支付请求失败"); return AjaxResult.error("支付请求失败");
} }
@@ -254,7 +253,7 @@ public class OrderInfoServiceImpl implements IOrderInfoService
} }
// 检查退款金额 // 检查退款金额
if (request.getRefundAmount() > orderInfo.getAmount()) { if (orderInfo.getAmount().compareTo(new BigDecimal(request.getRefundAmount())) > 0) {
return AjaxResult.error("退款金额不能大于订单金额"); return AjaxResult.error("退款金额不能大于订单金额");
} }
@@ -349,22 +348,23 @@ public class OrderInfoServiceImpl implements IOrderInfoService
/** /**
* 处理支付过程 * 处理支付过程
*/ */
private boolean processPayment(OrderInfo orderInfo, PaymentRequest request) { private ShopUser processPayment(OrderInfo orderInfo, PaymentRequest request) {
String payType = orderInfo.getPayType(); String payType = orderInfo.getPayType();
// 根据支付方式调用相应的支付接口 // 根据支付方式调用相应的支付接口
switch (payType) { switch (payType) {
case "aliPay": case "aliPay":
//return paymentUtil.processAliPay(orderInfo, request); //return paymentUtil.processAliPay(orderInfo, request);
return false; return null;
case "wechatPay": case "wechatPay":
//return paymentUtil.processWechatPay(orderInfo, request); //return paymentUtil.processWechatPay(orderInfo, request);
return false; return null;
case "applePay": case "applePay":
return appleyPay.setIapCertificate(String.valueOf(orderInfo.getUserId()), request.getPaymentToken(), false); return appleyPay.setIapCertificate(orderInfo.getUserId(), request.getPaymentToken(),
orderInfo, false);
default: default:
Map<String, Object> errorResult = new HashMap<>(); Map<String, Object> errorResult = new HashMap<>();
errorResult.put("error", "不支持的支付方式"); errorResult.put("error", "不支持的支付方式");
return false; return null;
} }
} }
@@ -380,13 +380,13 @@ public class OrderInfoServiceImpl implements IOrderInfoService
if ("1".equals(packageType)) { if ("1".equals(packageType)) {
// 包月 // 包月
orderInfo.setEndTime(DateUtils.addMonths(now, 1)); orderInfo.setEndTime(DateUtils.addMonths(now, 1));
} else if ("3".equals(packageType)) { } else if ("2".equals(packageType)) {
// 包季度 // 包季度
orderInfo.setEndTime(DateUtils.addMonths(now, 3)); orderInfo.setEndTime(DateUtils.addMonths(now, 3));
} else if ("6".equals(packageType)) { } else if ("3".equals(packageType)) {
// 半年 // 半年
orderInfo.setEndTime(DateUtils.addMonths(now, 6)); orderInfo.setEndTime(DateUtils.addMonths(now, 6));
} else if ("12".equals(packageType)) { } else if ("4".equals(packageType)) {
// 一年 // 一年
orderInfo.setEndTime(DateUtils.addMonths(now, 12)); orderInfo.setEndTime(DateUtils.addMonths(now, 12));
} }

View File

@@ -2,6 +2,7 @@ package com.ruoyi.system.util;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ShopUserService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -12,6 +13,8 @@ public class AppleNotificationProcessor {
@Autowired @Autowired
private AppleSignedPayloadDecoder payloadDecoder; private AppleSignedPayloadDecoder payloadDecoder;
@Autowired
private ShopUserService shopUserService;
/** /**
* 完整的通知处理流程 * 完整的通知处理流程
@@ -147,6 +150,7 @@ public class AppleNotificationProcessor {
log.info("处理续订事件 - 子类型: {}", notificationInfo.getSubtype()); log.info("处理续订事件 - 子类型: {}", notificationInfo.getSubtype());
if (transactionInfo != null) { if (transactionInfo != null) {
// 找到最近的原始订单数据做校验 ,防止重复校验问题,创建新的订单数据,并调用 shopUserService.updateShopUserVipTime(transactionInfo.getUserId(), "1")
} }
} }

View File

@@ -6,9 +6,13 @@ import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.entity.OrderInfo; import com.ruoyi.common.core.domain.entity.OrderInfo;
import com.ruoyi.common.core.domain.entity.ShopUser;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.OrderInfoMapper;
import com.ruoyi.system.service.IOrderInfoService; import com.ruoyi.system.service.IOrderInfoService;
import com.ruoyi.system.service.ShopUserService;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -21,6 +25,7 @@ import javax.net.ssl.X509TrustManager;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
@@ -41,6 +46,10 @@ public class AppleyPay {
@Autowired @Autowired
private IOrderInfoService orderInfoService; private IOrderInfoService orderInfoService;
@Autowired
private OrderInfoMapper orderInfoMapper;
@Autowired
private ShopUserService shopUserService;
//购买凭证验证地址 //购买凭证验证地址
private static final String certificateUrl = "https://buy.itunes.apple.com/verifyReceipt"; private static final String certificateUrl = "https://buy.itunes.apple.com/verifyReceipt";
@@ -73,20 +82,20 @@ public class AppleyPay {
* @param receipt 苹果传递前端给的值 * @param receipt 苹果传递前端给的值
* @param chooseEnv 是否时测试环境 * @param chooseEnv 是否时测试环境
*/ */
public boolean setIapCertificate(String userId, String receipt, boolean chooseEnv) { public ShopUser setIapCertificate(Long userId, String receipt, OrderInfo orderInfo,boolean chooseEnv) {
log.info("IOS端发送的购买凭证。数据有 userId = {},receipt = {},chooseEnv = {}",userId,receipt,chooseEnv); log.info("IOS端发送的购买凭证。数据有 userId = {},receipt = {},chooseEnv = {}",userId,receipt,chooseEnv);
if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(receipt)) { if (userId == null || StringUtils.isEmpty(receipt)) {
log.error("用户ID 或者 receipt为空"); log.error("用户ID 或者 receipt为空");
return false; return null;
} }
String url = null; String url = null;
url = chooseEnv == true ? certificateUrl : certificateUrlTest; url = chooseEnv == true ? certificateUrl : certificateUrlTest;
final String certificateCode = receipt; final String certificateCode = receipt;
if (StringUtils.isNotEmpty(certificateCode)) { if (StringUtils.isNotEmpty(certificateCode)) {
String s = sendHttpsCoon(url, certificateCode, userId); return sendHttpsCoon(url, certificateCode, userId,orderInfo);
return "支付成功".equals(s);
} else { } else {
return false; log.error("用户ID 或者 receipt为空");
return null;
} }
} }
@@ -104,10 +113,10 @@ public class AppleyPay {
* @param userId 用户ID * @param userId 用户ID
* @return 结果 * @return 结果
*/ */
private String sendHttpsCoon(String url, String code, String userId) { private ShopUser sendHttpsCoon(String url, String code, Long userId, OrderInfo orderParam) {
if (url == null || url.isEmpty()) { if (url == null || url.isEmpty()) {
log.error("验证URL为空"); log.error("验证URL为空");
return "支付失败,验证URL为空"; return null;
} }
try { try {
//设置SSLContext //设置SSLContext
@@ -138,8 +147,8 @@ public class AppleyPay {
//获取输入流 //获取输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
String line = null; String line;
StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
sb.append(line); sb.append(line);
} }
@@ -155,14 +164,14 @@ public class AppleyPay {
if (status == null || status != 0) { if (status == null || status != 0) {
String errorMsg = getStatusErrorMessage(status); String errorMsg = getStatusErrorMessage(status);
log.error("苹果验证失败,状态码: {}, 错误信息: {}", status, errorMsg); log.error("苹果验证失败,状态码: {}, 错误信息: {}", status, errorMsg);
return "支付失败,苹果验证失败: " + errorMsg; return null;
} }
// 获取 latest_receipt_info可能是数组或单个对象 // 获取 latest_receipt_info可能是数组或单个对象
Object latestReceiptInfoObj = alljsoncode.get("latest_receipt_info"); Object latestReceiptInfoObj = alljsoncode.get("latest_receipt_info");
if (latestReceiptInfoObj == null) { if (latestReceiptInfoObj == null) {
log.error("latest_receipt_info 为空"); log.error("latest_receipt_info 为空");
return "支付失败,未找到交易信息"; return null;
} }
// 处理 latest_receipt_info可能是数组或单个对象 // 处理 latest_receipt_info可能是数组或单个对象
@@ -172,7 +181,7 @@ public class AppleyPay {
JSONArray receiptArray = (JSONArray) latestReceiptInfoObj; JSONArray receiptArray = (JSONArray) latestReceiptInfoObj;
if (receiptArray.isEmpty()) { if (receiptArray.isEmpty()) {
log.error("latest_receipt_info 数组为空"); log.error("latest_receipt_info 数组为空");
return "支付失败,交易信息数组为空"; return null;
} }
// 获取最新的交易记录(数组最后一个元素) // 获取最新的交易记录(数组最后一个元素)
Object lastReceipt = receiptArray.get(receiptArray.size() - 1); Object lastReceipt = receiptArray.get(receiptArray.size() - 1);
@@ -184,7 +193,7 @@ public class AppleyPay {
if (latestTransaction == null) { if (latestTransaction == null) {
log.error("无法解析交易信息"); log.error("无法解析交易信息");
return "支付失败,无法解析交易信息"; return null;
} }
// 获取关键信息 // 获取关键信息
@@ -192,9 +201,17 @@ public class AppleyPay {
String productId = latestTransaction.getProductId(); String productId = latestTransaction.getProductId();
String expiresDateMs = latestTransaction.getExpiresDateMs(); String expiresDateMs = latestTransaction.getExpiresDateMs();
// 查询交易信息是否已经存在
OrderInfo selectOrderInfo = orderInfoMapper.selectByTradeNo(transactionId);
if (selectOrderInfo != null){
log.warn("交易ID {} 已存在可能重复处理。用户ID: {}", transactionId, userId);
// 交易信息已存在
return null;
}
if (StringUtils.isEmpty(transactionId)) { if (StringUtils.isEmpty(transactionId)) {
log.error("transaction_id 为空"); log.error("transaction_id 为空");
return "支付失败,交易ID为空"; return null;
} }
// 检查订单是否已处理(防重复发货) // 检查订单是否已处理(防重复发货)
@@ -208,7 +225,7 @@ public class AppleyPay {
OrderInfo existingOrder = existingOrders.get(0); OrderInfo existingOrder = existingOrders.get(0);
if (existingOrder.getPayStatus() != null && existingOrder.getPayStatus() >= 2) { if (existingOrder.getPayStatus() != null && existingOrder.getPayStatus() >= 2) {
log.info("订单已处理返回成功。订单ID: {}, 交易ID: {}", existingOrder.getOrderId(), transactionId); log.info("订单已处理返回成功。订单ID: {}, 交易ID: {}", existingOrder.getOrderId(), transactionId);
return "支付成功"; return shopUserService.selectUserById(userId);
} }
} }
@@ -220,7 +237,7 @@ public class AppleyPay {
if (expiresTimestamp < currentTimestamp) { if (expiresTimestamp < currentTimestamp) {
log.warn("订阅已过期。交易ID: {}, 过期时间: {}, 当前时间: {}", log.warn("订阅已过期。交易ID: {}, 过期时间: {}, 当前时间: {}",
transactionId, new Date(expiresTimestamp), new Date(currentTimestamp)); transactionId, new Date(expiresTimestamp), new Date(currentTimestamp));
return "支付失败,订阅已过期"; return null;
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
log.warn("无法解析过期时间: {}", expiresDateMs); log.warn("无法解析过期时间: {}", expiresDateMs);
@@ -229,83 +246,92 @@ public class AppleyPay {
// 根据产品ID处理不同的订阅类型 // 根据产品ID处理不同的订阅类型
String packageType = null; String packageType = null;
String orderName = null; String orderName;
Long amount = null; // 金额(分) BigDecimal amount; // 金额(分)
// 计算服务开始和结束时间
Date startTime = new Date();
// 创建订单记录
OrderInfo orderInfo = new OrderInfo();
orderInfo.setOrderId(orderParam.getOrderId());
orderInfo.setUserId(userId);
orderInfo.setPayType("applePay");
orderInfo.setPayStatus(2L); // 2-待出货
orderInfo.setPayTime(DateUtils.getNowDate());
orderInfo.setStartTime(startTime);
orderInfo.setTradeNo(transactionId);
orderInfo.setCallbackContent(sb.toString()); // 保存完整的回调内容
orderInfo.setCallTime(DateUtils.getNowDate());
orderInfo.setCallbackContent(transactionId);
orderInfo.setIdDel(0L);
orderInfo.setVersion(1L);
orderInfo.setCreateTime(DateUtils.getNowDate());
orderInfo.setUpdateTime(DateUtils.getNowDate());
if ("com.mingyue.product.month".equals(productId)) { if ("com.mingyue.product.month".equals(productId)) {
// 月付 // 月付
packageType = "1"; packageType = "1";
orderName = "VIP会员包月"; orderName = "VIP会员包月";
amount = 1200L; // 12元 = 1200分 amount = new BigDecimal("268.00"); // 12元 = 1200分
log.info("用户ID{}, 产品:月付订阅", userId); log.info("用户ID{}, 产品:月付订阅", userId);
orderInfo.setAmount(amount);
orderInfo.setOrderName(orderName);
Date endTime = calculateEndTime(startTime, packageType);
orderInfo.setEndTime(endTime);
orderInfo.setPackageType(packageType);
orderInfoService.updateOrderInfo(orderInfo);
return shopUserService.updateShopUserVipTime(userId, "1");
} else if ("com.mingyue.product.quarterly".equals(productId)) { } else if ("com.mingyue.product.quarterly".equals(productId)) {
// 季付 // 季付
packageType = "2"; packageType = "2";
orderName = "VIP会员包季度"; orderName = "VIP会员包季度";
amount = 3000L; // 30元 = 3000分 amount = new BigDecimal("70.00"); // 30元 = 3000分
log.info("用户ID{}, 产品:季付订阅", userId); log.info("用户ID{}, 产品:季付订阅", userId);
Date endTime = calculateEndTime(startTime, packageType);
orderInfo.setAmount(amount);
orderInfo.setOrderName(orderName);
orderInfo.setEndTime(endTime);
orderInfo.setPackageType(packageType);
orderInfoService.updateOrderInfo(orderInfo);
return shopUserService.updateShopUserVipTime(userId, "2");
} else if ("com.mingyue.product.semiAnnual".equals(productId)) { } else if ("com.mingyue.product.semiAnnual".equals(productId)) {
// 半年付 // 半年付
packageType = "3"; packageType = "3";
orderName = "VIP会员包半年"; orderName = "VIP会员包半年";
amount = 6000L; // 60元 = 6000分假设 amount = new BigDecimal("135.00"); // 60元 = 6000分假设
log.info("用户ID{}, 产品:半年付订阅", userId); log.info("用户ID{}, 产品:半年付订阅", userId);
Date endTime = calculateEndTime(startTime, packageType);
orderInfo.setAmount(amount);
orderInfo.setOrderName(orderName);
orderInfo.setEndTime(endTime);
orderInfo.setPackageType(packageType);
orderInfoService.updateOrderInfo(orderInfo);
return shopUserService.updateShopUserVipTime(userId, "3");
} else if ("com.mingyue.product.annual".equals(productId)) { } else if ("com.mingyue.product.annual".equals(productId)) {
// 年付 // 年付
packageType = "4"; packageType = "4";
orderName = "VIP会员包年"; orderName = "VIP会员包年";
amount = 12000L; // 120元 = 12000分假设 amount = new BigDecimal("18.00"); // 120元 = 12000分假设
log.info("用户ID{}, 产品:年付订阅", userId); log.info("用户ID{}, 产品:年付订阅", userId);
} else {
log.error("用户ID{}, 未知的产品ID: {}", userId, productId);
return "支付失败,未知的产品ID: " + productId;
}
// 创建或更新订单
try {
// 计算服务开始和结束时间
Date startTime = new Date();
Date endTime = calculateEndTime(startTime, packageType);
// 创建订单记录
OrderInfo orderInfo = new OrderInfo();
orderInfo.setId(java.util.UUID.randomUUID().toString().replace("-", ""));
orderInfo.setOrderId(System.currentTimeMillis());
orderInfo.setOrderName(orderName);
orderInfo.setUserId(Long.parseLong(userId));
orderInfo.setAmount(amount); orderInfo.setAmount(amount);
orderInfo.setPayType("applePay"); orderInfo.setOrderName(orderName);
orderInfo.setPayStatus(2L); // 2-待出货 Date endTime = calculateEndTime(startTime, packageType);
orderInfo.setPayTime(DateUtils.getNowDate());
orderInfo.setStartTime(startTime);
orderInfo.setEndTime(endTime); orderInfo.setEndTime(endTime);
orderInfo.setPackageType(packageType); orderInfo.setPackageType(packageType);
orderInfo.setTradeNo(transactionId); orderInfoService.updateOrderInfo(orderInfo);
orderInfo.setCallbackContent(sb.toString()); // 保存完整的回调内容 return shopUserService.updateShopUserVipTime(userId, "4");
orderInfo.setCallTime(DateUtils.getNowDate()); } else {
orderInfo.setIdDel(0L); log.error("用户ID{}, 未知的产品ID: {}", userId, productId);
orderInfo.setVersion(1L); return null;
orderInfo.setCreateTime(DateUtils.getNowDate());
orderInfo.setUpdateTime(DateUtils.getNowDate());
// 保存订单
int result = orderInfoService.insertOrderInfo(orderInfo);
if (result > 0) {
log.info("订单创建成功。订单ID: {}, 交易ID: {}, 用户ID: {}, 产品: {}",
orderInfo.getOrderId(), transactionId, userId, productId);
return "支付成功";
} else {
log.error("订单创建失败。交易ID: {}, 用户ID: {}", transactionId, userId);
return "支付失败,订单创建失败";
}
} catch (Exception e) {
log.error("创建订单异常。交易ID: {}, 用户ID: {}, 异常: {}", transactionId, userId, e.getMessage(), e);
return "支付失败,订单创建异常: " + e.getMessage();
} }
} catch (Exception e) { } catch (Exception e) {
log.error("向苹果发起验证支付请求是否有效出现异常:{}", e.getMessage(), e); log.error("向苹果发起验证支付请求是否有效出现异常:{}", e.getMessage(), e);
return "支付过程中,出现了异常: " + e.getMessage(); return null;
} }
} }
@@ -324,13 +350,13 @@ public class AppleyPay {
case "1": // 月付 case "1": // 月付
calendar.add(Calendar.MONTH, 1); calendar.add(Calendar.MONTH, 1);
break; break;
case "3": // 季付 case "2": // 季付
calendar.add(Calendar.MONTH, 3); calendar.add(Calendar.MONTH, 3);
break; break;
case "6": // 半年付 case "3": // 半年付
calendar.add(Calendar.MONTH, 6); calendar.add(Calendar.MONTH, 6);
break; break;
case "12": // 年付 case "4": // 年付
calendar.add(Calendar.YEAR, 1); calendar.add(Calendar.YEAR, 1);
break; break;
default: default:

View File

@@ -219,4 +219,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where> </where>
ORDER BY o.create_time DESC ORDER BY o.create_time DESC
</select> </select>
<select id="selectByTradeNo" resultMap="OrderInfoResult">
SELECT * FROM order_info WHERE trade_no = #{tradeNo}
</select>
</mapper> </mapper>