Payment return decided by the server only; encoded path ids; no sign-out on a two-tab refresh race

- ?orderId must be numeric; every id in an API path is encodeURIComponent'd.
- The payment sheet shows success only from GET /payment/orders/{id}; a failed lookup says the
  status is unknown instead of "paid".
- A 401 from /auth/refresh is not a sign-out when another tab already stored a rotated token.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 04:52:25 +03:30
parent 647ccf2c88
commit e850f6dfbd
4 changed files with 50 additions and 22 deletions

View File

@@ -202,7 +202,13 @@ export function createHttpClient(options: HttpClientOptions) {
} catch {
return new ApiError(0, 'ارتباط با سرور برقرار نشد');
}
if (response.status === 401) return 'invalid';
if (response.status === 401) {
// تبِ دیگری همین توکن را زودتر تمدید کرده (سرور توکنِ قبلی را باطل می‌کند) و توکنِ تازه
// را در همان localStorageِ مشترک گذاشته؛ آن نشست سالم است و نباید هر دو تب خارج شوند.
const latest = storage.get();
if (latest?.refreshToken && latest.refreshToken !== current.refreshToken) return latest;
return 'invalid';
}
if (!response.ok) return errorFrom(response, await parseBody(response));
const data = (await response.json()) as Tokens;
const next = { token: data.token, refreshToken: data.refreshToken || current.refreshToken };