PAYATHON 2026

建议开发pad版云支付点单系统,提升餐饮支付一体化能力

支付小周

结论

Pad 版云支付点单工具具备开发条件,也适合餐饮场景。项目不能停留在增加一个 Pad 点餐界面上,还要建立统一的订单、支付和对账体系,并处理好与商户原有收银系统之间的数据协同。

可以先选择少量商户试点,第一阶段集中完成二维码点餐、服务员点餐、云支付收款、退款和门店日结等核心功能。原收银机报表如何接入,则要看系统的开放能力,可依次考虑 API 对接、标准文件导入导出和独立对账报表。

如果原收银系统既不开放接口,也不支持导入外部订单,就无法承诺直接合并其内部报表。遇到这种情况,可以由云支付生成统一经营报表,再通过商户订单号、支付流水号和营业日期进行财务核对。

为什么值得开发

现阶段的问题不在支付本身,而是订单数据与支付数据彼此割裂。

消费者扫描桌面二维码后,可以一次完成点餐和付款,但订单未必会进入商户原有收银机。服务员通过收银机录入的订单、消费者扫码产生的订单,以及云支付记录的支付流水,可能分散在不同系统里。商户日结时只能人工合并,容易出现漏单、重复统计或退款状态不一致。

Pad 版工具可以补充这些能力:

  • 服务员在桌边开台、点餐、加菜、退菜和结账。
  • 消费者扫码后自助点餐并付款。
  • 服务员点餐与消费者扫码加菜进入同一桌台订单。
  • 统一记录订单金额、优惠金额、实收金额和退款金额。
  • 微信、支付宝等聚合支付渠道共用一套订单模型。
  • 门店按桌台、班次、支付渠道和营业日期生成报表。

Pad 只是操作入口。系统最终是否好用,取决于后端能否把菜品、订单、支付、退款、交班和日结连成一套完整流程。

建议的系统结构

系统可以分成五个部分:

  1. Pad 点单端
    供服务员管理桌台、开单、加菜、催菜、退菜和发起支付。

  2. 顾客扫码端
    通过桌面二维码识别门店和桌台,供顾客浏览菜单、下单、加菜和付款。

  3. 订单中心
    统一接收 Pad 与扫码端产生的订单,维护订单状态、金额快照和操作记录。

  4. 支付中心
    调用云支付能力,处理支付下单、异步通知、查询、撤销和退款。

  5. 报表与对账中心
    汇总订单、支付和退款数据,并与原收银系统交换数据或进行核对。

同一张桌台可能先由服务员开单,随后由顾客扫码加菜。因此,系统不应简单地将二维码绑定为一张固定订单。二维码更适合绑定门店和桌台,后端再根据桌台状态动态创建或关联实际订单。

实施步骤

1. 先确认原收银系统的开放能力

开发前,需要向收银系统厂商确认:

  • 是否提供订单写入 API。
  • 是否提供菜品、规格、价格和库存查询 API。
  • 是否支持外部支付结果回写。
  • 是否支持退款状态同步。
  • 是否可以订阅订单变更通知。
  • 是否支持 CSV、Excel 或其他标准格式导入。
  • 是否允许第三方订单参与交班和日结报表。
  • 外部订单号、支付流水号是否可以在报表中展示。

不同收银系统的接口差异很大。在拿到接口文档和授权之前,不能假定云支付订单一定能写入原收银机。

2. 建立统一订单模型

Pad 点餐和扫码点餐必须接入同一个订单中心。订单至少要保存以下标识:

  • merchant_id:商户标识。
  • store_id:门店标识。
  • table_id:桌台标识。
  • order_no:云支付点单系统订单号。
  • external_order_no:原收银系统订单号。
  • payment_no:云支付流水号。
  • channel_trade_no:支付渠道流水号。
  • business_date:营业日期。
  • order_status:订单状态。
  • payment_status:支付状态。
  • sync_status:收银系统同步状态。

订单状态与支付状态需要分别管理。例如,菜品已经下单但尚未付款时,订单状态可以是 CONFIRMED,支付状态则是 UNPAID。发生部分退款后,支付状态可以改为 PARTIALLY_REFUNDED,订单本身却不一定需要取消。

金额应以整数分保存,避免浮点数计算产生误差。

{
  "order_no": "YP202609140001",
  "merchant_id": "M10001",
  "store_id": "S10001",
  "table_id": "T08",
  "business_date": "2026-09-14",
  "source": "PAD",
  "order_status": "CONFIRMED",
  "payment_status": "UNPAID",
  "amounts": {
    "original_amount": 12800,
    "discount_amount": 1000,
    "payable_amount": 11800,
    "paid_amount": 0,
    "refunded_amount": 0
  },
  "items": [
    {
      "sku_id": "SKU1001",
      "name": "招牌牛肉饭",
      "quantity": 2,
      "unit_price": 4800,
      "line_amount": 9600
    },
    {
      "sku_id": "SKU2031",
      "name": "冰柠檬茶",
      "quantity": 2,
      "unit_price": 1600,
      "line_amount": 3200
    }
  ]
}

