From 57fa2b4d692ab45e1d75fa1823c7dac045206498 Mon Sep 17 00:00:00 2001 From: shanshanzhong Date: Mon, 9 Mar 2026 02:32:42 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20IAP=20=E9=87=8D=E5=A4=8D=E4=BA=A4?= =?UTF-8?q?=E6=98=93=E6=A3=80=E6=B5=8B=E4=BC=98=E5=8C=96=EF=BC=8C=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E7=BB=AD=E6=9C=9F=E8=AF=AF=E6=8B=A6=E5=92=8C=E5=AD=A4?= =?UTF-8?q?=E5=84=BF=E8=AE=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 关闭孤儿订单:检测到重复交易时,立即关闭新的 pending 订单(status=3) 2. tradeNo 候选改为只用 transactionId,不再用 originalTransactionId - originalTransactionId 是整个订阅族共享的,续期时会误命中旧订单 - originalTransactionId 仍用于 IAP 事务表幂等检查(FindByOriginalId) --- .../public/iap/apple/attachTransactionLogic.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/internal/logic/public/iap/apple/attachTransactionLogic.go b/internal/logic/public/iap/apple/attachTransactionLogic.go index 973fd83..329eb7f 100644 --- a/internal/logic/public/iap/apple/attachTransactionLogic.go +++ b/internal/logic/public/iap/apple/attachTransactionLogic.go @@ -40,6 +40,7 @@ const ( orderTypeSubscribe uint8 = 1 orderStatusPending uint8 = 1 orderStatusPaid uint8 = 2 + orderStatusClosed uint8 = 3 orderStatusFinished uint8 = 5 ) @@ -101,6 +102,16 @@ func (l *AttachTransactionLogic) Attach(req *types.AttachAppleTransactionRequest if existingOrderNo != "" { l.Errorw("Apple 交易重复绑定,返回已绑定订单", logger.Field("orderNo", req.OrderNo), logger.Field("existingOrderNo", existingOrderNo), logger.Field("tradeNoCandidates", tradeNoCandidates)) l.sendIAPAttachTraceToTelegram("REJECT_DUPLICATE_TRANSACTION", orderInfo, u.Id, orderInfo.SubscribeId, "", orderInfo.Quantity, txPayload.PurchaseDate, txPayload.TransactionId, txPayload.OriginalTransactionId, "already used by "+existingOrderNo) + // 关闭当前 pending 订单,避免产生孤儿订单 + if orderInfo.Status == orderStatusPending { + if closeErr := l.svcCtx.DB.Model(&ordermodel.Order{}). + Where("order_no = ? AND status = ?", req.OrderNo, orderStatusPending). + Update("status", orderStatusClosed).Error; closeErr != nil { + l.Errorw("关闭重复订单失败", logger.Field("orderNo", req.OrderNo), logger.Field("error", closeErr.Error())) + } else { + l.Infow("已关闭重复 pending 订单", logger.Field("orderNo", req.OrderNo), logger.Field("existingOrderNo", existingOrderNo)) + } + } return &types.AttachAppleTransactionResponse{ExistingOrderNo: existingOrderNo}, nil } tradeNo := "" @@ -496,11 +507,8 @@ func (l *AttachTransactionLogic) getAppleTradeNoCandidates(txPayload *iapapple.T if txPayload == nil { return nil } - candidates := make([]string, 0, 2) - if txPayload.OriginalTransactionId != "" { - candidates = append(candidates, txPayload.OriginalTransactionId) - } - if txPayload.TransactionId != "" && txPayload.TransactionId != txPayload.OriginalTransactionId { + candidates := make([]string, 0, 1) + if txPayload.TransactionId != "" { candidates = append(candidates, txPayload.TransactionId) } return candidates