{
  "openapi": "3.0.3",
  "info": {
    "title": "VWCG-1072 访客财务成功流水接口",
    "version": "2026-07-28-v4",
    "description": "第三方财务按时间窗口逐笔拉取访客账户已经成功发生的充值、消费、退款和提现流水，可按业务类型和手机号筛选。接口不汇总订单，现金和补贴分别返回；保留已删除访客的历史账，不属于四类业务方向的历史异常流水不返回。"
  },
  "paths": {
    "/api/finance/visitor/flows": {
      "get": {
        "tags": [],
        "summary": "访客成功账户流水逐笔查询",
        "description": "每天按 [start_time, end_time) 查询访客成功账户流水，可选 flow_type 和 mobile 筛选。一条现金或补贴账户流水对应一条结果，同一业务单同时发生现金和补贴变动时分别返回。充值、退款只返回正向金额，消费、提现只返回负向金额。首次查询传时间和可选筛选条件；后续页传上一页 next_cursor。page_size 只要求为正整数，不设置业务最大值。",
        "operationId": "visitorFinanceFlows",
        "parameters": [
          {
            "name": "account",
            "in": "header",
            "required": true,
            "description": "商户级 API 账号，对应 ydy_api_auth.account，必须满足 type=1、status=1 且在有效期内。",
            "schema": {
              "type": "string"
            },
            "example": "{{account-dev}}"
          },
          {
            "name": "pwd",
            "in": "header",
            "required": true,
            "description": "商户级 API 账号密码，对应 ydy_api_auth.pwd。",
            "schema": {
              "type": "string",
              "format": "password"
            },
            "example": "{{pwd-dev}}"
          },
          {
            "name": "key",
            "in": "header",
            "required": true,
            "description": "商户级 API 密钥，对应 ydy_api_auth.key。",
            "schema": {
              "type": "string",
              "format": "password"
            },
            "example": "{{key-dev}}"
          },
          {
            "name": "start_time",
            "in": "query",
            "required": false,
            "description": "首次查询必填，账户金额发生开始时间，包含该时刻。传 cursor 时可省略；若重复传入，必须与首屏一致。",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"
            },
            "example": "2026-07-26 00:00:00"
          },
          {
            "name": "end_time",
            "in": "query",
            "required": false,
            "description": "首次查询必填，账户金额发生结束时间，不包含该时刻。传 cursor 时可省略；若重复传入，必须与首屏一致。",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"
            },
            "example": "2026-07-27 00:00:00"
          },
          {
            "name": "flow_type",
            "in": "query",
            "required": false,
            "description": "可选业务类型。支持 recharge、consume、refund、cashout；多个值使用英文逗号分隔，为空表示全部。传 cursor 时可省略；若重复传入，必须与首屏类型集合一致。",
            "schema": {
              "type": "string",
              "pattern": "^(recharge|consume|refund|cashout)(,(recharge|consume|refund|cashout))*$"
            },
            "example": "consume,refund"
          },
          {
            "name": "mobile",
            "in": "query",
            "required": false,
            "description": "可选访客手机号，按人员手机号解析优先级精确匹配。传 cursor 时可省略；若重复传入，必须与首屏一致。",
            "schema": {
              "type": "string"
            },
            "example": "13800000000"
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "本页最多返回的原始流水条数，默认 200，最小 1，不设置业务最大值，服务端不静默截断。",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 200
            },
            "example": 200
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "首次查询不传；后续分页原样传上一页 next_cursor。游标有效期 24 小时，并绑定商户、首屏时间窗口、flow_type、mobile、流水高水位、首屏访客账户集合和提现成功明细集合。",
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{48}$"
            },
            "example": "0123456789abcdef0123456789abcdef0123456789abcdef"
          }
        ],
        "responses": {
          "200": {
            "description": "查询成功时 code=0；前置认证失败沿用现有接口外壳，可能以 HTTP 200、code=1 返回。",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/VisitorFinanceSuccessResponseV2"
                    },
                    {
                      "$ref": "#/components/schemas/VisitorFinanceErrorResponseV2"
                    }
                  ]
                },
                "examples": {
                  "success": {
                    "summary": "同一消费单现金和补贴分别逐笔返回",
                    "value": {
                      "code": 0,
                      "message": "查询成功",
                      "data": {
                        "total": 2,
                        "has_more": false,
                        "next_cursor": null,
                        "list": [
                          {
                            "flow_no": "VF0123456789ABCDEF0123456789ABCD",
                            "flow_type": "consume",
                            "fund_type": "cash",
                            "person_name": "示例访客",
                            "mobile": "13800000000",
                            "amount": "-8.00",
                            "occur_time": "2026-07-26 12:00:00",
                            "order_no": "MEAL-DEMO-001",
                            "recharge_method": null,
                            "restaurant_name": "示例食堂",
                            "stall_name": "示例档口"
                          },
                          {
                            "flow_no": "VFABCDEF0123456789ABCDEF01234567",
                            "flow_type": "consume",
                            "fund_type": "subsidy",
                            "person_name": "示例访客",
                            "mobile": "13800000000",
                            "amount": "-2.00",
                            "occur_time": "2026-07-26 12:00:00",
                            "order_no": "MEAL-DEMO-001",
                            "recharge_method": null,
                            "restaurant_name": "示例食堂",
                            "stall_name": "示例档口"
                          }
                        ]
                      },
                      "trace_id": "6a671d7d5539d"
                    }
                  },
                  "authenticationFailed": {
                    "summary": "认证失败",
                    "value": {
                      "code": 1,
                      "message": "接口认证失败",
                      "data": [],
                      "time": "1785142653",
                      "trace_id": "6a671d7d5539d"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "参数、游标或一卡通 business 配置异常。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VisitorFinanceErrorResponseV2"
                }
              }
            }
          },
          "403": {
            "description": "认证账号有效但不是 type=1 商户级账号。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VisitorFinanceErrorResponseV2"
                }
              }
            }
          },
          "500": {
            "description": "服务内部查询失败。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VisitorFinanceErrorResponseV2"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "VisitorFinanceSuccessResponseV2": {
        "type": "object",
        "required": [
          "code",
          "message",
          "data"
        ],
        "properties": {
          "code": {
            "type": "integer",
            "enum": [
              0
            ]
          },
          "message": {
            "type": "string",
            "enum": [
              "查询成功"
            ]
          },
          "data": {
            "$ref": "#/components/schemas/VisitorFlowPageV2"
          },
          "trace_id": {
            "type": "string",
            "description": "请求追踪标识。"
          }
        }
      },
      "VisitorFinanceErrorResponseV2": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "integer",
            "enum": [
              1
            ]
          },
          "message": {
            "type": "string"
          },
          "data": {
            "nullable": true,
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "array",
                "items": {}
              }
            ]
          },
          "time": {
            "type": "string",
            "nullable": true
          },
          "trace_id": {
            "type": "string"
          }
        }
      },
      "VisitorFlowPageV2": {
        "type": "object",
        "required": [
          "total",
          "has_more",
          "next_cursor",
          "list"
        ],
        "properties": {
          "total": {
            "type": "integer",
            "minimum": 0,
            "description": "首屏高水位快照内符合条件的原始账户流水总条数，不是订单数、人员数或汇总数。"
          },
          "has_more": {
            "type": "boolean",
            "description": "当前快照是否还有下一页。"
          },
          "next_cursor": {
            "type": "string",
            "nullable": true,
            "pattern": "^[a-f0-9]{48}$",
            "description": "下一页不透明游标；末页为 null。"
          },
          "list": {
            "type": "array",
            "description": "逐笔成功账户流水。现金和补贴分别占一条，不做汇总。",
            "items": {
              "$ref": "#/components/schemas/VisitorFlowItemV2"
            }
          }
        }
      },
      "VisitorFlowItemV2": {
        "type": "object",
        "description": "固定返回 11 个字段。不适用或没有业务单号的字段返回 JSON null。",
        "required": [
          "flow_no",
          "flow_type",
          "fund_type",
          "person_name",
          "mobile",
          "amount",
          "occur_time",
          "order_no",
          "recharge_method",
          "restaurant_name",
          "stall_name"
        ],
        "properties": {
          "flow_no": {
            "type": "string",
            "pattern": "^VF[A-F0-9]{30}$",
            "description": "单笔账户流水稳定唯一编号，第三方用于幂等去重。"
          },
          "flow_type": {
            "type": "string",
            "enum": [
              "recharge",
              "consume",
              "refund",
              "cashout"
            ],
            "description": "充值、消费、退款或提现。"
          },
          "fund_type": {
            "type": "string",
            "enum": [
              "cash",
              "subsidy"
            ],
            "description": "现金余额或补贴余额。"
          },
          "person_name": {
            "$ref": "#/components/schemas/NullableStringV2"
          },
          "mobile": {
            "$ref": "#/components/schemas/NullableStringV2"
          },
          "amount": {
            "$ref": "#/components/schemas/MoneyStringV2"
          },
          "occur_time": {
            "$ref": "#/components/schemas/DateTimeStringV2"
          },
          "order_no": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NullableStringV2"
              }
            ],
            "description": "当前资金变动对应的充值单、餐单、退款单或提现主单号；业务没有原始单号或无法关联时为 null。"
          },
          "recharge_method": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NullableStringV2"
              }
            ],
            "description": "仅现金充值返回充值方式，其他业务为 null。"
          },
          "restaurant_name": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NullableStringV2"
              }
            ],
            "description": "消费对应食堂；餐饮退款可按原餐单回填，其他业务为 null。"
          },
          "stall_name": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NullableStringV2"
              }
            ],
            "description": "消费对应档口；餐饮退款可按原餐单回填，其他业务为 null。"
          }
        }
      },
      "MoneyStringV2": {
        "type": "string",
        "pattern": "^-?(0|[1-9]\\d*)\\.\\d{2}$",
        "description": "账户实际变动金额。充值、退款为正，消费、提现为负；使用两位小数字符串避免浮点误差。",
        "example": "-8.00"
      },
      "NullableStringV2": {
        "type": "string",
        "nullable": true,
        "description": "业务不适用或无法关联时为 null，不使用空字符串。"
      },
      "DateTimeStringV2": {
        "type": "string",
        "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
        "description": "账户流水实际写入时间。",
        "example": "2026-07-26 12:00:00"
      }
    }
  }
}
