{
  "openapi": "3.0.3",
  "info": {
    "title": "重庆环卫-通用预扣款订单接口",
    "version": "1.0.0",
    "description": "智慧餐厅 store + ai_api 通用预扣款订单接口文档。当前用于咖啡机对接，后续可兼容其他预扣款来源。"
  },
  "servers": [
    {
      "url": "http://127.0.0.1",
      "description": "本地 zhctapp_v2_0 开发容器"
    }
  ],
  "tags": [
    {
      "name": "外部接口/三方调用康比特/预扣款订单-咖啡机对接",
      "description": "咖啡机接口 A/C/B 与小程序扫码入口"
    }
  ],
  "paths": {
    "/api/prepayOrder/code": {
      "post": {
        "tags": [
          "外部接口/三方调用康比特/预扣款订单-咖啡机对接"
        ],
        "x-apifox-folder": "外部接口/三方调用康比特/预扣款订单-咖啡机对接",
        "summary": "接口 A：取码",
        "description": "# 接口 A：取码 `/api/prepayOrder/code`\n\n## 接口概述\n\n咖啡机或后续预扣款设备调用本接口获取付款二维码。智慧餐厅系统会校验设备是否存在、签名是否正确，并创建或复用一条 `ydy_prepay_order` 预扣款订单，返回给设备可展示的二维码内容 `twocode`。\n\n咖啡机展示二维码后，消费者使用小程序扫码；扫码入口会生成正式消费订单 `ydy_meal_order`，后续支付、扣款流程沿用手机端订单支付流程。\n\n## 接口信息\n\n- **接口地址**：`https://xxx.com/api/prepayOrder/code`\n- **请求方法**：POST\n- **Content-Type**：`application/x-www-form-urlencoded`\n- **接口版本**：v1.0\n\n## 请求参数（Body）\n\n| 参数名 | 类型 | 是否必填 | 描述 | 示例值 |\n| --- | --- | --- | --- | --- |\n| orderid | String | 是 | 设备侧订单号；返回二维码中会原样带回，用于设备后续查扣款和报结果 | 260728144800001 |\n| machid | String | 是 | 咖啡机设备编号；对应 PC 端设备管理的 SN 字段 | CQHW_COFFEE_001 |\n| trackno | String | 否 | 货道、轨道或商品编号 | LATTE-01 |\n| name | String | 否 | 商品名称，扫码生成正式订单时写入订单备注 | 拿铁 |\n| price | Integer | 否 | 商品金额，单位分 | 1200 |\n| channelid | String | 否 | 设备或第三方侧渠道标识，原样记录 | BALANCE |\n| timestamp | String | 是 | 时间戳，参与签名 | 1785218917 |\n| randstr | String | 是 | 随机字符串，参与签名 | CQHW_RAND_A |\n| sign | String | 是 | 签名值，按签名规则生成 | e10adc3949ba59abbe56e057f20f883e |\n\n\n## 调用说明\n\n- `machid` 固定对应智慧餐厅 PC 端设备管理中的设备 SN；本项目咖啡机设备类型已独立配置。\n- `orderid` 为设备侧订单号，同一 `machid + orderid` 会复用已有预扣款订单，避免重复生成。\n- `price` 金额单位为分，例如 `1200` 表示 12.00 元。\n- 当前接口返回不包含 `trace_id` 字段；问题排查时请提供 `machid`、`orderid`、`torderid` 和接口调用时间。\n\n\n\n## 签名规则\n\n设备侧接口统一使用 `timestamp`、`randstr`、`sign` 做签名校验。\n\n1. 系统配置 `coffee_machine_appkey`，默认值：`1234567890abcdef`。\n2. 取 `appkey`、`timestamp`、`randstr` 三个字符串，按字典序升序排序。\n3. 将排序后的三个字符串直接拼接，不加分隔符。\n4. 对拼接结果计算 `sha1`，取小写十六进制字符串作为 `sign`。\n\n示例：\n\n```text\nappkey = 1234567890abcdef\ntimestamp = 1785218917\nrandstr = CQHW_RAND_A\nsign = sha1(sort(appkey,timestamp,randstr).join(''))\n```\n\n\n## 请求示例\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"machid\": \"CQHW_COFFEE_001\",\n  \"trackno\": \"LATTE-01\",\n  \"name\": \"拿铁\",\n  \"price\": \"1200\",\n  \"channelid\": \"BALANCE\",\n  \"timestamp\": \"1785218917\",\n  \"randstr\": \"CQHW_RAND_A\",\n  \"sign\": \"按签名算法生成\"\n}\n```\n\n## 响应格式\n\n### 取码成功响应\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"torderid\": \"10001\",\n  \"twocode\": \"https://xxx.com/aizhct/api/PrepayOrder/scan?type=prepay&source=1&orderid=260728144800001&machid=CQHW_COFFEE_001&torderid=10001\",\n  \"code\": \"1\",\n  \"msg\": \"成功\"\n}\n```\n\n### 取码失败响应\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"torderid\": \"\",\n  \"code\": \"0\",\n  \"msg\": \"设备不存在\"\n}\n```\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"torderid\": \"\",\n  \"code\": \"0\",\n  \"msg\": \"签名错误\"\n}\n```\n\n## 状态码说明\n\n| code | 描述 |\n| --- | --- |\n| 1 | 取码成功，设备可展示 `twocode` 二维码 |\n| 0 | 取码失败，失败原因见 `msg` |\n\n## 响应字段说明\n\n| 字段名 | 类型 | 描述 |\n| --- | --- | --- |\n| orderid | String | 设备侧订单号 |\n| torderid | String | 智慧餐厅预扣款订单 ID，对应 `ydy_prepay_order.id` |\n| twocode | String | 设备展示的二维码内容；消费者扫码后进入小程序扫码入口 |\n| code | String | 接口处理结果，`1` 成功、`0` 失败 |\n| msg | String | 响应消息，描述处理结果或失败原因 |\n\n## curl 示例\n\n```bash\ncurl --location --request POST 'https://xxx.com/api/prepayOrder/code' \\\n  --header 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode 'orderid=260728144800001' \\\n  --data-urlencode 'machid=CQHW_COFFEE_001' \\\n  --data-urlencode 'trackno=LATTE-01' \\\n  --data-urlencode 'name=拿铁' \\\n  --data-urlencode 'price=1200' \\\n  --data-urlencode 'channelid=BALANCE' \\\n  --data-urlencode 'timestamp=1785218917' \\\n  --data-urlencode 'randstr=CQHW_RAND_A' \\\n  --data-urlencode 'sign=按签名算法生成'\n```",
        "operationId": "createPrepayOrderCode",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PrepayCodeRequest"
              },
              "examples": {
                "coffee": {
                  "summary": "咖啡机取码",
                  "value": {
                    "orderid": "CQHW_E2E_20260728_ORDER_10001",
                    "machid": "CQHW_E2E_20260728_MACH_001",
                    "trackno": "LATTE-01",
                    "name": "拿铁",
                    "price": "1200",
                    "channelid": "BALANCE",
                    "timestamp": "1785218917",
                    "randstr": "CQHW_E2E_20260728_RAND_A",
                    "sign": "按签名算法生成"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "取码结果。code=1 表示成功；code=0 表示失败。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrepayCodeResponse"
                },
                "examples": {
                  "success": {
                    "summary": "成功",
                    "value": {
                      "orderid": "CQHW_E2E_20260728_ORDER_10001",
                      "torderid": "5",
                      "twocode": "http://127.0.0.1/aizhct/api/PrepayOrder/scan?type=prepay&source=1&orderid=CQHW_E2E_20260728_ORDER_10001&machid=CQHW_E2E_20260728_MACH_001&torderid=5",
                      "code": "1",
                      "msg": "成功"
                    }
                  },
                  "fail": {
                    "summary": "失败",
                    "value": {
                      "orderid": "CQHW_E2E_20260728_ORDER_10001",
                      "torderid": "",
                      "code": "0",
                      "msg": "设备不存在"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/aizhct/api/PrepayOrder/scan": {
      "get": {
        "tags": [
          "外部接口/三方调用康比特/预扣款订单-咖啡机对接"
        ],
        "x-apifox-folder": "外部接口/三方调用康比特/预扣款订单-咖啡机对接",
        "summary": "小程序扫码入口：预扣款订单转正式订单",
        "description": "# 小程序扫码入口 `/aizhct/api/PrepayOrder/scan`\n\n## 接口概述\n\n消费者扫描设备展示的 `twocode` 后进入本接口。接口校验预扣款订单来源、设备订单号、设备 `machid` 和当前登录用户，将预扣款订单转换成正式消费订单 `ydy_meal_order`。\n\n生成的正式订单 `source=咖啡机订单`，支付方式沿用手机端余额支付流程。消费者支付成功后，系统会回写预扣款订单状态，设备再通过接口 C 查询扣款结果。\n\n## 接口信息\n\n- **接口地址**：`https://xxx.com/aizhct/api/PrepayOrder/scan`\n- **请求方法**：GET\n- **鉴权方式**：小程序登录态，请求头传 `Access-Token`\n- **接口版本**：v1.0\n\n## 请求头（Header）\n\n| 参数名 | 类型 | 描述 | 示例值 |\n| --- | --- | --- | --- |\n| Access-Token | String | 小程序登录 token | {{terminal_token}} |\n\n## 请求参数（Query）\n\n| 参数名 | 类型 | 是否必填 | 描述 | 示例值 |\n| --- | --- | --- | --- | --- |\n| type | String | 否 | 二维码类型，建议固定传 `prepay` | prepay |\n| source | Integer | 否 | 预扣款来源，`1=咖啡机` | 1 |\n| orderid | String | 是 | 设备侧订单号，与接口 A 取码时的 `orderid` 一致 | 260728144800001 |\n| machid | String | 是 | 设备编号，与接口 A 取码时的 `machid` 一致 | CQHW_COFFEE_001 |\n| torderid | Integer | 是 | 智慧餐厅预扣款订单 ID | 10001 |\n\n说明：\n\n- 当前开发容器验证路径为 `/aizhct/api/PrepayOrder/scan`。\n- 短横线别名 `/aizhct/api/prepay-order/scan` 当前因 ai_api `with_route=false` 未生效，二维码应使用本文档路径。\n- 如果预扣款订单已绑定正式订单，再次扫码会返回已绑定订单，不重复创建 `ydy_meal_order`。\n\n## 请求示例\n\n```text\n/aizhct/api/PrepayOrder/scan?type=prepay&source=1&orderid=260728144800001&machid=CQHW_COFFEE_001&torderid=10001\n```\n\n## 响应格式\n\n### 扫码成功响应\n\n```json\n{\n  \"message\": \"订单创建成功\",\n  \"status\": 200,\n  \"data\": {\n    \"orderId\": 67874,\n    \"isPay\": 1\n  }\n}\n```\n\n### 扫码失败响应\n\n```json\n{\n  \"message\": \"预扣款订单不存在\",\n  \"status\": 500,\n  \"data\": []\n}\n```\n\n```json\n{\n  \"message\": \"缺少必要的参数token, 请先登录\",\n  \"status\": 401,\n  \"data\": []\n}\n```\n\n## 状态码说明\n\n| status | 描述 |\n| --- | --- |\n| 200 | 扫码成功，已生成或返回正式消费订单 |\n| 401 | 未登录或登录 token 缺失/失效 |\n| 500 | 业务校验失败，失败原因见 `message` |\n\n## 响应字段说明\n\n| 字段名 | 类型 | 描述 |\n| --- | --- | --- |\n| message | String | 响应消息 |\n| status | Integer | 接口处理状态 |\n| data.orderId | Integer | 正式消费订单 ID，对应 `ydy_meal_order.id` |\n| data.isPay | Integer | 是否需要继续支付，`1=需要支付`、`0=无需支付或已支付` |\n\n## curl 示例\n\n```bash\ncurl --location 'https://xxx.com/aizhct/api/PrepayOrder/scan?type=prepay&source=1&orderid=260728144800001&machid=CQHW_COFFEE_001&torderid=10001' \\\n  --header 'Access-Token: {{terminal_token}}'\n```",
        "operationId": "scanPrepayOrder",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "prepay"
            },
            "description": "二维码类型标识。当前建议传 prepay。"
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "example": 1
            },
            "description": "预扣款来源。1=咖啡机。"
          },
          {
            "name": "orderid",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "CQHW_E2E_20260728_ORDER_10001"
            },
            "description": "设备订单号。"
          },
          {
            "name": "machid",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "CQHW_E2E_20260728_MACH_001"
            },
            "description": "设备 machid，对应 ydy_equipment.sn。"
          },
          {
            "name": "torderid",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 5
            },
            "description": "智慧餐厅预扣款订单 ID，对应 ydy_prepay_order.id。"
          }
        ],
        "security": [
          {
            "MiniAppToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "扫码创建订单结果。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MiniAppResponse"
                },
                "examples": {
                  "success": {
                    "summary": "成功",
                    "value": {
                      "message": "订单创建成功",
                      "status": 200,
                      "data": {
                        "orderId": 67874,
                        "isPay": 1
                      }
                    }
                  },
                  "missingLogin": {
                    "summary": "未登录",
                    "value": {
                      "message": "缺少必要的参数token, 请先登录",
                      "status": 401,
                      "data": []
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/prepayOrder/payResult": {
      "post": {
        "tags": [
          "外部接口/三方调用康比特/预扣款订单-咖啡机对接"
        ],
        "x-apifox-folder": "外部接口/三方调用康比特/预扣款订单-咖啡机对接",
        "summary": "接口 C：查扣款",
        "description": "# 接口 C：查扣款 `/api/prepayOrder/payResult`\n\n## 接口概述\n\n咖啡机调用本接口查询消费者是否完成支付。设备应在消费者扫码后轮询本接口，只有当返回 `code=1` 时才开始制作咖啡。\n\n系统会统一校验设备是否存在、签名是否正确，并根据 `torderid` 或 `machid + orderid` 查询 `ydy_prepay_order` 状态。\n\n## 接口信息\n\n- **接口地址**：`https://xxx.com/api/prepayOrder/payResult`\n- **请求方法**：POST\n- **Content-Type**：`application/x-www-form-urlencoded`\n- **接口版本**：v1.0\n\n## 请求参数（Body）\n\n| 参数名 | 类型 | 是否必填 | 描述 | 示例值 |\n| --- | --- | --- | --- | --- |\n| orderid | String | 是 | 设备侧订单号 | 260728144800001 |\n| machid | String | 是 | 设备编号，对应 PC 端设备 SN | CQHW_COFFEE_001 |\n| torderid | String | 否 | 智慧餐厅预扣款订单 ID；建议传入，传入时会校验 `orderid` 与 `machid` 是否匹配 | 10001 |\n| timestamp | String | 是 | 时间戳，参与签名 | 1785218919 |\n| randstr | String | 是 | 随机字符串，参与签名 | CQHW_RAND_C |\n| sign | String | 是 | 签名值，按签名规则生成 | e10adc3949ba59abbe56e057f20f883e |\n\n\n## 调用说明\n\n- `machid` 固定对应智慧餐厅 PC 端设备管理中的设备 SN；本项目咖啡机设备类型已独立配置。\n- `orderid` 为设备侧订单号，同一 `machid + orderid` 会复用已有预扣款订单，避免重复生成。\n- `price` 金额单位为分，例如 `1200` 表示 12.00 元。\n- 当前接口返回不包含 `trace_id` 字段；问题排查时请提供 `machid`、`orderid`、`torderid` 和接口调用时间。\n\n\n\n## 签名规则\n\n设备侧接口统一使用 `timestamp`、`randstr`、`sign` 做签名校验。\n\n1. 系统配置 `coffee_machine_appkey`，默认值：`1234567890abcdef`。\n2. 取 `appkey`、`timestamp`、`randstr` 三个字符串，按字典序升序排序。\n3. 将排序后的三个字符串直接拼接，不加分隔符。\n4. 对拼接结果计算 `sha1`，取小写十六进制字符串作为 `sign`。\n\n示例：\n\n```text\nappkey = 1234567890abcdef\ntimestamp = 1785218917\nrandstr = CQHW_RAND_A\nsign = sha1(sort(appkey,timestamp,randstr).join(''))\n```\n\n\n## 请求示例\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"machid\": \"CQHW_COFFEE_001\",\n  \"torderid\": \"10001\",\n  \"timestamp\": \"1785218919\",\n  \"randstr\": \"CQHW_RAND_C\",\n  \"sign\": \"按签名算法生成\"\n}\n```\n\n## 响应格式\n\n### 消费者付款成功响应\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"torderid\": \"10001\",\n  \"code\": \"1\",\n  \"msg\": \"消费者付款成功\"\n}\n```\n\n### 正在等待消费者付款响应\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"torderid\": \"10001\",\n  \"code\": \"2\",\n  \"msg\": \"正在等待消费者付款\"\n}\n```\n\n### 失败响应\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"torderid\": \"10001\",\n  \"code\": \"0\",\n  \"msg\": \"预扣款订单不存在\"\n}\n```\n\n## 状态码说明\n\n| code | 描述 | 设备处理建议 |\n| --- | --- | --- |\n| 0 | 失败，失败原因见 `msg` | 停止本次交易或提示异常 |\n| 1 | 消费者付款成功 | 开始制作/出货 |\n| 2 | 正在等待消费者付款 | 继续等待或按设备策略轮询 |\n| 3 | 此次交易已过期 | 停止本次交易 |\n| 4 | 此次交易已关闭 | 当前系统暂不主动产生该状态，保留兼容 |\n| 5 | 此次交易已完成 | 已出货完成，设备无需重复制作 |\n\n## 响应字段说明\n\n| 字段名 | 类型 | 描述 |\n| --- | --- | --- |\n| orderid | String | 设备侧订单号 |\n| torderid | String | 智慧餐厅预扣款订单 ID |\n| code | String | 交易状态码 |\n| msg | String | 状态说明或失败原因 |\n\n## curl 示例\n\n```bash\ncurl --location --request POST 'https://xxx.com/api/prepayOrder/payResult' \\\n  --header 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode 'orderid=260728144800001' \\\n  --data-urlencode 'machid=CQHW_COFFEE_001' \\\n  --data-urlencode 'torderid=10001' \\\n  --data-urlencode 'timestamp=1785218919' \\\n  --data-urlencode 'randstr=CQHW_RAND_C' \\\n  --data-urlencode 'sign=按签名算法生成'\n```",
        "operationId": "queryPrepayOrderPayment",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PrepayQueryRequest"
              },
              "examples": {
                "queryPaid": {
                  "summary": "查询已支付订单",
                  "value": {
                    "orderid": "CQHW_E2E_20260728_ORDER_10001",
                    "machid": "CQHW_E2E_20260728_MACH_001",
                    "torderid": "5",
                    "timestamp": "1785218919",
                    "randstr": "CQHW_E2E_20260728_RAND_C",
                    "sign": "按签名算法生成"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "扣款查询结果。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrepayStatusResponse"
                },
                "examples": {
                  "paid": {
                    "summary": "消费者付款成功",
                    "value": {
                      "orderid": "CQHW_E2E_20260728_ORDER_10001",
                      "torderid": "5",
                      "code": "1",
                      "msg": "消费者付款成功"
                    }
                  },
                  "waiting": {
                    "summary": "等待付款",
                    "value": {
                      "orderid": "CQHW_E2E_20260728_ORDER_UNSCANNED",
                      "torderid": "7",
                      "code": "2",
                      "msg": "正在等待消费者付款"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/prepayOrder/fulfillResult": {
      "post": {
        "tags": [
          "外部接口/三方调用康比特/预扣款订单-咖啡机对接"
        ],
        "x-apifox-folder": "外部接口/三方调用康比特/预扣款订单-咖啡机对接",
        "summary": "接口 B：报结果",
        "description": "# 接口 B：报结果 `/api/prepayOrder/fulfillResult`\n\n## 接口概述\n\n咖啡机完成制作/出货后调用本接口回传出货结果。系统会记录设备回传内容，更新 `ydy_prepay_order` 的出货状态。\n\n出货成功时，预扣款订单状态更新为 `code=5 此次交易已完成`；出货失败时记录失败原因，便于后续人工核查。\n\n## 接口信息\n\n- **接口地址**：`https://xxx.com/api/prepayOrder/fulfillResult`\n- **请求方法**：POST\n- **Content-Type**：`application/x-www-form-urlencoded`\n- **接口版本**：v1.0\n\n## 请求参数（Body）\n\n| 参数名 | 类型 | 是否必填 | 描述 | 示例值 |\n| --- | --- | --- | --- | --- |\n| orderid | String | 是 | 设备侧订单号 | 260728144800001 |\n| machid | String | 是 | 设备编号，对应 PC 端设备 SN | CQHW_COFFEE_001 |\n| torderid | String | 否 | 智慧餐厅预扣款订单 ID；建议传入 | 10001 |\n| status | Integer | 是 | 出货结果，`1=成功`、`0=失败` | 1 |\n| errinfo | String | 否 | 出货失败原因；`status=0` 时建议传入 | 设备出货失败 |\n| timestamp | String | 是 | 时间戳，参与签名 | 1785218920 |\n| randstr | String | 是 | 随机字符串，参与签名 | CQHW_RAND_B |\n| sign | String | 是 | 签名值，按签名规则生成 | e10adc3949ba59abbe56e057f20f883e |\n\n\n## 调用说明\n\n- `machid` 固定对应智慧餐厅 PC 端设备管理中的设备 SN；本项目咖啡机设备类型已独立配置。\n- `orderid` 为设备侧订单号，同一 `machid + orderid` 会复用已有预扣款订单，避免重复生成。\n- `price` 金额单位为分，例如 `1200` 表示 12.00 元。\n- 当前接口返回不包含 `trace_id` 字段；问题排查时请提供 `machid`、`orderid`、`torderid` 和接口调用时间。\n\n\n\n## 签名规则\n\n设备侧接口统一使用 `timestamp`、`randstr`、`sign` 做签名校验。\n\n1. 系统配置 `coffee_machine_appkey`，默认值：`1234567890abcdef`。\n2. 取 `appkey`、`timestamp`、`randstr` 三个字符串，按字典序升序排序。\n3. 将排序后的三个字符串直接拼接，不加分隔符。\n4. 对拼接结果计算 `sha1`，取小写十六进制字符串作为 `sign`。\n\n示例：\n\n```text\nappkey = 1234567890abcdef\ntimestamp = 1785218917\nrandstr = CQHW_RAND_A\nsign = sha1(sort(appkey,timestamp,randstr).join(''))\n```\n\n\n## 请求示例\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"machid\": \"CQHW_COFFEE_001\",\n  \"torderid\": \"10001\",\n  \"timestamp\": \"1785218919\",\n  \"randstr\": \"CQHW_RAND_C\",\n  \"sign\": \"按签名算法生成\",\n  \"status\": \"1\",\n  \"errinfo\": \"\"\n}\n```\n\n## 响应格式\n\n### 上报成功响应\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"torderid\": \"10001\",\n  \"code\": \"1\",\n  \"msg\": \"成功\"\n}\n```\n\n### 上报失败响应\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"torderid\": \"10001\",\n  \"code\": \"0\",\n  \"msg\": \"签名错误\"\n}\n```\n\n```json\n{\n  \"orderid\": \"260728144800001\",\n  \"torderid\": \"10001\",\n  \"code\": \"0\",\n  \"msg\": \"预扣款订单不存在\"\n}\n```\n\n## 状态码说明\n\n| code | 描述 |\n| --- | --- |\n| 1 | 系统接收并处理成功 |\n| 0 | 系统处理失败，失败原因见 `msg` |\n\n## 出货状态说明\n\n| status | 描述 | 系统处理 |\n| --- | --- | --- |\n| 1 | 出货成功 | 更新预扣款订单为已完成 `prepay_status=5`，出货状态为成功 |\n| 0 | 出货失败 | 记录 `errinfo`，出货状态为失败，预扣款订单交易状态保持原值 |\n\n## 响应字段说明\n\n| 字段名 | 类型 | 描述 |\n| --- | --- | --- |\n| orderid | String | 设备侧订单号 |\n| torderid | String | 智慧餐厅预扣款订单 ID |\n| code | String | 接口处理结果，`1` 成功、`0` 失败 |\n| msg | String | 响应消息，描述处理结果或失败原因 |\n\n## curl 示例\n\n```bash\ncurl --location --request POST 'https://xxx.com/api/prepayOrder/fulfillResult' \\\n  --header 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode 'orderid=260728144800001' \\\n  --data-urlencode 'machid=CQHW_COFFEE_001' \\\n  --data-urlencode 'torderid=10001' \\\n  --data-urlencode 'timestamp=1785218919' \\\n  --data-urlencode 'randstr=CQHW_RAND_C' \\\n  --data-urlencode 'sign=按签名算法生成' \\\n  --data-urlencode 'status=1' \\\n  --data-urlencode 'errinfo='\n```",
        "operationId": "reportPrepayOrderFulfillment",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PrepayFulfillRequest"
              },
              "examples": {
                "success": {
                  "summary": "出货成功",
                  "value": {
                    "orderid": "CQHW_E2E_20260728_ORDER_10001",
                    "machid": "CQHW_E2E_20260728_MACH_001",
                    "torderid": "5",
                    "status": "1",
                    "errinfo": "",
                    "timestamp": "1785218920",
                    "randstr": "CQHW_E2E_20260728_RAND_B",
                    "sign": "按签名算法生成"
                  }
                },
                "fail": {
                  "summary": "出货失败",
                  "value": {
                    "orderid": "CQHW_E2E_20260728_ORDER_10001",
                    "machid": "CQHW_E2E_20260728_MACH_001",
                    "torderid": "5",
                    "status": "0",
                    "errinfo": "设备出货失败",
                    "timestamp": "1785218920",
                    "randstr": "CQHW_E2E_20260728_RAND_B",
                    "sign": "按签名算法生成"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "报结果处理结果。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrepayFulfillResponse"
                },
                "examples": {
                  "success": {
                    "summary": "成功",
                    "value": {
                      "orderid": "CQHW_E2E_20260728_ORDER_10001",
                      "torderid": "5",
                      "code": "1",
                      "msg": "成功"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "MiniAppToken": {
        "type": "apiKey",
        "in": "header",
        "name": "Access-Token",
        "description": "小程序登录 token。"
      }
    },
    "schemas": {
      "PrepayCodeRequest": {
        "type": "object",
        "required": [
          "orderid",
          "machid",
          "timestamp",
          "randstr",
          "sign"
        ],
        "properties": {
          "orderid": {
            "type": "string",
            "description": "设备上传订单号。业务上用于幂等判断。",
            "maxLength": 64
          },
          "machid": {
            "type": "string",
            "description": "设备 machid，对应 ydy_equipment.sn。",
            "maxLength": 32
          },
          "trackno": {
            "type": "string",
            "description": "设备货道、轨道或商品编号。",
            "maxLength": 32
          },
          "name": {
            "type": "string",
            "description": "商品名称。",
            "maxLength": 128
          },
          "price": {
            "type": "integer",
            "description": "金额，单位分。",
            "minimum": 0,
            "example": 1200
          },
          "channelid": {
            "type": "string",
            "description": "设备或第三方支付渠道标识。",
            "maxLength": 16
          },
          "timestamp": {
            "type": "string",
            "description": "时间戳，参与签名。"
          },
          "randstr": {
            "type": "string",
            "description": "随机字符串，参与签名。"
          },
          "sign": {
            "type": "string",
            "description": "签名值：sha1(sort(appkey,timestamp,randstr) 后拼接)。"
          }
        }
      },
      "PrepayQueryRequest": {
        "type": "object",
        "required": [
          "orderid",
          "machid",
          "timestamp",
          "randstr",
          "sign"
        ],
        "properties": {
          "orderid": {
            "type": "string",
            "description": "设备上传订单号。"
          },
          "machid": {
            "type": "string",
            "description": "设备 machid。"
          },
          "torderid": {
            "type": "string",
            "description": "预扣款订单 ID。建议传入；传入时仍会校验 orderid 与 machid 是否匹配。"
          },
          "timestamp": {
            "type": "string",
            "description": "时间戳，参与签名。"
          },
          "randstr": {
            "type": "string",
            "description": "随机字符串，参与签名。"
          },
          "sign": {
            "type": "string",
            "description": "签名值：sha1(sort(appkey,timestamp,randstr) 后拼接)。"
          }
        }
      },
      "PrepayFulfillRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PrepayQueryRequest"
          },
          {
            "type": "object",
            "required": [
              "status"
            ],
            "properties": {
              "status": {
                "type": "integer",
                "description": "出货状态：1=成功，0=失败。",
                "enum": [
                  0,
                  1
                ]
              },
              "errinfo": {
                "type": "string",
                "description": "出货失败原因。",
                "maxLength": 500
              }
            }
          }
        ]
      },
      "PrepayCodeResponse": {
        "type": "object",
        "properties": {
          "orderid": {
            "type": "string",
            "description": "设备上传订单号。"
          },
          "torderid": {
            "type": "string",
            "description": "智慧餐厅预扣款订单 ID。"
          },
          "twocode": {
            "type": "string",
            "description": "返回给设备展示的二维码内容。"
          },
          "code": {
            "type": "string",
            "description": "1=成功，0=失败。"
          },
          "msg": {
            "type": "string",
            "description": "提示信息。"
          }
        }
      },
      "PrepayStatusResponse": {
        "type": "object",
        "properties": {
          "orderid": {
            "type": "string"
          },
          "torderid": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "0=失败，1=消费者付款成功，2=正在等待消费者付款，3=此次交易已过期，4=此次交易已关闭，5=此次交易已完成。",
            "enum": [
              "0",
              "1",
              "2",
              "3",
              "4",
              "5"
            ]
          },
          "msg": {
            "type": "string"
          }
        }
      },
      "PrepayFulfillResponse": {
        "type": "object",
        "properties": {
          "orderid": {
            "type": "string"
          },
          "torderid": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "1=接收成功，0=失败。"
          },
          "msg": {
            "type": "string"
          }
        }
      },
      "MiniAppResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "data": {
            "type": "object",
            "properties": {
              "orderId": {
                "type": "integer",
                "description": "生成或已绑定的 ydy_meal_order.id。"
              },
              "isPay": {
                "type": "integer",
                "description": "1=需要继续支付，0=无需支付或已支付。",
                "enum": [
                  0,
                  1
                ]
              }
            }
          }
        }
      }
    }
  }
}
