diff --git a/backend/application/common/service/TransferAuthorizationService.php b/backend/application/common/service/TransferAuthorizationService.php index e061158..d324411 100644 --- a/backend/application/common/service/TransferAuthorizationService.php +++ b/backend/application/common/service/TransferAuthorizationService.php @@ -182,19 +182,25 @@ class TransferAuthorizationService /** * 向微信发起授权申请 + * @param bool $isRetry 是否为换号重试(防止递归) */ - private static function requestAuthorization($user, string $authNo, string $displayName, EasyWeChatService $wechat, bool $renew): array + private static function requestAuthorization($user, string $authNo, string $displayName, EasyWeChatService $wechat, bool $renew, bool $isRetry = false): array { $userId = $user->id; $res = $wechat->applyTransferAuthorization($authNo, $user->openid, $displayName); - //当前单已受理/已终结:改为查单,禁止换号重试 + //单号已被占用(已受理/已终结/重入参数不一致):查单按微信侧实际状态处理 if (self::isApplyConflict($res)) { $query = $wechat->queryTransferAuthorization($authNo, false); $resolved = self::resolveByWechatState($userId, $authNo, $query, $wechat, self::getByUserId($userId)); if ($resolved !== null) { return $resolved; } + //原单已无法拉起授权页:已终结,或重入参数不一致导致该单号不可复用。 + //换全新单号重新发起,保证用户一定能拿到 package;原未确认单 24 小时后自动关闭 + if (!$isRetry) { + return self::requestAuthorization($user, self::generateAuthNoUnique($userId), $displayName, $wechat, true, true); + } } if (self::isQuantityLimit($res)) { @@ -282,7 +288,11 @@ class TransferAuthorizationService { $message = (string)($res['message'] ?? ''); - return mb_strpos($message, '已解除或已授权成功') !== false; + //单号已被占用:原单已解除/已授权成功,或重复发起时请求参数与原单不一致(重入校验) + return $message !== '' && ( + mb_strpos($message, '已解除或已授权成功') !== false + || mb_strpos($message, '重入参数不一致') !== false + ); } /**