补开放接口文档
This commit is contained in:
@@ -85,6 +85,68 @@ const orderResponseExample = `{
|
|||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
|
const deliveryOrderResponseExample = `{
|
||||||
|
"code": 0,
|
||||||
|
"message": "ok",
|
||||||
|
"data": {
|
||||||
|
"order_no": "FO20260730000123",
|
||||||
|
"status": "paid",
|
||||||
|
"can_ship": true,
|
||||||
|
"cannot_ship_reason": "",
|
||||||
|
"product": { "name": "套装-糯粉咩咩", "sku": "suit_pink_sheep", "game": "和平精英" },
|
||||||
|
"buyer_name": "buyer-001",
|
||||||
|
"amount": 105,
|
||||||
|
"created_at": "2026-07-30T10:00:00+08:00",
|
||||||
|
"shipped_at": null,
|
||||||
|
"ship_fail_reason": "",
|
||||||
|
"game_channel": "安卓-QQ",
|
||||||
|
"game_uid": "4808146277",
|
||||||
|
"role_name": "巫师哈丁12",
|
||||||
|
"pay_score": 360,
|
||||||
|
"good": { "title": "套装-糯粉咩咩", "image": "https://..." }
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
const deliveryLinkResponseExample = `{
|
||||||
|
"code": 0,
|
||||||
|
"message": "ok",
|
||||||
|
"data": {
|
||||||
|
"order_no": "FO20260730000123",
|
||||||
|
"delivery_url": "https://shop.example/delivery/dlc/FO20260730000123?exp=1753934400&sign=...",
|
||||||
|
"expires_at": "2026-07-31T12:00:00Z",
|
||||||
|
"exp": 1753934400,
|
||||||
|
"sign": "..."
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
const deliveryBindResponseExample = `{
|
||||||
|
"code": 0,
|
||||||
|
"message": "ok",
|
||||||
|
"data": {
|
||||||
|
"bind_uuid": "bind-123",
|
||||||
|
"bind_url": "https://bind.example/qrcode",
|
||||||
|
"qr_url": "https://api.qrserver.com/v1/create-qr-code/?size=240x240&data=https%3A%2F%2Fbind.example%2Fqrcode"
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
const deliverySubmitResponseExample = `{
|
||||||
|
"code": 0,
|
||||||
|
"message": "ok",
|
||||||
|
"data": {
|
||||||
|
"order_no": "FO20260730000123",
|
||||||
|
"status": "processing",
|
||||||
|
"message": "已提交上游发货,等待发货结果回传",
|
||||||
|
"provider_order_no": "provider-1",
|
||||||
|
"game_account": {
|
||||||
|
"game_account": "4808146277",
|
||||||
|
"game_account_role_name": "巫师哈丁12"
|
||||||
|
},
|
||||||
|
"upstream_order": {
|
||||||
|
"order_no": "provider-1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
export const endpoints: EndpointSpec[] = [
|
export const endpoints: EndpointSpec[] = [
|
||||||
{
|
{
|
||||||
key: 'list-products',
|
key: 'list-products',
|
||||||
@@ -200,6 +262,109 @@ export const endpoints: EndpointSpec[] = [
|
|||||||
'已进入 processing/succeeded 的订单不可取消,返回 400。',
|
'已进入 processing/succeeded 的订单不可取消,返回 400。',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'delivery-link',
|
||||||
|
method: 'GET',
|
||||||
|
path: '/api/client/v1/orders/{order_no}/delivery-link',
|
||||||
|
summary: '获取签名发货链接,适合直接跳转平台 Web 发货页',
|
||||||
|
scope: 'orders:read + fulfillment:read',
|
||||||
|
pathParams: [{ name: 'order_no', type: 'string', required: true, desc: '平台订单号', example: 'FO20260730000123' }],
|
||||||
|
responseExample: deliveryLinkResponseExample,
|
||||||
|
responseFields: [
|
||||||
|
{ name: 'order_no', type: 'string', desc: '平台订单号' },
|
||||||
|
{ name: 'delivery_url', type: 'string', desc: '可直接打开的发货链接' },
|
||||||
|
{ name: 'expires_at', type: 'datetime', desc: '链接过期时间' },
|
||||||
|
{ name: 'exp', type: 'int', desc: '过期 Unix 秒时间戳' },
|
||||||
|
{ name: 'sign', type: 'string', desc: '签名,供链接校验使用' },
|
||||||
|
],
|
||||||
|
notes: [
|
||||||
|
'适合商户系统只想“返回一个链接”给终端用户的场景。',
|
||||||
|
'delivery_url 可以直接给用户打开,sign 仅供后端或调试使用,不建议展示。',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'delivery-order',
|
||||||
|
method: 'GET',
|
||||||
|
path: '/api/client/v1/orders/{order_no}/delivery',
|
||||||
|
summary: '查询发货页结构化数据,适合商户自建发货界面',
|
||||||
|
scope: 'orders:read + fulfillment:read',
|
||||||
|
pathParams: [{ name: 'order_no', type: 'string', required: true, desc: '平台订单号', example: 'FO20260730000123' }],
|
||||||
|
responseExample: deliveryOrderResponseExample,
|
||||||
|
responseFields: [
|
||||||
|
{ name: 'order_no', type: 'string', desc: '平台订单号' },
|
||||||
|
{ name: 'status', type: 'string', desc: '订单状态' },
|
||||||
|
{ name: 'can_ship', type: 'bool', desc: '是否可以发货' },
|
||||||
|
{ name: 'cannot_ship_reason', type: 'string', desc: '不可发货原因' },
|
||||||
|
{ name: 'product', type: 'object', desc: '商品信息' },
|
||||||
|
{ name: 'buyer_name', type: 'string', desc: '买家名称 / 备注' },
|
||||||
|
{ name: 'amount', type: 'int', desc: '订单金额' },
|
||||||
|
{ name: 'created_at', type: 'datetime', desc: '创建时间' },
|
||||||
|
{ name: 'shipped_at', type: 'datetime', desc: '发货时间' },
|
||||||
|
{ name: 'ship_fail_reason', type: 'string', desc: '最近一次失败原因' },
|
||||||
|
{ name: 'game_channel', type: 'string', desc: '区服渠道' },
|
||||||
|
{ name: 'game_uid', type: 'string', desc: 'UID / 角色编号' },
|
||||||
|
{ name: 'role_name', type: 'string', desc: '角色名' },
|
||||||
|
{ name: 'pay_score', type: 'int', desc: '消耗积分' },
|
||||||
|
{ name: 'good', type: 'object', desc: '上游商品详情' },
|
||||||
|
],
|
||||||
|
notes: [
|
||||||
|
'该接口返回的是结构化数据,适合商户自有页面渲染。',
|
||||||
|
'如果只是想直接给用户一个发货页链接,优先用 delivery-link。',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'delivery-bind',
|
||||||
|
method: 'POST',
|
||||||
|
path: '/api/client/v1/orders/{order_no}/delivery/bind',
|
||||||
|
summary: '发起绑定,返回绑定跳转链接与二维码地址',
|
||||||
|
scope: 'orders:write',
|
||||||
|
pathParams: [{ name: 'order_no', type: 'string', required: true, desc: '平台订单号', example: 'FO20260730000123' }],
|
||||||
|
bodyParams: [
|
||||||
|
{ name: 'game_account', type: 'string', required: true, desc: '玩家编号 / UID', example: '4808146277' },
|
||||||
|
],
|
||||||
|
requestExample: `{
|
||||||
|
"game_account": "4808146277"
|
||||||
|
}`,
|
||||||
|
responseExample: deliveryBindResponseExample,
|
||||||
|
responseFields: [
|
||||||
|
{ name: 'bind_uuid', type: 'string', desc: '绑定凭证,提交发货时使用' },
|
||||||
|
{ name: 'bind_url', type: 'string', desc: '绑定跳转地址' },
|
||||||
|
{ name: 'qr_url', type: 'string', desc: '绑定二维码地址' },
|
||||||
|
],
|
||||||
|
notes: [
|
||||||
|
'适合商户自建页面先让用户确认 UID,再去拿绑定结果。',
|
||||||
|
'同一订单重复绑定时,请以最新返回的绑定凭证为准。',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'delivery-submit',
|
||||||
|
method: 'POST',
|
||||||
|
path: '/api/client/v1/orders/{order_no}/delivery/submit',
|
||||||
|
summary: '提交发货到上游并进入履约中状态',
|
||||||
|
scope: 'orders:write',
|
||||||
|
pathParams: [{ name: 'order_no', type: 'string', required: true, desc: '平台订单号', example: 'FO20260730000123' }],
|
||||||
|
bodyParams: [
|
||||||
|
{ name: 'game_account', type: 'string', required: true, desc: '玩家编号 / UID', example: '4808146277' },
|
||||||
|
{ name: 'bind_uuid', type: 'string', required: true, desc: '绑定凭证', example: 'bind-123' },
|
||||||
|
],
|
||||||
|
requestExample: `{
|
||||||
|
"game_account": "4808146277",
|
||||||
|
"bind_uuid": "bind-123"
|
||||||
|
}`,
|
||||||
|
responseExample: deliverySubmitResponseExample,
|
||||||
|
responseFields: [
|
||||||
|
{ name: 'order_no', type: 'string', desc: '平台订单号' },
|
||||||
|
{ name: 'status', type: 'string', desc: '提交后的履约状态' },
|
||||||
|
{ name: 'message', type: 'string', desc: '处理结果说明' },
|
||||||
|
{ name: 'provider_order_no', type: 'string', desc: '上游订单号' },
|
||||||
|
{ name: 'game_account', type: 'object', desc: '上游绑定结果' },
|
||||||
|
{ name: 'upstream_order', type: 'object', desc: '上游创建结果' },
|
||||||
|
],
|
||||||
|
notes: [
|
||||||
|
'同一订单重复提交应直接返回已有结果,不应重复创建上游队列。',
|
||||||
|
'提交成功后,最终成功/失败仍以 `ship_notify` 回传结果为准。',
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'get-wallet',
|
key: 'get-wallet',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|||||||
@@ -28,6 +28,20 @@ const preStyle: CSSProperties = {
|
|||||||
wordBreak: 'break-all',
|
wordBreak: 'break-all',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deliveryModes = [
|
||||||
|
{
|
||||||
|
mode: 'Web 发货页',
|
||||||
|
scene: '商户想要“只返回一个链接”,让用户直接打开平台页面填写 UID',
|
||||||
|
interfaces: '/api/client/v1/orders/{order_no}/delivery-link',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mode: '自建发货页',
|
||||||
|
scene: '商户自己有前端页面,想在自己的系统里完成发货流程',
|
||||||
|
interfaces:
|
||||||
|
'/api/client/v1/orders/{order_no}/delivery\n/api/client/v1/orders/{order_no}/delivery/bind\n/api/client/v1/orders/{order_no}/delivery/submit',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
export default function OpenApiDocs() {
|
export default function OpenApiDocs() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -37,10 +51,13 @@ export default function OpenApiDocs() {
|
|||||||
<Paragraph type="secondary">
|
<Paragraph type="secondary">
|
||||||
面向商户系统调用的开放 API。凭证在「商户中心 / API 客户端」创建,
|
面向商户系统调用的开放 API。凭证在「商户中心 / API 客户端」创建,
|
||||||
采用 <Text code>X-App-Key</Text> + HMAC-SHA256 签名鉴权。
|
采用 <Text code>X-App-Key</Text> + HMAC-SHA256 签名鉴权。
|
||||||
<Text code>/api/open/v1</Text> 仅保留给发货平台查询与回传,不在本页展示。
|
发货链路同时支持「返回签名链接」和「返回结构化数据」两种模式。
|
||||||
|
<Text code>/api/open/v1</Text> 仍是上游回调链路,和本页的商户 API 分开。
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
|
|
||||||
<Tabs
|
<Tabs
|
||||||
|
tabPosition="left"
|
||||||
|
style={{ minHeight: 680 }}
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
key: 'overview',
|
key: 'overview',
|
||||||
@@ -57,6 +74,11 @@ export default function OpenApiDocs() {
|
|||||||
label: '接口列表',
|
label: '接口列表',
|
||||||
children: <EndpointsTab />,
|
children: <EndpointsTab />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'delivery',
|
||||||
|
label: '发货模式',
|
||||||
|
children: <DeliveryModeTab />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'status',
|
key: 'status',
|
||||||
label: '状态说明',
|
label: '状态说明',
|
||||||
@@ -80,10 +102,29 @@ function OverviewTab() {
|
|||||||
<li>在「商户中心 / API 客户端」创建凭证,获得 <Text code>AppKey</Text> 与 <Text code>AppSecret</Text>。</li>
|
<li>在「商户中心 / API 客户端」创建凭证,获得 <Text code>AppKey</Text> 与 <Text code>AppSecret</Text>。</li>
|
||||||
<li>每次请求携带 <Text code>X-App-Key / X-Timestamp / X-Nonce / X-Sign</Text> 四个鉴权头。</li>
|
<li>每次请求携带 <Text code>X-App-Key / X-Timestamp / X-Nonce / X-Sign</Text> 四个鉴权头。</li>
|
||||||
<li>调用「商品列表」拿到可售 <Text code>sku</Text>,调用「下单」创建订单并扣款。</li>
|
<li>调用「商品列表」拿到可售 <Text code>sku</Text>,调用「下单」创建订单并扣款。</li>
|
||||||
<li>拿到 <Text code>order_no</Text> 后进入发货链接;订单状态由发货平台回调更新,可通过「查询订单」轮询。</li>
|
<li>拿到 <Text code>order_no</Text> 后,可选择返回发货链接,或者用结构化发货接口完成自建页面流程。</li>
|
||||||
</ol>
|
</ol>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<Card size="small" title="发货链路概览">
|
||||||
|
<Table
|
||||||
|
size="small"
|
||||||
|
pagination={false}
|
||||||
|
rowKey="mode"
|
||||||
|
dataSource={deliveryModes}
|
||||||
|
columns={[
|
||||||
|
{ title: '模式', dataIndex: 'mode', width: 140 },
|
||||||
|
{ title: '适用场景', dataIndex: 'scene' },
|
||||||
|
{
|
||||||
|
title: '相关接口',
|
||||||
|
dataIndex: 'interfaces',
|
||||||
|
render: (v: string) => (
|
||||||
|
<pre style={preStyle}>{v}</pre>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
<Card size="small" title="环境信息">
|
<Card size="small" title="环境信息">
|
||||||
<Descriptions size="small" column={1} bordered>
|
<Descriptions size="small" column={1} bordered>
|
||||||
<Descriptions.Item label="Base URL">
|
<Descriptions.Item label="Base URL">
|
||||||
@@ -101,6 +142,32 @@ function OverviewTab() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function DeliveryModeTab() {
|
||||||
|
return (
|
||||||
|
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
||||||
|
<Card size="small" title="推荐用法">
|
||||||
|
<Descriptions size="small" column={1} bordered>
|
||||||
|
<Descriptions.Item label="只想给用户一个链接">
|
||||||
|
用 <Text code>delivery-link</Text>,后端直接返回签名后的 Web 发货页地址,前端只负责跳转或复制。
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="想自建发货页面">
|
||||||
|
用 <Text code>delivery</Text> 获取订单数据,再按需调用 <Text code>bind</Text> 和 <Text code>submit</Text>。
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="取消作废">
|
||||||
|
取消作废属于商户后台操作,恢复后会重新签发新有效期和新签名。
|
||||||
|
</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
</Card>
|
||||||
|
<Alert
|
||||||
|
type="info"
|
||||||
|
showIcon
|
||||||
|
message="两种模式共用同一套底层履约逻辑"
|
||||||
|
description="不管是 Web 发货页还是商户自建页面,最终都会走同一套订单校验、绑定和提交逻辑,只是前端形态不同。"
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function AuthTab() {
|
function AuthTab() {
|
||||||
return (
|
return (
|
||||||
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user