import type { CSSProperties } from 'react'
import { Alert, Card, Collapse, Descriptions, Space, Table, Tabs, Tag, Typography } from 'antd'
import EndpointDoc, { CommonResponseDoc } from '../openapi/EndpointDoc'
import {
commonResponseFields,
endpoints,
errorCodes,
orderStatusTable,
paymentStatusTable,
} from '../openapi/endpoints'
const { Title, Paragraph, Text } = Typography
const baseUrl =
typeof window !== 'undefined'
? window.location.origin.replace(':5173', ':8080')
: 'http://localhost:8080'
const preStyle: CSSProperties = {
margin: 0,
padding: 12,
background: '#f6f8fa',
borderRadius: 6,
fontSize: 12.5,
lineHeight: 1.6,
overflow: 'auto',
whiteSpace: 'pre-wrap',
wordBreak: 'break-all',
}
export default function OpenApiDocs() {
return (
开放接口
面向商户系统、履约器和外部平台调用的通用开放 API。凭证在「商户中心 / API 客户端」创建,
采用 X-App-Key + HMAC-SHA256 签名鉴权。
原 /api/open/v1 保留给上游发货对接,不在本页展示。
,
},
{
key: 'auth',
label: '鉴权与签名',
children:
,
},
{
key: 'endpoints',
label: '接口列表',
children:
,
},
{
key: 'status',
label: '状态说明',
children:
,
},
]}
/>
)
}
function OverviewTab() {
return (
在「商户中心 / API 客户端」创建凭证,获得 AppKey 与 AppSecret。
每次请求携带 X-App-Key / X-Timestamp / X-Nonce / X-Sign 四个鉴权头。
调用「商品列表」拿到可售 sku,调用「下单」创建订单并扣款。
履约器通过「发货回传」回写 processing/success/failed,状态可由「查询订单」轮询。
}
/>
{baseUrl}
X-App-Key、X-Timestamp、X-Nonce、X-Sign
允许 ±300 秒
POST 请求使用 application/json
)
}
function AuthTab() {
return (
{v} },
{ title: '必填', dataIndex: 'required', width: 80, render: (v) => v ? 是 : 否 },
{ title: '说明', dataIndex: 'desc' },
]}
/>
{'timestamp\nnonce\nMETHOD\npath\nsha256(body)'}
按固定顺序,用换行符 \n 拼接
大写,如 GET / POST
仅 URL.Path,不含域名和 query
GET 为空字节;POST 必须与实际发送 body 完全一致
hex( HMAC-SHA256( app_secret, 签名内容 ) ),小写十六进制
{`timestamp
nonce
GET
/api/client/v1/products
sha256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`}
{`timestamp
nonce
POST
/api/client/v1/orders
sha256(body) = <实际请求 body 字节的 SHA256 十六进制>`}
POST 签名用的 body 必须与实际发送的 body 字节级一致,不要签名后再改空格或字段顺序。
签名失败常见原因:secret 错、path 多了 query、body 不一致、时间戳过期、nonce 重复。
下单接口还需携带 Idempotency-Key,且必须与 client_order_no 一致。
}
/>
)
}
function EndpointsTab() {
return (
({
key: spec.key,
label: (
{spec.method}
{spec.path}
{spec.summary}
),
children: ,
}))}
/>
)
}
function StatusTab() {
return (
{v} },
{
title: 'can_fulfill',
dataIndex: 'example',
width: 160,
render: (v: string) =>
v === 'can_fulfill=true' ? true : false,
},
{ title: '说明', dataIndex: 'desc' },
]}
/>
{v} },
{ title: '说明', dataIndex: 'desc' },
]}
/>
{`拿到 sku(商品列表)
↓
POST /orders 下单(幂等,Idempotency-Key = client_order_no)
↓
(履约器)POST /orders/{order_no}/ship-notify ship_status=processing
↓
按 product.sku 发货
↓
POST /orders/{order_no}/ship-notify ship_status=success 或 failed
↓
(可选)GET /orders/{order_no} 轮询确认 fulfillment_status=succeeded`}
}
/>
)
}