返回博客

第三方 POS 接口只传两个字段,开卡门店永远不更新

接入某 POS 系统的会员同步接口时,业务需求是把会员的「归属门店」和「开卡门店」同时迁移到新门店。调用 updateNew 接口后,归属门店(belongCounterCode)确实变了,但数据库里的开卡门店字段(open_card_counter_code)始终是旧值。

翻遍了三处源码注释,都写着同一句话:「updateNew 接口不支持修改开卡门店,只能改归属门店」。这条注释被当成 API 限制记录在案,后续维护者照单全收,没人去验证原始接口文档。

现象

  • updateNew 调用返回 code: 10000returnCode: "0",HTTP 200,一切正常
  • 本地数据库 open_card_counter_code 字段不更新
  • 三处历史注释均断言「此接口不修改开卡门店」

根因

注释描述的是当时的业务设计(「我们的 updateNew 调用不修改开卡门店」),而不是 API 能力边界。真实情况是:

updateNew 接口支持同时修改归属门店和开卡门店,但开卡门店需要完整传入四个字段,缺一不可:

| 字段 | 来源 | 注意 | |------|------|------| | openCardCounterId | 等同于 organizationId(POS 组织 ID) | 是 POS 内部 org ID,不是本地系统主键 | | openCardCounterCode | 门店的 POS 柜台编码 | | | openCardCounterName | 门店名称 | 用 name 字段,不是 counter_name(虚拟渠道店名不同) | | organizationId | POS 组织 ID | 同时控制归属门店 |

历史代码只传了 memberCode + organizationId 两个字段,开卡相关的三个 openCard* 字段从未出现在请求体里。POS 端收到请求后只更新有值的部分,开卡门店当然纹丝不动。

注释把「我们没传字段」误写成「接口不支持」,之后每一位接手的开发者都相信了这个错误断言,并沿用只传两个字段的写法,进一步「验证」了注释的正确性——形成了一个自我强化的错误循环。

坑:四元组缺字段 = 静默不更新

POS 接口不会因为缺字段报错,只会静默忽略。返回 code: 10000 只代表请求被接受,不代表所有字段都被更新。必须传完整的四元组,开卡门店才会变更。

另外,openCardCounterName 必须取门店的 name,不能取 counter_name——部分虚拟渠道门店的这两个字段值不同,用错会导致 POS 端存入错误门店名。

正解

构造完整六字段请求体,缺一不可:

$body = [
    'memberCode'          => $memberCode,         // 会员 POS 卡号
    'organizationId'      => $store->offline_org_id,  // POS 组织 ID(非本地主键)
    'openCardCounterId'   => $store->offline_org_id,  // 与 organizationId 相同
    'openCardCounterCode' => $store->counter_code,    // POS 柜台编码
    'openCardCounterName' => $store->name,            // 门店名,注意不是 counter_name
    'brandCode'           => 'ACME',
    'callerSource'        => 'MyApp',
];

成功判断需要双重校验:

if ($res['code'] === 10000 && $res['data']['returnCode'] === '0') {
    // 真正成功,归属门店 + 开卡门店均已更新
}
正解:传完整四元组,双重校验响应码

updateNew 原生支持同时更新归属门店和开卡门店,无需两次调用。传入完整的 6 个字段,并同时校验 body.code == 10000body.data.returnCode == "0",才算真正落地。

排查要点

接口返回成功但字段没变,优先排查以下三点:

  1. 请求体是否包含全部必要字段——用抓包或日志打印实际发出的 JSON
  2. 字段名大小写——例如 openCardCounterID(大写 D)会被静默忽略,必须是 openCardCounterId
  3. ID 来源——organizationId 必须是 POS 系统的组织 ID(对应本地数据库的 offline_org_id),传本地主键会导致 POS 端找不到组织

一句话外卖

第三方接口注释写着「不支持 X」时,先验证注释是描述 API 限制还是描述当时代码的取舍——历史业务决策很容易被后人误读成能力边界。