小飞侠接口对接
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CourierApiError } from '../courier.error';
|
||||
import { CourierConfigService } from '../courier.config';
|
||||
import { buildXiaofeixiaSign } from './xiaofeixia.sign';
|
||||
import { XIAOFEIXIA_SUCCESS_CODE } from './xiaofeixia.constants';
|
||||
import type { XiaofeixiaApiResponse } from './xiaofeixia.types';
|
||||
|
||||
type RequestParams = Record<string, string | number | undefined>;
|
||||
|
||||
@Injectable()
|
||||
export class XiaofeixiaClient {
|
||||
constructor(private readonly courierConfig: CourierConfigService) {}
|
||||
|
||||
async request<T>(cmd: string, bizParams: RequestParams): Promise<T> {
|
||||
const cfg = this.courierConfig.load().xiaofeixia;
|
||||
|
||||
if (!cfg.mchId || !cfg.apiKey) {
|
||||
throw new CourierApiError(
|
||||
'小飞侠商户配置不完整,请设置 XIAOFEIXIA_MCH_ID 与 XIAOFEIXIA_API_KEY',
|
||||
'CONFIG_ERROR',
|
||||
'XIAOFEIXIA',
|
||||
);
|
||||
}
|
||||
|
||||
const baseParams: RequestParams = {
|
||||
mchId: cfg.mchId,
|
||||
cmd,
|
||||
signType: cfg.signType,
|
||||
...bizParams,
|
||||
};
|
||||
|
||||
if (cfg.appId) {
|
||||
baseParams.appId = cfg.appId;
|
||||
}
|
||||
|
||||
const sign = buildXiaofeixiaSign(baseParams, cfg.apiKey, cfg.signType);
|
||||
const body = new URLSearchParams();
|
||||
|
||||
for (const [key, value] of Object.entries({ ...baseParams, sign })) {
|
||||
if (value !== undefined && value !== null && value !== '') {
|
||||
body.append(key, String(value));
|
||||
}
|
||||
}
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
response = await fetch(cfg.apiUrl, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: body.toString(),
|
||||
});
|
||||
} catch (error) {
|
||||
throw new CourierApiError(
|
||||
'小飞侠接口网络异常',
|
||||
'200000',
|
||||
'XIAOFEIXIA',
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new CourierApiError(
|
||||
`小飞侠 HTTP 请求失败: ${response.status}`,
|
||||
'200000',
|
||||
'XIAOFEIXIA',
|
||||
);
|
||||
}
|
||||
|
||||
const payload = (await response.json()) as XiaofeixiaApiResponse<T>;
|
||||
|
||||
if (payload.code !== XIAOFEIXIA_SUCCESS_CODE) {
|
||||
throw new CourierApiError(
|
||||
payload.message || '小飞侠接口业务失败',
|
||||
payload.code,
|
||||
'XIAOFEIXIA',
|
||||
payload,
|
||||
);
|
||||
}
|
||||
|
||||
return payload.data as T;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user