Files
trade-message-center/docs/onetalk-order-message-format-observation-2026-09-11.md

4.5 KiB
Raw Permalink Blame History

OneTalk 订单消息:运行态格式观察

观察日期:2026-09-11
证据边界:现有已登录 OneTalk PWA 的 Chromium CDP,只读调用页面 SDK;不保存或输出原始订单、地址、令牌、加密标识、消息正文或完整 URL。
性质:单个真实样本的运行态观察,不是订单系统接口契约,也不是当前跨层数据合同。

1. 怎么判断是订单

SDK 历史条目的订单判别条件为:

const isOrderMessage = (message: Record<string, unknown>): boolean =>
    message.messageType === "rec" &&
    message.type === 1 &&
    message.viewType === 0 &&
    message.msgType === 10010 &&
    message.subType === 59 &&
    message.originalData?.cardType === 9;

msgType=10010 是业务卡片族而不是订单标记;必须同时检查 subType=59cardType=9

2. JSON 中已有的数据

2.1 订单关联字段

originalData.cardType = 9
originalData.params keys =
  orderId, bizCode, contractId, sign, ctime,
  from, to, id, params, tenant

orderIdcontractIdidbizCode 可用于同一受控边界内的订单关联。sign、参与方标识和加密/令牌型字段不得跨 MAIN world 传输或持久化。

2.2 Base64 订单摘要

originalData.params.params 在本样本中是 Base64 编码的 UTF-8 JSON。解码后具有以下结构:

type OrderSummary = {
    id: number;
    orderAmount: number;
    orderAmountCurrency: string;
    paymentAmount: number;
    paymentAmountCurrency: string;
    statusMessageKey: string;
    actionList: Array<{
        name: string;
        messageKey: string;
        properties: {
            payStep?: string;
        };
    }>;
};

因此当前可直接获得:

  • 订单和实付金额及币种;
  • 非本地化的订单状态键 statusMessageKey
  • 动作列表及部分付款阶段 payStep
  • 订单关联 ID。

2.3 当前不能从结构化摘要直接获得的数据

样本 UI 显示的商品数量、商品明细/图片、人类可读状态、收件地址和详情链接不在上述已解码摘要内。

本样本 content 为非 JSON 的普通字符串模板。它不能直接作为稳定 schema 使用,也不能未经白名单处理跨层传递。

extInfo.icbuData 中的 titleiconUrlcardUrlsactionsdefaultContent 在本样本为空;只有 chatEvent 有值,不能据此承诺订单详情链接可用。

3. 怎么获取

3.1 取得订单消息

const getOrderMessages = async (conversation) => {
    const service = window.IcbuIM.IMBaaSSDK.default.getMessageService();
    const response = await service.fetchMessagesWithoutUpdateToRead(
        {
            conversationCode: conversation.cid,
            contactAccountId: conversation.accountId,
            contactAccountIdEncrypt: conversation.accountIdEncrypt,
            aliId: conversation.aliId,
            aliIdEncrypt: conversation.aliIdEncrypt,
            searchMessageId: "",
            timeSlide: { forward: false, timeStamp: Date.now(), pageSize: 20 },
        },
        conversation,
    );

    return (response.list ?? []).filter(
        (message) =>
            message.messageType === "rec" &&
            message.type === 1 &&
            message.viewType === 0 &&
            message.msgType === 10010 &&
            message.subType === 59 &&
            message.originalData?.cardType === 9,
    );
};

3.2 在 MAIN world 内解码摘要

必须限制大小、验证 Base64/UTF-8/JSON 和字段 schema;示例仅展示解码入口,不构成跨层透传授权。

const decodeOrderSummary = (encoded) => {
    if (typeof encoded !== "string" || encoded.length === 0) return null;

    try {
        const bytes = Uint8Array.from(atob(encoded), (character) => character.charCodeAt(0));
        const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));

        if (!parsed || typeof parsed !== "object") return null;
        return parsed;
    } catch {
        return null;
    }
};

生产实现不能将 null 静默当作“无订单”:Base64、UTF-8、JSON 或 schema 失败应成为可观测的显式异常/受控 unsupported 结果。

4. 已验证与未覆盖

  • 已验证:10010/59/cardType=9 判别组合,订单参数键,嵌套 params 的 Base64-UTF-8-JSON 编码,以及摘要键集合。
  • 未覆盖:商品数量和明细、图片、状态键到本地化文案的映射、收件地址、详情链接、不同订单状态及多商品订单的字段变体。