系统还要保存菜品名称和单价在下单时的快照,不能只关联当前菜单。否则商户调整价格后,历史订单金额和报表也可能随之变化。

3. 统一 Pad 与扫码点餐流程

推荐采用以下流程:

  1. 服务员在 Pad 上选择桌台并开台。
  2. 订单中心创建桌台订单。
  3. 顾客扫描桌面二维码。
  4. 后端根据门店、桌台和二维码状态查找当前有效订单。
  5. 顾客提交菜品,订单中心校验价格并追加订单明细。
  6. 后厨或打印系统接收出菜单。
  7. 顾客或服务员发起支付。
  8. 支付中心创建云支付交易。
  9. 系统收到支付成功通知后更新支付状态。
  10. 订单同步到原收银系统,或进入待对账列表。

多人同时扫码,或者服务员与顾客同时加菜,都需要单独处理。更新订单时可以使用版本号做乐观锁控制,防止后提交的请求覆盖前面的数据。

POST /api/v1/orders/YP202609140001/items
Content-Type: application/json
Idempotency-Key: 7f65b0b5-913e-49ab-bf70-60e21abbad33

{
  "order_version": 6,
  "items": [
    {
      "sku_id": "SKU2031",
      "quantity": 1
    }
  ]
}

如果服务端发现当前版本已经是 7,应返回冲突信息,让客户端刷新订单后重新提交,不能直接覆盖订单。

{
  "code": "ORDER_VERSION_CONFLICT",
  "message": "订单已发生变化,请刷新后重试",
  "current_version": 7
}

4. 正确处理支付回调

前端显示「支付成功」不能作为最终入账依据。系统应以通过验签的支付异步通知为主要依据,同时通过主动查询处理通知延迟或丢失。

下面是一个简化的伪代码示例。签名算法、请求头和字段名称必须以实际云支付接口文档为准。

@PostMapping("/callbacks/payment")
public ResponseEntity<String> handlePaymentCallback(
        @RequestHeader("X-Signature") String signature,
        @RequestBody String body) {

    if (!signatureVerifier.verify(body, signature)) {
        return ResponseEntity.status(401).body("INVALID_SIGNATURE");
    }

    PaymentCallback callback = parse(body);

    paymentService.processOnce(
        callback.getPaymentNo(),
        callback.getStatus(),
        callback.getPaidAmount(),
        callback.getChannelTradeNo()
    );

    return ResponseEntity.ok("SUCCESS");
}

processOnce 必须具备幂等性。同一笔支付通知可能重复发送,系统不能因此重复入账、重复打印或重复向收银系统同步。

更新支付状态时,还要校验订单号、商户号、币种和金额。如果只根据「支付成功」字段更新订单,会有串单或金额不一致的风险。

5. 分级实现收银报表协同

方案一:通过 API 双向对接

这种方案的使用体验最完整。云支付订单生成后写入收银系统,支付完成后回写支付结果。原收银系统发生退菜、退款或改单时,也要通知云支付订单中心。

前提是收银系统提供稳定接口,并允许外部订单进入其营业报表。

接口调用可以采用类似结构:

POST /pos-api/v1/external-orders
Content-Type: application/json
Idempotency-Key: YP202609140001

{
  "external_source": "CLOUD_PAY_ORDERING",
  "order_no": "YP202609140001",
  "store_id": "S10001",
  "table_no": "08",
  "business_date": "2026-09-14",
  "payable_amount": 11800,
  "paid_amount": 11800,
  "payment_method": "CLOUD_PAY",
  "payment_no": "PAY2026091400098",
  "items": [
    {
      "external_sku_id": "POS-SKU-1001",
      "quantity": 2,
      "unit_price": 4800
    }
  ]
}

这里的路径和字段仅用于展示设计思路,不代表任何现有收银系统的正式接口。

方案二:通过标准文件交换

如果收银系统没有实时 API,但支持文件导入,可以按营业日期导出 CSV。文件至少要包含订单号、外部订单号、交易时间、订单金额、优惠金额、实收金额、退款金额和支付渠道。

business_date,order_no,external_order_no,paid_at,payable_amount,paid_amount,refunded_amount,payment_method
2026-09-14,YP202609140001,POS202609140088,2026-09-14T12:16:08+08:00,118.00,118.00,0.00,CLOUD_PAY

导出文件中的金额可以使用元,但内部计算仍建议使用分。文件还要明确字符编码、时区、金额单位和字段版本,避免两个系统对同一字段产生不同理解。

