feat(store): 添加门店、门店验证
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
/** 401 是认证失败;403 表示密钥权限或账户组合不被允许。 */
|
||||
export class OzonCredentialError extends Error {
|
||||
public constructor(public readonly status: 401 | 403) {
|
||||
super(`Ozon credential request failed (${status})`);
|
||||
}
|
||||
}
|
||||
/** 认证以外的确定性 4xx,不能误报为凭据无效。 */
|
||||
export class OzonRequestError extends Error {
|
||||
public constructor(public readonly status: number) {
|
||||
super(`Ozon verification request was rejected (${status})`);
|
||||
}
|
||||
}
|
||||
export class OzonRetryableError extends Error {}
|
||||
|
||||
/**
|
||||
* Uses the category-tree read endpoint as the credential probe. It has no write side effect and,
|
||||
* unlike warehouse-list, is verified against the current Ozon account integration.
|
||||
*/
|
||||
export async function verifyOzonCredentials(
|
||||
clientId: string,
|
||||
apiKey: string,
|
||||
): Promise<void> {
|
||||
let response: Response;
|
||||
try {
|
||||
response = await fetch('https://api-seller.ozon.ru/v1/description-category/tree', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Client-Id': clientId,
|
||||
'Api-Key': apiKey,
|
||||
},
|
||||
body: JSON.stringify({ language: 'ZH_HANS' }),
|
||||
signal: AbortSignal.timeout(30_000),
|
||||
});
|
||||
} catch {
|
||||
throw new OzonRetryableError('Ozon request could not be completed');
|
||||
}
|
||||
if (response.ok) return;
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw new OzonCredentialError(response.status);
|
||||
}
|
||||
if (response.status === 429 || response.status >= 500) {
|
||||
throw new OzonRetryableError(`Ozon temporarily unavailable (${response.status})`);
|
||||
}
|
||||
throw new OzonRequestError(response.status);
|
||||
}
|
||||
Reference in New Issue
Block a user