apple支付部分逻辑
This commit is contained in:
@@ -2,13 +2,16 @@ package com.ruoyi.web.controller.back;
|
|||||||
|
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.ruoyi.common.utils.http.HttpUtils;
|
import com.ruoyi.common.utils.http.HttpUtils;
|
||||||
|
import com.ruoyi.system.util.AppleNotificationProcessor;
|
||||||
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.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述:
|
* 描述:
|
||||||
@@ -19,10 +22,23 @@ import java.util.Map;
|
|||||||
@RestController
|
@RestController
|
||||||
public class CallBackController {
|
public class CallBackController {
|
||||||
private static final Logger log = LoggerFactory.getLogger(CallBackController.class);
|
private static final Logger log = LoggerFactory.getLogger(CallBackController.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AppleNotificationProcessor notificationProcessor;
|
||||||
|
|
||||||
@RequestMapping("/ios")
|
@RequestMapping("/ios")
|
||||||
public void iosCallBack(@RequestBody Map<String,Object> param){
|
public void iosCallBack(@RequestBody String notificationBody) {
|
||||||
System.out.println(param);
|
//System.out.println(notificationBody);
|
||||||
log.info("ios 回调参数:{}", JSONUtil.toJsonStr( param));
|
//log.info("ios 回调参数:{}", JSONUtil.toJsonStr(notificationBody));
|
||||||
|
try {
|
||||||
|
// 异步处理,避免超时
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
notificationProcessor.processSignedPayload(notificationBody);
|
||||||
|
});
|
||||||
|
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("处理iOS回调异常: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ public class ClientOrderInfoController extends BaseController
|
|||||||
// 获取客户端IP
|
// 获取客户端IP
|
||||||
String clientIp = getClientIp(httpRequest);
|
String clientIp = getClientIp(httpRequest);
|
||||||
request.setClientIp(clientIp);
|
request.setClientIp(clientIp);
|
||||||
|
|
||||||
return orderInfoService.createOrder(request);
|
return orderInfoService.createOrder(request);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return AjaxResult.error("创建订单失败: " + e.getMessage());
|
return AjaxResult.error("创建订单失败: " + e.getMessage());
|
||||||
|
|||||||
@@ -67,21 +67,21 @@ spring:
|
|||||||
enabled: true
|
enabled: true
|
||||||
# redis 配置
|
# redis 配置
|
||||||
redis:
|
redis:
|
||||||
# host: 116.204.124.80
|
host: 116.204.124.80
|
||||||
# # 端口,默认为6379
|
|
||||||
# port: 16379
|
|
||||||
# # 数据库索引
|
|
||||||
# database: 0
|
|
||||||
# # 密码
|
|
||||||
# password: Lwz19520416443@
|
|
||||||
# # 地址
|
|
||||||
host: 127.0.0.1
|
|
||||||
# 端口,默认为6379
|
# 端口,默认为6379
|
||||||
port: 6379
|
port: 16379
|
||||||
# 数据库索引
|
# 数据库索引
|
||||||
database: 0
|
database: 0
|
||||||
# 密码
|
# 密码
|
||||||
password:
|
password: Lwz19520416443@
|
||||||
|
# # 地址
|
||||||
|
# host: 127.0.0.1
|
||||||
|
# # 端口,默认为6379
|
||||||
|
# port: 6379
|
||||||
|
# # 数据库索引
|
||||||
|
# database: 0
|
||||||
|
# # 密码
|
||||||
|
# password:
|
||||||
# 连接超时时间
|
# 连接超时时间
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
lettuce:
|
lettuce:
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class OrderCreateRequest implements Serializable {
|
|||||||
/** 支付方式 aliPay/wechatPay/applePay */
|
/** 支付方式 aliPay/wechatPay/applePay */
|
||||||
private String payType;
|
private String payType;
|
||||||
|
|
||||||
/** 套餐类型 1包月 3包季度 6半年 12一年 */
|
/** 套餐类型 1 包月 2 包季度 3 半年 4 一年 */
|
||||||
private String packageType;
|
private String packageType;
|
||||||
|
|
||||||
/** 设备类型 android/ios */
|
/** 设备类型 android/ios */
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.ruoyi.common.core.domain.entity;
|
|||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import com.ruoyi.common.annotation.Excel;
|
import com.ruoyi.common.annotation.Excel;
|
||||||
@@ -13,6 +14,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
|
|||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
* @date 2025-08-03
|
* @date 2025-08-03
|
||||||
*/
|
*/
|
||||||
|
@Data
|
||||||
public class OrderInfo extends BaseEntity
|
public class OrderInfo extends BaseEntity
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -100,232 +102,4 @@ public class OrderInfo extends BaseEntity
|
|||||||
/** 乐观锁版本号 */
|
/** 乐观锁版本号 */
|
||||||
@Excel(name = "乐观锁版本号")
|
@Excel(name = "乐观锁版本号")
|
||||||
private Long version;
|
private Long version;
|
||||||
|
|
||||||
public void setId(String id)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId()
|
|
||||||
{
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOrderId(Long orderId)
|
|
||||||
{
|
|
||||||
this.orderId = orderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getOrderId()
|
|
||||||
{
|
|
||||||
return orderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOrderName(String orderName)
|
|
||||||
{
|
|
||||||
this.orderName = orderName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOrderName()
|
|
||||||
{
|
|
||||||
return orderName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserId(Long userId)
|
|
||||||
{
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getUserId()
|
|
||||||
{
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAmount(Long amount)
|
|
||||||
{
|
|
||||||
this.amount = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getAmount()
|
|
||||||
{
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPayType(String payType)
|
|
||||||
{
|
|
||||||
this.payType = payType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPayType()
|
|
||||||
{
|
|
||||||
return payType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPayTime(Date payTime)
|
|
||||||
{
|
|
||||||
this.payTime = payTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getPayTime()
|
|
||||||
{
|
|
||||||
return payTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPayStatus(Long payStatus)
|
|
||||||
{
|
|
||||||
this.payStatus = payStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getPayStatus()
|
|
||||||
{
|
|
||||||
return payStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStartTime(Date startTime)
|
|
||||||
{
|
|
||||||
this.startTime = startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getStartTime()
|
|
||||||
{
|
|
||||||
return startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEndTime(Date endTime)
|
|
||||||
{
|
|
||||||
this.endTime = endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getEndTime()
|
|
||||||
{
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIdDel(Long idDel)
|
|
||||||
{
|
|
||||||
this.idDel = idDel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getIdDel()
|
|
||||||
{
|
|
||||||
return idDel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCallTime(Date callTime)
|
|
||||||
{
|
|
||||||
this.callTime = callTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getCallTime()
|
|
||||||
{
|
|
||||||
return callTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPackageType(String packageType)
|
|
||||||
{
|
|
||||||
this.packageType = packageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPackageType()
|
|
||||||
{
|
|
||||||
return packageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCallbackContent(String callbackContent)
|
|
||||||
{
|
|
||||||
this.callbackContent = callbackContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCallbackContent()
|
|
||||||
{
|
|
||||||
return callbackContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTradeNo(String tradeNo)
|
|
||||||
{
|
|
||||||
this.tradeNo = tradeNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTradeNo()
|
|
||||||
{
|
|
||||||
return tradeNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRefundAmount(Long refundAmount)
|
|
||||||
{
|
|
||||||
this.refundAmount = refundAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getRefundAmount()
|
|
||||||
{
|
|
||||||
return refundAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRefundTime(Date refundTime)
|
|
||||||
{
|
|
||||||
this.refundTime = refundTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getRefundTime()
|
|
||||||
{
|
|
||||||
return refundTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClientIp(String clientIp)
|
|
||||||
{
|
|
||||||
this.clientIp = clientIp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientIp()
|
|
||||||
{
|
|
||||||
return clientIp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeviceType(String deviceType)
|
|
||||||
{
|
|
||||||
this.deviceType = deviceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDeviceType()
|
|
||||||
{
|
|
||||||
return deviceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVersion(Long version)
|
|
||||||
{
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getVersion()
|
|
||||||
{
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
|
||||||
.append("id", getId())
|
|
||||||
.append("orderId", getOrderId())
|
|
||||||
.append("orderName", getOrderName())
|
|
||||||
.append("userId", getUserId())
|
|
||||||
.append("amount", getAmount())
|
|
||||||
.append("payType", getPayType())
|
|
||||||
.append("payTime", getPayTime())
|
|
||||||
.append("payStatus", getPayStatus())
|
|
||||||
.append("startTime", getStartTime())
|
|
||||||
.append("endTime", getEndTime())
|
|
||||||
.append("createTime", getCreateTime())
|
|
||||||
.append("idDel", getIdDel())
|
|
||||||
.append("updateTime", getUpdateTime())
|
|
||||||
.append("callTime", getCallTime())
|
|
||||||
.append("packageType", getPackageType())
|
|
||||||
.append("callbackContent", getCallbackContent())
|
|
||||||
.append("tradeNo", getTradeNo())
|
|
||||||
.append("refundAmount", getRefundAmount())
|
|
||||||
.append("refundTime", getRefundTime())
|
|
||||||
.append("clientIp", getClientIp())
|
|
||||||
.append("deviceType", getDeviceType())
|
|
||||||
.append("version", getVersion())
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.ruoyi.common.core.domain.entity;
|
|||||||
import java.math.BigDecimal;
|
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 org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import com.ruoyi.common.annotation.Excel;
|
import com.ruoyi.common.annotation.Excel;
|
||||||
@@ -14,6 +15,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
|
|||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
* @date 2025-10-27
|
* @date 2025-10-27
|
||||||
*/
|
*/
|
||||||
|
@Data
|
||||||
public class Product extends BaseEntity
|
public class Product extends BaseEntity
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -35,7 +37,7 @@ public class Product extends BaseEntity
|
|||||||
|
|
||||||
/** 分类ID */
|
/** 分类ID */
|
||||||
@Excel(name = "分类ID")
|
@Excel(name = "分类ID")
|
||||||
private Long categoryId;
|
private String categoryId;
|
||||||
|
|
||||||
/** 商品类型:1-包月,2-包季,3-半年 */
|
/** 商品类型:1-包月,2-包季,3-半年 */
|
||||||
@Excel(name = "商品类型:1-包月,2-包季,3-半年 ")
|
@Excel(name = "商品类型:1-包月,2-包季,3-半年 ")
|
||||||
@@ -79,174 +81,4 @@ public class Product extends BaseEntity
|
|||||||
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
|
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||||
private Date updatedAt;
|
private Date updatedAt;
|
||||||
|
|
||||||
public void setId(String id)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId()
|
|
||||||
{
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProductId(Long productId)
|
|
||||||
{
|
|
||||||
this.productId = productId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getProductId()
|
|
||||||
{
|
|
||||||
return productId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name)
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description)
|
|
||||||
{
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription()
|
|
||||||
{
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCategoryId(Long categoryId)
|
|
||||||
{
|
|
||||||
this.categoryId = categoryId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getCategoryId()
|
|
||||||
{
|
|
||||||
return categoryId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProductType(Integer productType)
|
|
||||||
{
|
|
||||||
this.productType = productType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getProductType()
|
|
||||||
{
|
|
||||||
return productType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(Integer status)
|
|
||||||
{
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getStatus()
|
|
||||||
{
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOriginalPrice(BigDecimal originalPrice)
|
|
||||||
{
|
|
||||||
this.originalPrice = originalPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BigDecimal getOriginalPrice()
|
|
||||||
{
|
|
||||||
return originalPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrentPrice(BigDecimal currentPrice)
|
|
||||||
{
|
|
||||||
this.currentPrice = currentPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BigDecimal getCurrentPrice()
|
|
||||||
{
|
|
||||||
return currentPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMonthlyDuration(Long monthlyDuration)
|
|
||||||
{
|
|
||||||
this.monthlyDuration = monthlyDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getMonthlyDuration()
|
|
||||||
{
|
|
||||||
return monthlyDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setQuarterlyDuration(Long quarterlyDuration)
|
|
||||||
{
|
|
||||||
this.quarterlyDuration = quarterlyDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getQuarterlyDuration()
|
|
||||||
{
|
|
||||||
return quarterlyDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStock(Long stock)
|
|
||||||
{
|
|
||||||
this.stock = stock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getStock()
|
|
||||||
{
|
|
||||||
return stock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSales(Long sales)
|
|
||||||
{
|
|
||||||
this.sales = sales;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getSales()
|
|
||||||
{
|
|
||||||
return sales;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreatedAt(Date createdAt)
|
|
||||||
{
|
|
||||||
this.createdAt = createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getCreatedAt()
|
|
||||||
{
|
|
||||||
return createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpdatedAt(Date updatedAt)
|
|
||||||
{
|
|
||||||
this.updatedAt = updatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getUpdatedAt()
|
|
||||||
{
|
|
||||||
return updatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
|
||||||
.append("id", getId())
|
|
||||||
.append("productId", getProductId())
|
|
||||||
.append("name", getName())
|
|
||||||
.append("description", getDescription())
|
|
||||||
.append("categoryId", getCategoryId())
|
|
||||||
.append("productType", getProductType())
|
|
||||||
.append("status", getStatus())
|
|
||||||
.append("originalPrice", getOriginalPrice())
|
|
||||||
.append("currentPrice", getCurrentPrice())
|
|
||||||
.append("monthlyDuration", getMonthlyDuration())
|
|
||||||
.append("quarterlyDuration", getQuarterlyDuration())
|
|
||||||
.append("stock", getStock())
|
|
||||||
.append("sales", getSales())
|
|
||||||
.append("createdAt", getCreatedAt())
|
|
||||||
.append("updatedAt", getUpdatedAt())
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,8 @@ public class SecurityConfig
|
|||||||
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
|
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
|
||||||
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
||||||
//"/client/**","/back/**"
|
//"/client/**","/back/**"
|
||||||
requests.antMatchers("/login", "/register","/client/shopLogin","/file/download/**", "/captchaImage","/client/getCode","/back/**","/client/file/**").permitAll()
|
requests.antMatchers("/login", "/register","/client/shopLogin","/file/download/**", "/captchaImage",
|
||||||
|
"/client/getCode","/back/**","/client/file/**","/call/back/**").permitAll()
|
||||||
// 静态资源,可匿名访问
|
// 静态资源,可匿名访问
|
||||||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
|
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
|
||||||
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
||||||
|
|||||||
@@ -23,6 +23,13 @@
|
|||||||
<artifactId>ruoyi-common</artifactId>
|
<artifactId>ruoyi-common</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.38</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -13,6 +13,7 @@ import com.ruoyi.common.utils.SecurityUtils;
|
|||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.system.mapper.OrderInfoMapper;
|
import com.ruoyi.system.mapper.OrderInfoMapper;
|
||||||
import com.ruoyi.system.service.IOrderInfoService;
|
import com.ruoyi.system.service.IOrderInfoService;
|
||||||
|
import com.ruoyi.system.util.AppleyPay;
|
||||||
import com.ruoyi.system.util.PaymentUtil;
|
import com.ruoyi.system.util.PaymentUtil;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -174,15 +175,20 @@ 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:// 待修改
|
||||||
|
processPayment(orderInfo, request);
|
||||||
|
|
||||||
|
boolean paymentResult = true;
|
||||||
|
|
||||||
|
if (paymentResult){
|
||||||
|
return AjaxResult.success("支付请求成功");
|
||||||
|
}else {
|
||||||
|
return AjaxResult.error("支付请求失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用第三方支付接口
|
|
||||||
Map<String, Object> paymentResult = processPayment(orderInfo, request);
|
|
||||||
|
|
||||||
return AjaxResult.success("支付请求成功", paymentResult);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return AjaxResult.error("支付异常: " + e.getMessage());
|
return AjaxResult.error("支付异常: " + e.getMessage());
|
||||||
}
|
}
|
||||||
@@ -336,22 +342,29 @@ public class OrderInfoServiceImpl implements IOrderInfoService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AppleyPay appleyPay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理支付过程
|
* 处理支付过程
|
||||||
*/
|
*/
|
||||||
private Map<String, Object> processPayment(OrderInfo orderInfo, PaymentRequest request) {
|
private boolean processPayment(OrderInfo orderInfo, PaymentRequest request) {
|
||||||
|
String payType = orderInfo.getPayType();
|
||||||
// 根据支付方式调用相应的支付接口
|
// 根据支付方式调用相应的支付接口
|
||||||
switch (request.getPayType()) {
|
switch (payType) {
|
||||||
case "aliPay":
|
case "aliPay":
|
||||||
return paymentUtil.processAliPay(orderInfo, request);
|
//return paymentUtil.processAliPay(orderInfo, request);
|
||||||
|
return false;
|
||||||
case "wechatPay":
|
case "wechatPay":
|
||||||
return paymentUtil.processWechatPay(orderInfo, request);
|
//return paymentUtil.processWechatPay(orderInfo, request);
|
||||||
|
return false;
|
||||||
case "applePay":
|
case "applePay":
|
||||||
return paymentUtil.processApplePay(orderInfo, request);
|
return appleyPay.setIapCertificate(String.valueOf(orderInfo.getUserId()), request.getPaymentToken(), false);
|
||||||
default:
|
default:
|
||||||
Map<String, Object> errorResult = new HashMap<>();
|
Map<String, Object> errorResult = new HashMap<>();
|
||||||
errorResult.put("error", "不支持的支付方式");
|
errorResult.put("error", "不支持的支付方式");
|
||||||
return errorResult;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,226 @@
|
|||||||
|
package com.ruoyi.system.util;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class AppleNotificationProcessor {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AppleSignedPayloadDecoder payloadDecoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完整的通知处理流程
|
||||||
|
*/
|
||||||
|
public void processSignedPayload(String signedPayload) {
|
||||||
|
try {
|
||||||
|
// 1. 解码
|
||||||
|
JSONObject payload = payloadDecoder.decodeSignedPayload(signedPayload);
|
||||||
|
if (payload == null) {
|
||||||
|
log.error("Payload解码失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 提取各种信息
|
||||||
|
NotificationInfo notificationInfo = payloadDecoder.extractNotificationInfo(payload);
|
||||||
|
TransactionInfo transactionInfo = payloadDecoder.extractTransactionInfo(notificationInfo.getData());
|
||||||
|
RenewalInfo renewalInfo = payloadDecoder.extractRenewalInfo(notificationInfo.getData());
|
||||||
|
|
||||||
|
// 3. 记录日志
|
||||||
|
logNotificationDetails(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
|
||||||
|
// 4. 业务处理
|
||||||
|
processBusinessLogic(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理通知完整流程异常: {}", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录详细的通知信息
|
||||||
|
*/
|
||||||
|
private void logNotificationDetails(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
|
||||||
|
log.info("=== 苹果通知详情 ===");
|
||||||
|
log.info("通知类型: {}, 子类型: {}",
|
||||||
|
notificationInfo.getNotificationType(),
|
||||||
|
notificationInfo.getSubtype());
|
||||||
|
log.info("通知UUID: {}, 版本: {}",
|
||||||
|
notificationInfo.getNotificationUUID(),
|
||||||
|
notificationInfo.getVersion());
|
||||||
|
|
||||||
|
if (transactionInfo != null) {
|
||||||
|
log.info("交易信息 - 原始ID: {}, 产品: {}",
|
||||||
|
transactionInfo.getOriginalTransactionId(),
|
||||||
|
transactionInfo.getProductId());
|
||||||
|
log.info("购买时间: {}, 过期时间: {}",
|
||||||
|
transactionInfo.getPurchaseDate(),
|
||||||
|
transactionInfo.getExpiresDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renewalInfo != null) {
|
||||||
|
log.info("续订信息 - 自动续订状态: {}, 续订产品: {}",
|
||||||
|
renewalInfo.getAutoRenewStatus(),
|
||||||
|
renewalInfo.getAutoRenewProductId());
|
||||||
|
}
|
||||||
|
log.info("=== 通知详情结束 ===");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务逻辑处理
|
||||||
|
*/
|
||||||
|
private void processBusinessLogic(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
|
||||||
|
String notificationType = notificationInfo.getNotificationType();
|
||||||
|
String originalTransactionId = getOriginalTransactionId(transactionInfo, renewalInfo);
|
||||||
|
|
||||||
|
// 根据通知类型路由到不同的处理方法
|
||||||
|
switch (notificationType) {
|
||||||
|
case "SUBSCRIBED":
|
||||||
|
handleSubscriptionEvent(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
break;
|
||||||
|
case "DID_RENEW":
|
||||||
|
handleRenewalEvent(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
break;
|
||||||
|
case "DID_FAIL_TO_RENEW":
|
||||||
|
handleRenewalFailureEvent(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
break;
|
||||||
|
case "DID_CHANGE_RENEWAL_PREF":
|
||||||
|
handleRenewalPreferenceChange(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
break;
|
||||||
|
case "DID_CHANGE_RENEWAL_STATUS":
|
||||||
|
handleRenewalStatusChange(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
break;
|
||||||
|
case "OFFER_REDEEMED":
|
||||||
|
handleOfferRedeemed(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
break;
|
||||||
|
case "EXPIRED":
|
||||||
|
handleExpiredEvent(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
break;
|
||||||
|
case "REFUND":
|
||||||
|
handleRefundEvent(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
break;
|
||||||
|
case "REVOKE":
|
||||||
|
handleRevokeEvent(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
break;
|
||||||
|
case "GRACE_PERIOD_EXPIRED":
|
||||||
|
handleGracePeriodExpired(notificationInfo, transactionInfo, renewalInfo);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.warn("未处理的通知类型: {}", notificationType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getOriginalTransactionId(TransactionInfo transactionInfo, RenewalInfo renewalInfo) {
|
||||||
|
if (transactionInfo != null && StringUtils.isNotEmpty(transactionInfo.getOriginalTransactionId())) {
|
||||||
|
return transactionInfo.getOriginalTransactionId();
|
||||||
|
}
|
||||||
|
if (renewalInfo != null && StringUtils.isNotEmpty(renewalInfo.getOriginalTransactionId())) {
|
||||||
|
return renewalInfo.getOriginalTransactionId();
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体的业务处理方法
|
||||||
|
private void handleSubscriptionEvent(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
log.info("处理订阅事件 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
|
if (transactionInfo != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRenewalEvent(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
log.info("处理续订事件 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
|
if (transactionInfo != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRenewalFailureEvent(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
log.warn("处理续订失败事件 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
|
String transactionId = getOriginalTransactionId(transactionInfo, renewalInfo);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRenewalPreferenceChange(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
log.info("处理续订偏好变更 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
|
if (renewalInfo != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRenewalStatusChange(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
log.info("处理续订状态变更 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
|
if (renewalInfo != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleOfferRedeemed(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
log.info("处理优惠兑换 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
|
// TODO: 处理优惠兑换逻辑
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleExpiredEvent(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
log.warn("处理过期事件 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
|
String transactionId = getOriginalTransactionId(transactionInfo, renewalInfo);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRefundEvent(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
log.warn("处理退款事件 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
|
String transactionId = getOriginalTransactionId(transactionInfo, renewalInfo);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRevokeEvent(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
log.warn("处理权益撤销事件 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
|
String transactionId = getOriginalTransactionId(transactionInfo, renewalInfo);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleGracePeriodExpired(NotificationInfo notificationInfo,
|
||||||
|
TransactionInfo transactionInfo,
|
||||||
|
RenewalInfo renewalInfo) {
|
||||||
|
log.warn("处理宽限期过期事件 - 子类型: {}", notificationInfo.getSubtype());
|
||||||
|
|
||||||
|
String transactionId = getOriginalTransactionId(transactionInfo, renewalInfo);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
package com.ruoyi.system.util;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AppleSignedPayloadDecoder {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AppleSignedPayloadDecoder.class);
|
||||||
|
/**
|
||||||
|
* 直接解码Signed Payload,无需公钥验证
|
||||||
|
*/
|
||||||
|
public JSONObject decodeSignedPayload(String signedPayload) {
|
||||||
|
try {
|
||||||
|
log.info("开始解码Signed Payload");
|
||||||
|
|
||||||
|
// 1. 直接解码JWT(不验证签名)
|
||||||
|
String[] parts = signedPayload.split("\\.");
|
||||||
|
if (parts.length != 3) {
|
||||||
|
log.error("Invalid JWT format");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 解码Payload部分
|
||||||
|
String payloadJson = decodeBase64Url(parts[1]);
|
||||||
|
JSONObject payload = JSON.parseObject(payloadJson);
|
||||||
|
|
||||||
|
log.info("解码成功 - 通知类型: {}", payload.getString("notificationType"));
|
||||||
|
return payload;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解码Signed Payload异常: {}", e.getMessage(), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64URL解码
|
||||||
|
*/
|
||||||
|
private String decodeBase64Url(String base64Url) {
|
||||||
|
try {
|
||||||
|
// 将Base64URL转换为标准Base64
|
||||||
|
String base64 = base64Url.replace('-', '+').replace('_', '/');
|
||||||
|
|
||||||
|
// 添加padding
|
||||||
|
switch (base64.length() % 4) {
|
||||||
|
case 2: base64 += "=="; break;
|
||||||
|
case 3: base64 += "="; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] decodedBytes = Base64.getDecoder().decode(base64);
|
||||||
|
return new String(decodedBytes, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Base64URL解码失败: {}", e.getMessage());
|
||||||
|
throw new RuntimeException("Base64解码失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取关键通知信息
|
||||||
|
*/
|
||||||
|
public NotificationInfo extractNotificationInfo(JSONObject payload) {
|
||||||
|
NotificationInfo info = new NotificationInfo();
|
||||||
|
|
||||||
|
info.setNotificationType(payload.getString("notificationType"));
|
||||||
|
info.setSubtype(payload.getString("subtype"));
|
||||||
|
info.setNotificationUUID(payload.getString("notificationUUID"));
|
||||||
|
info.setVersion(payload.getString("version"));
|
||||||
|
info.setData(payload.getJSONObject("data"));
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从data中提取交易信息
|
||||||
|
*/
|
||||||
|
public TransactionInfo extractTransactionInfo(JSONObject data) {
|
||||||
|
try {
|
||||||
|
if (data == null) return null;
|
||||||
|
|
||||||
|
String signedTransactionInfo = data.getString("signedTransactionInfo");
|
||||||
|
if (StringUtils.isEmpty(signedTransactionInfo)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解码交易信息JWT
|
||||||
|
String[] transactionParts = signedTransactionInfo.split("\\.");
|
||||||
|
if (transactionParts.length != 3) return null;
|
||||||
|
|
||||||
|
String transactionPayload = decodeBase64Url(transactionParts[1]);
|
||||||
|
JSONObject transactionJson = JSON.parseObject(transactionPayload);
|
||||||
|
|
||||||
|
TransactionInfo transactionInfo = new TransactionInfo();
|
||||||
|
transactionInfo.setOriginalTransactionId(transactionJson.getString("originalTransactionId"));
|
||||||
|
transactionInfo.setTransactionId(transactionJson.getString("transactionId"));
|
||||||
|
transactionInfo.setProductId(transactionJson.getString("productId"));
|
||||||
|
transactionInfo.setPurchaseDate(transactionJson.getString("purchaseDate"));
|
||||||
|
transactionInfo.setExpiresDate(transactionJson.getString("expiresDate"));
|
||||||
|
transactionInfo.setOriginalPurchaseDate(transactionJson.getString("originalPurchaseDate"));
|
||||||
|
|
||||||
|
return transactionInfo;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("提取交易信息异常: {}", e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从data中提取续订信息
|
||||||
|
*/
|
||||||
|
public RenewalInfo extractRenewalInfo(JSONObject data) {
|
||||||
|
try {
|
||||||
|
if (data == null) return null;
|
||||||
|
|
||||||
|
String signedRenewalInfo = data.getString("signedRenewalInfo");
|
||||||
|
if (StringUtils.isEmpty(signedRenewalInfo)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解码续订信息JWT
|
||||||
|
String[] renewalParts = signedRenewalInfo.split("\\.");
|
||||||
|
if (renewalParts.length != 3) return null;
|
||||||
|
|
||||||
|
String renewalPayload = decodeBase64Url(renewalParts[1]);
|
||||||
|
JSONObject renewalJson = JSON.parseObject(renewalPayload);
|
||||||
|
|
||||||
|
RenewalInfo renewalInfo = new RenewalInfo();
|
||||||
|
renewalInfo.setOriginalTransactionId(renewalJson.getString("originalTransactionId"));
|
||||||
|
renewalInfo.setAutoRenewStatus(renewalJson.getString("autoRenewStatus"));
|
||||||
|
renewalInfo.setProductId(renewalJson.getString("productId"));
|
||||||
|
renewalInfo.setAutoRenewProductId(renewalJson.getString("autoRenewProductId"));
|
||||||
|
|
||||||
|
return renewalInfo;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("提取续订信息异常: {}", e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,108 @@
|
|||||||
|
package com.ruoyi.system.util;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述:
|
||||||
|
*
|
||||||
|
* @author MXP by 2025/11/6
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InAppTransaction {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购买数量
|
||||||
|
*/
|
||||||
|
private String quantity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产品ID
|
||||||
|
*/
|
||||||
|
private String productId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 交易ID
|
||||||
|
*/
|
||||||
|
private String transactionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始交易ID(对于订阅,整个订阅周期保持不变)
|
||||||
|
*/
|
||||||
|
private String originalTransactionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购买日期(字符串格式)
|
||||||
|
*/
|
||||||
|
private String purchaseDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购买日期(时间戳毫秒)
|
||||||
|
*/
|
||||||
|
private String purchaseDateMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购买日期(太平洋时间)
|
||||||
|
*/
|
||||||
|
private String purchaseDatePst;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始购买日期(字符串格式)
|
||||||
|
*/
|
||||||
|
private String originalPurchaseDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始购买日期(时间戳毫秒)
|
||||||
|
*/
|
||||||
|
private String originalPurchaseDateMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始购买日期(太平洋时间)
|
||||||
|
*/
|
||||||
|
private String originalPurchaseDatePst;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过期日期(字符串格式)- 仅订阅有效
|
||||||
|
*/
|
||||||
|
private String expiresDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过期日期(时间戳毫秒)- 仅订阅有效
|
||||||
|
*/
|
||||||
|
private String expiresDateMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过期日期(太平洋时间)- 仅订阅有效
|
||||||
|
*/
|
||||||
|
private String expiresDatePst;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web订单行项目ID
|
||||||
|
*/
|
||||||
|
private String webOrderLineItemId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否试用期
|
||||||
|
*/
|
||||||
|
private String isTrialPeriod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否在介绍优惠期
|
||||||
|
*/
|
||||||
|
private String isInIntroOfferPeriod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用内购买所有权类型
|
||||||
|
*/
|
||||||
|
private String inAppOwnershipType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订阅组标识符
|
||||||
|
*/
|
||||||
|
private String subscriptionGroupIdentifier;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.ruoyi.system.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述:
|
||||||
|
*
|
||||||
|
* @author MXP by 2025/11/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知信息DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
class NotificationInfo {
|
||||||
|
private String notificationType;
|
||||||
|
private String subtype;
|
||||||
|
private String notificationUUID;
|
||||||
|
private String version;
|
||||||
|
private JSONObject data;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.ruoyi.system.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述:
|
||||||
|
*
|
||||||
|
* @author MXP by 2025/11/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 续订信息DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
class RenewalInfo {
|
||||||
|
private String originalTransactionId;
|
||||||
|
private String autoRenewStatus;
|
||||||
|
private String productId;
|
||||||
|
private String autoRenewProductId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.ruoyi.system.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述:
|
||||||
|
*
|
||||||
|
* @author MXP by 2025/11/6
|
||||||
|
*/
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 交易信息DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
class TransactionInfo {
|
||||||
|
private String originalTransactionId;
|
||||||
|
private String transactionId;
|
||||||
|
private String productId;
|
||||||
|
private String purchaseDate;
|
||||||
|
private String expiresDate;
|
||||||
|
private String originalPurchaseDate;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user