{
  "openapi": "3.1.0",
  "info": {
    "title": "UniPay 商户对接 API",
    "version": "1.0.0",
    "description": "易支付 v1 收款和独立支付宝付款。收款 money 是元字符串，付款 amount_cents 是整数分；两套密钥不可混用。公开文档 /docs，AI 全文 /llms-full.txt。版本号标识文档契约，不是部署镜像版本。"
  },
  "servers": [
    {
      "url": "/",
      "description": "当前部署源站；离线导入工具时替换为商户后台网关基础地址。"
    }
  ],
  "externalDocs": {
    "url": "/docs",
    "description": "完整签名和业务处理指南"
  },
  "tags": [
    {
      "name": "收款",
      "description": "易支付 v1 收款、浏览器收银台和服务端查单。"
    },
    {
      "name": "付款",
      "description": "独立 HMAC 签名的支付宝付款和持久化状态查询。"
    },
    {
      "name": "状态",
      "description": "无需认证的进程存活检查。"
    }
  ],
  "paths": {
    "/submit.php": {
      "get": {
        "operationId": "submitPaymentGet",
        "tags": [
          "收款"
        ],
        "summary": "浏览器跳转支付",
        "description": "按易支付 v1 签名后 URL 编码。",
        "parameters": [
          {
            "name": "pid",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "商户 PID，非支付宝 APPID。",
              "minLength": 1
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "商户需配置并启用对应产品；alipay 在手机浏览器优先使用已启用 WAP。",
              "enum": [
                "alipay",
                "alipay_page",
                "alipay_wap"
              ]
            }
          },
          {
            "name": "out_trade_no",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "商户业务订单号。同商户待支付订单复用原参数；过期或失败单重新激活；已支付单返回 400。",
              "minLength": 1
            }
          },
          {
            "name": "notify_url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "业务系统接收 GET 异步通知的公网 HTTP(S) 地址，推荐 HTTPS，不要自带查询参数。",
              "format": "uri"
            }
          },
          {
            "name": "return_url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "买家支付成功后的业务页面 URL。浏览器返回不能代替服务器确认入账。",
              "format": "uri"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "商品名称。",
              "minLength": 1
            }
          },
          {
            "name": "money",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "正数人民币元字符串，最多两位小数。",
              "pattern": "^\\d+(\\.\\d{1,2})?$",
              "examples": [
                "12.34"
              ]
            }
          },
          {
            "name": "sign",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "移除 sign、sign_type 和空值，按参数名 ASCII 排序原始值，用 & 连接 k=v 后直接追加收款 key，UTF-8 MD5 小写十六进制。签名后再 URL 编码。",
              "pattern": "^[a-fA-F0-9]{32}$"
            }
          },
          {
            "name": "sign_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "按易支付 v1 协议发送 MD5。",
              "enum": [
                "MD5"
              ]
            }
          }
        ],
        "responses": {
          "302": {
            "description": "引导买家浏览器到收银台，不代表支付成功。",
            "headers": {
              "Location": {
                "description": "/cashier/{trade_no}",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "缺少参数、签名错误、商户不可用、非法金额或订单已支付。",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "examples": [
                    "bad sign",
                    "illegal money",
                    "order already paid"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "按 PID + 来源 IP 每分钟最多 30 次提交。",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "结果不确定，先用原业务单号查询。",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "callbacks": {
          "paymentResult": {
            "{$request.query.notify_url}": {
              "get": {
                "summary": "收款成功异步通知",
                "description": "使用商户收款 key 对通知参数按易支付 MD5 验签。核对 PID、业务订单和金额，事务内仅入账一次。首次立即投递，失败后按 1m/5m/15m/1h/6h 重试；可能重复通知。",
                "parameters": [
                  {
                    "name": "pid",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "商户 PID，非支付宝 APPID。",
                      "minLength": 1
                    }
                  },
                  {
                    "name": "type",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "原订单的支付类型。"
                    }
                  },
                  {
                    "name": "out_trade_no",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "商户业务订单号。同商户待支付订单复用原参数；过期或失败单重新激活；已支付单返回 400。",
                      "minLength": 1
                    }
                  },
                  {
                    "name": "name",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "商品名称。",
                      "minLength": 1
                    }
                  },
                  {
                    "name": "money",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "正数人民币元字符串，最多两位小数。",
                      "pattern": "^\\d+(\\.\\d{1,2})?$",
                      "examples": [
                        "12.34"
                      ]
                    }
                  },
                  {
                    "name": "sign",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "移除 sign、sign_type 和空值，按参数名 ASCII 排序原始值，用 & 连接 k=v 后直接追加收款 key，UTF-8 MD5 小写十六进制。签名后再 URL 编码。",
                      "pattern": "^[a-fA-F0-9]{32}$"
                    }
                  },
                  {
                    "name": "sign_type",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "按易支付 v1 协议发送 MD5。",
                      "enum": [
                        "MD5"
                      ]
                    }
                  },
                  {
                    "name": "trade_no",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "UniPay 平台订单号。"
                    }
                  },
                  {
                    "name": "trade_status",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "const": "TRADE_SUCCESS"
                    }
                  }
                ],
                "responses": {
                  "200": {
                    "description": "验签、核对订单金额并持久化幂等处理后确认。正文只返回 success。",
                    "content": {
                      "text/plain": {
                        "schema": {
                          "type": "string",
                          "const": "success"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "submitPaymentPost",
        "tags": [
          "收款"
        ],
        "summary": "浏览器表单支付",
        "description": "接收 URL 编码表单，不接收 JSON。",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PaymentSubmit"
              }
            }
          }
        },
        "responses": {
          "302": {
            "description": "引导买家浏览器到收银台，不代表支付成功。",
            "headers": {
              "Location": {
                "description": "/cashier/{trade_no}",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "缺少参数、签名错误、商户不可用、非法金额或订单已支付。",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "examples": [
                    "bad sign",
                    "illegal money",
                    "order already paid"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "按 PID + 来源 IP 每分钟最多 30 次提交。",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "结果不确定，先用原业务单号查询。",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "callbacks": {
          "paymentResult": {
            "{$request.body#/notify_url}": {
              "get": {
                "summary": "收款成功异步通知",
                "description": "使用商户收款 key 对通知参数按易支付 MD5 验签。核对 PID、业务订单和金额，事务内仅入账一次。首次立即投递，失败后按 1m/5m/15m/1h/6h 重试；可能重复通知。",
                "parameters": [
                  {
                    "name": "pid",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "商户 PID，非支付宝 APPID。",
                      "minLength": 1
                    }
                  },
                  {
                    "name": "type",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "原订单的支付类型。"
                    }
                  },
                  {
                    "name": "out_trade_no",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "商户业务订单号。同商户待支付订单复用原参数；过期或失败单重新激活；已支付单返回 400。",
                      "minLength": 1
                    }
                  },
                  {
                    "name": "name",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "商品名称。",
                      "minLength": 1
                    }
                  },
                  {
                    "name": "money",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "正数人民币元字符串，最多两位小数。",
                      "pattern": "^\\d+(\\.\\d{1,2})?$",
                      "examples": [
                        "12.34"
                      ]
                    }
                  },
                  {
                    "name": "sign",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "移除 sign、sign_type 和空值，按参数名 ASCII 排序原始值，用 & 连接 k=v 后直接追加收款 key，UTF-8 MD5 小写十六进制。签名后再 URL 编码。",
                      "pattern": "^[a-fA-F0-9]{32}$"
                    }
                  },
                  {
                    "name": "sign_type",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "按易支付 v1 协议发送 MD5。",
                      "enum": [
                        "MD5"
                      ]
                    }
                  },
                  {
                    "name": "trade_no",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "description": "UniPay 平台订单号。"
                    }
                  },
                  {
                    "name": "trade_status",
                    "in": "query",
                    "required": true,
                    "schema": {
                      "type": "string",
                      "const": "TRADE_SUCCESS"
                    }
                  }
                ],
                "responses": {
                  "200": {
                    "description": "验签、核对订单金额并持久化幂等处理后确认。正文只返回 success。",
                    "content": {
                      "text/plain": {
                        "schema": {
                          "type": "string",
                          "const": "success"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api.php": {
      "get": {
        "operationId": "queryPayment",
        "tags": [
          "收款"
        ],
        "summary": "按业务订单号查询收款",
        "description": "仅支持 act=order + out_trade_no，不支持 trade_no。只在服务端经 HTTPS 调用，URL 含密钥，禁止写入日志。HTTP 200 仍需检查 code=1 且 trade_status=TRADE_SUCCESS；其他内部订单状态均映射为 WAIT_BUYER_PAY。",
        "security": [
          {
            "EpayQueryKey": []
          }
        ],
        "parameters": [
          {
            "name": "act",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "const": "order"
            }
          },
          {
            "name": "pid",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "out_trade_no",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "成功或业务错误均为 HTTP 200。",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PaymentQueryResult"
                    },
                    {
                      "$ref": "#/components/schemas/PaymentQueryError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/payouts": {
      "post": {
        "operationId": "createPayout",
        "tags": [
          "付款"
        ],
        "summary": "受理支付宝付款",
        "description": "签名字符串由 LF 连接且末尾无换行：unipay-payout-v1、PID、TIMESTAMP、NONCE、POST、PATH、SHA256_HEX(实际 JSON 正文字节)。PATH 不含域名和查询字符串。使用付款 API 密钥的 UTF-8 字节做 HMAC-SHA256；不要 hex-decode 密钥，也不要签名后重新序列化正文。每次重试更新 timestamp/nonce/签名，保留原业务单号和参数。 JSON 最大 64 KiB；不接受未知字段。202 仅表示受理。超时/5xx/processing/查无此单均不是失败，不得另起单号打款。",
        "security": [
          {
            "PayoutSignature": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PayoutPid"
          },
          {
            "$ref": "#/components/parameters/PayoutTimestamp"
          },
          {
            "$ref": "#/components/parameters/PayoutNonce"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePayout"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "已持久化并排队，尚未确认付款成功。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutResult"
                }
              }
            }
          },
          "200": {
            "description": "同单同参数的原记录。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutResult"
                }
              }
            }
          },
          "400": {
            "description": "字段无效、超过商户单笔限额或配置无效。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "401": {
            "description": "商户、密钥、签名或时间戳无效。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "403": {
            "description": "付款关闭。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "409": {
            "description": "nonce 重复，或业务单号对应不同参数。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "429": {
            "description": "每商户付款与查询合计每分钟 30 次。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "500": {
            "description": "结果不确定，保持原业务单号查询或重试。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "413": {
            "description": "正文超过 64 KiB。",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "callbacks": {
          "payoutResult": {
            "{$request.body#/notify_url}": {
              "post": {
                "summary": "付款终态通知",
                "description": "只通知 succeeded/failed。签名字符串为 LF 连接的 unipay-payout-notify-v1、PID、TIMESTAMP、NONCE、SHA256_HEX(正文)，末尾无换行。HMAC 使用受理时的付款密钥，即使之后已重置；通过 X-Unipay-Key-Id 选择密钥。检查时间偏差 300 秒，验签并核对订单金额，在事务中幂等处理后回应 success。最多投递 10 次。",
                "security": [
                  {
                    "PayoutNotificationSignature": []
                  }
                ],
                "parameters": [
                  {
                    "$ref": "#/components/parameters/PayoutPid"
                  },
                  {
                    "$ref": "#/components/parameters/PayoutTimestamp"
                  },
                  {
                    "$ref": "#/components/parameters/PayoutNonce"
                  },
                  {
                    "$ref": "#/components/parameters/PayoutKeyId"
                  }
                ],
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/PayoutNotification"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "验签、核对订单金额并持久化幂等处理后确认。正文只返回 success。",
                    "content": {
                      "text/plain": {
                        "schema": {
                          "type": "string",
                          "const": "success"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/payouts/query": {
      "post": {
        "operationId": "queryPayout",
        "tags": [
          "付款"
        ],
        "summary": "按业务提现单号查询付款",
        "description": "签名字符串由 LF 连接且末尾无换行：unipay-payout-v1、PID、TIMESTAMP、NONCE、POST、PATH、SHA256_HEX(实际 JSON 正文字节)。PATH 不含域名和查询字符串。使用付款 API 密钥的 UTF-8 字节做 HMAC-SHA256；不要 hex-decode 密钥，也不要签名后重新序列化正文。每次重试更新 timestamp/nonce/签名，保留原业务单号和参数。 返回持久化状态；后台独立向支付宝查单。非终态不自动超时失败。",
        "security": [
          {
            "PayoutSignature": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PayoutPid"
          },
          {
            "$ref": "#/components/parameters/PayoutTimestamp"
          },
          {
            "$ref": "#/components/parameters/PayoutNonce"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryPayout"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "仅 succeeded 和 failed 是终态。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutResult"
                }
              }
            }
          },
          "400": {
            "description": "字段无效、超过商户单笔限额或配置无效。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "401": {
            "description": "商户、密钥、签名或时间戳无效。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "404": {
            "description": "当前商户查不到该付款。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "409": {
            "description": "nonce 重复，或业务单号对应不同参数。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "429": {
            "description": "每商户付款与查询合计每分钟 30 次。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "500": {
            "description": "结果不确定，保持原业务单号查询或重试。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutError"
                }
              }
            }
          },
          "413": {
            "description": "正文超过 64 KiB。",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/healthz": {
      "get": {
        "operationId": "healthz",
        "tags": [
          "状态"
        ],
        "summary": "进程存活检查",
        "description": "不访问数据库，不能用于确认支付宝通道是否可用。",
        "responses": {
          "200": {
            "description": "进程运行中。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "const": "ok"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "PayoutPid": {
        "name": "X-Unipay-Pid",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "maxLength": 64
        },
        "description": "商户 PID。"
      },
      "PayoutTimestamp": {
        "name": "X-Unipay-Timestamp",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "pattern": "^[0-9]+$",
          "maxLength": 16
        },
        "description": "Unix 秒时间戳，允许前后 300 秒偏差。"
      },
      "PayoutNonce": {
        "name": "X-Unipay-Nonce",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{16,64}$"
        },
        "description": "每次 HTTP 请求使用新 nonce，重试也要更新。"
      },
      "PayoutKeyId": {
        "name": "X-Unipay-Key-Id",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "pattern": "^[a-f0-9]{12}$"
        },
        "description": "通知签名密钥 UTF-8 字节 SHA256 前 12 位，用于选择旧/新密钥。"
      }
    },
    "schemas": {
      "PaymentSubmit": {
        "type": "object",
        "required": [
          "pid",
          "type",
          "out_trade_no",
          "notify_url",
          "return_url",
          "name",
          "money",
          "sign"
        ],
        "properties": {
          "pid": {
            "type": "string",
            "description": "商户 PID，非支付宝 APPID。",
            "minLength": 1
          },
          "type": {
            "type": "string",
            "description": "商户需配置并启用对应产品；alipay 在手机浏览器优先使用已启用 WAP。",
            "enum": [
              "alipay",
              "alipay_page",
              "alipay_wap"
            ]
          },
          "out_trade_no": {
            "type": "string",
            "description": "商户业务订单号。同商户待支付订单复用原参数；过期或失败单重新激活；已支付单返回 400。",
            "minLength": 1
          },
          "notify_url": {
            "type": "string",
            "description": "业务系统接收 GET 异步通知的公网 HTTP(S) 地址，推荐 HTTPS，不要自带查询参数。",
            "format": "uri"
          },
          "return_url": {
            "type": "string",
            "description": "买家支付成功后的业务页面 URL。浏览器返回不能代替服务器确认入账。",
            "format": "uri"
          },
          "name": {
            "type": "string",
            "description": "商品名称。",
            "minLength": 1
          },
          "money": {
            "type": "string",
            "description": "正数人民币元字符串，最多两位小数。",
            "pattern": "^\\d+(\\.\\d{1,2})?$",
            "examples": [
              "12.34"
            ]
          },
          "sign": {
            "type": "string",
            "description": "移除 sign、sign_type 和空值，按参数名 ASCII 排序原始值，用 & 连接 k=v 后直接追加收款 key，UTF-8 MD5 小写十六进制。签名后再 URL 编码。",
            "pattern": "^[a-fA-F0-9]{32}$"
          },
          "sign_type": {
            "type": "string",
            "description": "按易支付 v1 协议发送 MD5。",
            "enum": [
              "MD5"
            ]
          }
        },
        "additionalProperties": {
          "type": "string"
        },
        "description": "额外非空参数也必须参与 MD5 签名。按协议发送 sign_type=MD5。"
      },
      "PaymentQueryResult": {
        "type": "object",
        "required": [
          "code",
          "trade_no",
          "out_trade_no",
          "type",
          "name",
          "money",
          "trade_status",
          "addtime",
          "endtime"
        ],
        "properties": {
          "code": {
            "type": "integer",
            "const": 1
          },
          "trade_no": {
            "type": "string"
          },
          "out_trade_no": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "money": {
            "type": "string",
            "description": "人民币元，固定两位小数。",
            "examples": [
              "12.34"
            ]
          },
          "trade_status": {
            "type": "string",
            "enum": [
              "TRADE_SUCCESS",
              "WAIT_BUYER_PAY"
            ]
          },
          "addtime": {
            "type": "string",
            "description": "UTC，YYYY-MM-DD HH:mm:ss。"
          },
          "endtime": {
            "type": "string",
            "description": "付款 UTC 时间，YYYY-MM-DD HH:mm:ss；未付款为空字符串。"
          }
        }
      },
      "PaymentQueryError": {
        "type": "object",
        "required": [
          "code",
          "msg"
        ],
        "properties": {
          "code": {
            "type": "integer",
            "enum": [
              -1,
              -2,
              -4
            ]
          },
          "msg": {
            "type": "string",
            "enum": [
              "key error",
              "unsupported act",
              "order not found"
            ]
          }
        }
      },
      "CreatePayout": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "out_biz_no",
          "amount_cents",
          "payee_account",
          "payee_name",
          "title",
          "notify_url",
          "transfer_scene_name"
        ],
        "properties": {
          "out_biz_no": {
            "type": "string",
            "description": "同商户唯一，重试必须复用。同单同参数返回原结果；改动任意参数返回 409。",
            "pattern": "^[A-Za-z0-9_-]{1,64}$"
          },
          "amount_cents": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "maximum": 100000000,
            "description": "人民币整数分，还须不超过商户单笔限额。"
          },
          "payee_account": {
            "type": "string",
            "description": "收款人的支付宝登录账号（邮箱或手机号）。",
            "minLength": 1,
            "maxLength": 100
          },
          "payee_name": {
            "type": "string",
            "description": "收款人实名。",
            "minLength": 1,
            "maxLength": 100
          },
          "title": {
            "type": "string",
            "description": "转账标题。",
            "minLength": 1,
            "maxLength": 100
          },
          "notify_url": {
            "type": "string",
            "description": "公网 HTTPS 回调，不允许私网/回环地址、userinfo、片段或重定向；最长 2048 UTF-8 字节。",
            "format": "uri",
            "maxLength": 2048
          },
          "transfer_scene_name": {
            "type": "string",
            "description": "支付宝签约的真实业务场景，不可使用占位示例直接实付。",
            "minLength": 1,
            "maxLength": 64
          },
          "transfer_scene_report_infos": {
            "type": "array",
            "maxItems": 10,
            "default": [],
            "items": {
              "$ref": "#/components/schemas/SceneReport"
            },
            "description": "按支付宝签约场景上报。"
          }
        },
        "description": "所有文本字段（除 URL）禁止首尾空白和控制字符。金额还需满足商户单笔限额，默认 10000 分。"
      },
      "QueryPayout": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "out_biz_no"
        ],
        "properties": {
          "out_biz_no": {
            "type": "string",
            "description": "已受理付款的业务提现单号。"
          }
        }
      },
      "SceneReport": {
        "type": "object",
        "required": [
          "info_type",
          "info_content"
        ],
        "properties": {
          "info_type": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "info_content": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300
          }
        }
      },
      "PayoutResult": {
        "type": "object",
        "required": [
          "payout_no",
          "out_biz_no",
          "amount_cents",
          "status",
          "channel_order_id",
          "failure_code",
          "created_at",
          "completed_at"
        ],
        "properties": {
          "payout_no": {
            "type": "string",
            "description": "UniPay 全局付款号，作为支付宝 out_biz_no。"
          },
          "out_biz_no": {
            "type": "string",
            "description": "商户业务提现单号。"
          },
          "amount_cents": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "description": "人民币整数分。"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "processing",
              "succeeded",
              "failed"
            ],
            "description": "queued/processing 保持冻结；succeeded 扣款一次；仅 failed 可解冻一次。"
          },
          "channel_order_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "failure_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "processing 时仅为诊断信息，不是解冻依据。"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "PayoutNotification": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PayoutResult"
          },
          {
            "type": "object",
            "required": [
              "pid"
            ],
            "properties": {
              "pid": {
                "type": "string"
              }
            }
          }
        ]
      },
      "PayoutError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      }
    },
    "securitySchemes": {
      "EpayQueryKey": {
        "type": "apiKey",
        "in": "query",
        "name": "key",
        "description": "商户收款 key。仅服务端经 HTTPS 调用；隐藏 URL 日志。"
      },
      "PayoutSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Unipay-Signature",
        "description": "签名字符串由 LF 连接且末尾无换行：unipay-payout-v1、PID、TIMESTAMP、NONCE、POST、PATH、SHA256_HEX(实际 JSON 正文字节)。PATH 不含域名和查询字符串。使用付款 API 密钥的 UTF-8 字节做 HMAC-SHA256；不要 hex-decode 密钥，也不要签名后重新序列化正文。每次重试更新 timestamp/nonce/签名，保留原业务单号和参数。 头值是计算后的 64 位十六进制签名，不是原始 API 密钥。"
      },
      "PayoutNotificationSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Unipay-Signature",
        "description": "受理时的付款密钥对 unipay-payout-notify-v1、PID、TIMESTAMP、NONCE、SHA256_HEX(正文) 以 LF 拼接后做 HMAC-SHA256，末尾无换行；64 位十六进制。"
      }
    }
  },
  "security": []
}