方案三:提供独立的统一对账报表

如果原收银系统完全封闭,可以由云支付侧生成独立报表,内容包括:

  • 点餐订单总额。
  • 支付成功总额。
  • 已退款金额。
  • 未支付和已取消订单。
  • Pad 点餐与扫码点餐占比。
  • 各支付渠道汇总。
  • 收银系统已同步、待同步和同步失败的订单。
  • 订单金额与支付金额不一致的异常记录。

这种方式不能修改原收银系统的内部报表,但可以减少人工核对工作,也适合在第一阶段使用。

6. 建立自动对账机制

合并报表时,不能只比较每天的总金额。总额相同不代表每笔订单都正确,因为漏单和重复单可能同时存在。

匹配时可以按以下优先级处理:

  1. external_order_no
  2. order_no
  3. payment_no
  4. 门店、金额和支付时间的组合

对账结果可以分为:

  • MATCHED:订单和支付完全一致。
  • ORDER_MISSING:有支付记录但没有订单。
  • PAYMENT_MISSING:有订单但没有成功支付。
  • AMOUNT_MISMATCH:订单金额与实付金额不一致。
  • REFUND_MISMATCH:退款金额或状态不一致。
  • DUPLICATED:疑似重复订单或重复入账。
  • SYNC_FAILED:写入原收银系统失败。

营业日期不能直接等同于自然日期。部分餐厅会在凌晨结束营业,凌晨产生的交易可能仍属于前一天的营业班次。具体切日时间应由门店配置,所有报表统一采用同一套规则。

第一阶段应控制范围

为了尽快验证实际价值,第一版不宜覆盖全部餐饮业务,可以先完成:

  • 门店和桌台管理。
  • 菜品、分类、规格和临时售罄。
  • 服务员开台、点餐、加菜和退菜。
  • 顾客扫码点餐。
  • 云支付下单、查询和退款。
  • 小票或后厨打印。
  • 交班报表和门店日结报表。
  • 标准 CSV 导出。
  • 一种主流收银系统的试点对接。
  • 同步失败后的人工重试。

会员、营销券、复杂套餐、排队叫号、库存核算和供应链管理可以留到后续阶段。如果第一版范围铺得太大,点单工具很容易变成另一套完整的收银系统,交付周期和维护成本都会明显增加。

需要特别注意的问题

菜品映射

云支付菜单与原收银系统菜单之间必须有稳定的映射关系。不能只按菜品名称匹配,因为重名、改名、规格和做法都可能造成歧义。系统应保存 sku_id 与 external_sku_id 的对应关系,并提供映射异常列表。

退款归属

退款可能由 Pad、原收银机或支付后台发起。系统需要明确主要操作入口,并同步退款结果。否则可能出现支付渠道已经退款,订单报表却仍显示全额实收。

部分退款、整单退款、退菜不退款和退款失败要分别记录,不能统一归入一个「已退款」状态。

订单修改

支付完成后再修改菜品,会影响账实一致。通常不应直接覆盖原订单,而要通过退菜、退款、补单或追加订单处理,同时保留完整的操作轨迹。

网络异常

餐厅的网络环境不一定稳定。Pad 端可以缓存菜单和桌台信息,但不能仅依赖本地状态判断支付结果。网络恢复后,系统应主动查询支付状态并补偿同步。

是否允许离线点餐,需要根据业务风险决定。如果允许离线开单,就要设计本地订单号、防重复提交和恢复同步机制。

权限与审计

退菜、改单、赠送、抹零和退款应采用不同的权限设置。每次敏感操作都要记录操作人、设备、时间、原值、修改后值和原因,方便门店追责和财务审计。

数据安全

桌台二维码中不能直接暴露可被随意修改的门店和桌台参数。可以使用随机令牌或带签名的短期参数,并由服务端验证二维码状态。

支付回调必须验签,接口通信应使用 HTTPS。支付凭证、顾客信息和操作日志还要根据适用的合规要求,设置访问权限、脱敏方式和保存期限。

更稳妥的落地建议

这个需求可以立项,但项目目标应定义为「餐饮订单支付一体化」,而不是只开发一个 Pad 应用。

落地时,可以先选择一家收银系统接口条件较好的商户完成闭环。顾客扫码与服务员 Pad 点餐共用订单中心,付款统一通过云支付完成,订单和支付结果再同步到收银系统。试点稳定后,再抽象菜品映射、订单写入、退款同步和日结对账接口,逐步适配其他收银系统。

如果试点商户的原收银系统没有任何开放能力,可以先提供云支付侧的统一经营报表和异常对账功能。即使暂时无法合并原报表,也能降低商户的核账成本,并为后续系统对接保留清晰的数据基础。

备注:内容仅供参考。