fix: Apple IAP attach 支持家庭成员购买场景
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m15s

member 发起购买后订阅归属于 owner,但 attach 交易时校验
orderSub.UserId != u.Id 报"订单订阅与当前用户不匹配"。
现在通过 ResolveEntitlementUser 获取 EffectiveUserID,
允许 member 绑定属于其家庭 owner 的订阅。

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
shanshanzhong 2026-03-12 03:38:42 -07:00
parent 2f33e1e680
commit add27aa4d9

View File

@ -59,6 +59,13 @@ func (l *AttachTransactionLogic) Attach(req *types.AttachAppleTransactionRequest
l.Errorw("无效访问,用户信息缺失")
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "invalid access")
}
// 解析家庭权益member 的订阅归属于 owner
entitlement, entErr := commonLogic.ResolveEntitlementUser(l.ctx, l.svcCtx.DB, u.Id)
if entErr != nil {
l.Errorw("解析家庭权益失败", logger.Field("userId", u.Id), logger.Field("error", entErr.Error()))
return nil, entErr
}
if strings.TrimSpace(req.OrderNo) == "" {
l.Errorw("参数错误orderNo 不能为空")
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "order_no is required")
@ -219,8 +226,8 @@ func (l *AttachTransactionLogic) Attach(req *types.AttachAppleTransactionRequest
orderSub, subErr := l.svcCtx.UserModel.FindOneSubscribeByToken(l.ctx, orderInfo.SubscribeToken)
switch {
case subErr == nil && orderSub != nil && orderSub.Id > 0:
if orderSub.UserId != u.Id {
l.Errorw("订单订阅与当前用户不匹配", logger.Field("orderNo", orderInfo.OrderNo), logger.Field("orderSubUserId", orderSub.UserId), logger.Field("userId", u.Id))
if orderSub.UserId != u.Id && orderSub.UserId != entitlement.EffectiveUserID {
l.Errorw("订单订阅与当前用户不匹配", logger.Field("orderNo", orderInfo.OrderNo), logger.Field("orderSubUserId", orderSub.UserId), logger.Field("userId", u.Id), logger.Field("effectiveUserId", entitlement.EffectiveUserID))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "order subscribe owner mismatch")
}
orderLinkedSub = orderSub
@ -233,7 +240,7 @@ func (l *AttachTransactionLogic) Attach(req *types.AttachAppleTransactionRequest
}
var singleModeAnchorSub *user.Subscribe
if !isNewPurchaseOrder && l.svcCtx.Config.Subscribe.SingleModel && orderLinkedSub == nil {
anchorSub, anchorErr := findSingleModeMergeTarget(l.ctx, l.svcCtx, u.Id, subscribeId)
anchorSub, anchorErr := findSingleModeMergeTarget(l.ctx, l.svcCtx, entitlement.EffectiveUserID, subscribeId)
switch {
case errors.Is(anchorErr, commonLogic.ErrSingleModePlanMismatch):
l.Errorw("单订阅模式下 IAP 套餐不匹配", logger.Field("userId", u.Id), logger.Field("orderNo", req.OrderNo), logger.Field("iapSubscribeId", subscribeId))
@ -385,7 +392,7 @@ func (l *AttachTransactionLogic) Attach(req *types.AttachAppleTransactionRequest
}
if !merged {
userSub := user.Subscribe{
UserId: u.Id,
UserId: entitlement.EffectiveUserID,
SubscribeId: subscribeId,
StartTime: time.Now(),
ExpireTime: exp,