feat(trade): upload WeChat mini program shipping info
Hook SHIPPING and on-site pickup to upload_shipping_info for settlement unlock. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,6 +8,9 @@ import type {
|
||||
WechatCodeSession,
|
||||
WechatOAuthSession,
|
||||
WechatWxaCodeUnlimitedInput,
|
||||
WechatUploadShippingInfoInput,
|
||||
WechatUploadShippingInfoResult,
|
||||
WechatDeliveryCompany,
|
||||
} from './wechat.interface';
|
||||
import { logWechatAuth, type WechatActorRef } from './wechat-log.util';
|
||||
import {
|
||||
@@ -303,6 +306,86 @@ export class WechatApiProvider implements IWechatProvider {
|
||||
return buf;
|
||||
}
|
||||
|
||||
async uploadShippingInfo(input: WechatUploadShippingInfoInput): Promise<WechatUploadShippingInfoResult> {
|
||||
const accessToken = await this.getMiniAccessToken();
|
||||
const orderKey: Record<string, string | number> = {
|
||||
order_number_type: input.orderNumberType,
|
||||
};
|
||||
if (input.orderNumberType === 2) {
|
||||
if (!input.transactionId) {
|
||||
throw new BadRequestException('微信支付单号不能为空');
|
||||
}
|
||||
orderKey.transaction_id = input.transactionId;
|
||||
} else {
|
||||
if (!input.mchId || !input.outTradeNo) {
|
||||
throw new BadRequestException('商户号与商户单号不能为空');
|
||||
}
|
||||
orderKey.mchid = input.mchId;
|
||||
orderKey.out_trade_no = input.outTradeNo;
|
||||
}
|
||||
|
||||
const body = {
|
||||
order_key: orderKey,
|
||||
logistics_type: input.logisticsType,
|
||||
delivery_mode: input.deliveryMode ?? 1,
|
||||
shipping_list: input.shippingList.map((row) => {
|
||||
const item: Record<string, unknown> = {
|
||||
item_desc: row.itemDesc.slice(0, 120),
|
||||
};
|
||||
if (row.trackingNo) item.tracking_no = row.trackingNo;
|
||||
if (row.expressCompany) item.express_company = row.expressCompany;
|
||||
if (row.contact?.consignorContact || row.contact?.receiverContact) {
|
||||
item.contact = {
|
||||
...(row.contact.consignorContact
|
||||
? { consignor_contact: row.contact.consignorContact }
|
||||
: {}),
|
||||
...(row.contact.receiverContact
|
||||
? { receiver_contact: row.contact.receiverContact }
|
||||
: {}),
|
||||
};
|
||||
}
|
||||
return item;
|
||||
}),
|
||||
upload_time: input.uploadTime,
|
||||
payer: { openid: input.payerOpenId },
|
||||
};
|
||||
|
||||
const apiUrl = `https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=${accessToken}`;
|
||||
const data = await this.fetchJson<{ errcode?: number; errmsg?: string }>(apiUrl, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
return {
|
||||
errcode: data.errcode ?? -1,
|
||||
errmsg: data.errmsg ?? 'unknown',
|
||||
};
|
||||
}
|
||||
|
||||
async getDeliveryList(): Promise<WechatDeliveryCompany[]> {
|
||||
const accessToken = await this.getMiniAccessToken();
|
||||
const apiUrl = `https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/get_delivery_list?access_token=${accessToken}`;
|
||||
const data = await this.fetchJson<{
|
||||
errcode?: number;
|
||||
errmsg?: string;
|
||||
delivery_list?: Array<{ delivery_id?: string; delivery_name?: string }>;
|
||||
}>(apiUrl, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: '{}',
|
||||
});
|
||||
if (data.errcode && data.errcode !== 0) {
|
||||
this.logger.warn(`get_delivery_list failed: ${data.errcode} ${data.errmsg}`);
|
||||
return [];
|
||||
}
|
||||
return (data.delivery_list ?? [])
|
||||
.filter((row) => row.delivery_id && row.delivery_name)
|
||||
.map((row) => ({
|
||||
deliveryId: row.delivery_id!,
|
||||
deliveryName: row.delivery_name!,
|
||||
}));
|
||||
}
|
||||
|
||||
async getPhoneNumberByCode(code: string, platform: 'mini' | 'h5', actorRef?: WechatActorRef): Promise<string> {
|
||||
if (platform === 'h5') {
|
||||
throw new InternalServerErrorException('H5 请使用短信绑定手机号');
|
||||
|
||||
Reference in New Issue
Block a user