对接文档重构:两种发货对接方式分开展示

- 左侧目录按分组展示:基础接口 / 发货链接模式 / 自建发货页模式 / 回调 / 附录
- 概述页发货对接方式对比表强化(适用场景/接口顺序/建议)
- 创建订单响应示例 data 统一为约定字段,补充 201/200 状态说明
- 对外响应字段 upstream_order 更名为 delivery(result_data 存储键兼容旧数据)
This commit is contained in:
yml2213
2026-08-03 14:48:30 +08:00
parent 4019b657c4
commit b7b9132242
4 changed files with 61 additions and 26 deletions
+6 -3
View File
@@ -48,7 +48,10 @@ func deliverySubmittedUpstream(order *model.FulfillmentOrder) bool {
return true return true
} }
m := resultDataMap(order.ResultData) m := resultDataMap(order.ResultData)
if _, ok := m["upstream_order"]; ok { if _, ok := m["delivery"]; ok {
return true
}
if _, ok := m["upstream_order"]; ok { // 兼容历史数据
return true return true
} }
return resultDataString(order.ResultData, "provider_order_stage") == deliveryStageSubmitted return resultDataString(order.ResultData, "provider_order_stage") == deliveryStageSubmitted
@@ -144,7 +147,7 @@ type DeliverySubmitResult struct {
Message string `json:"message"` Message string `json:"message"`
ProviderOrderNo string `json:"provider_order_no,omitempty"` ProviderOrderNo string `json:"provider_order_no,omitempty"`
GameAccount map[string]interface{} `json:"game_account,omitempty"` GameAccount map[string]interface{} `json:"game_account,omitempty"`
UpstreamOrder interface{} `json:"upstream_order,omitempty"` UpstreamOrder interface{} `json:"delivery,omitempty"`
} }
type DeliveryLinkAuth struct { type DeliveryLinkAuth struct {
@@ -348,7 +351,7 @@ func (s *DeliveryService) submit(orderNo, gameAccount, bindUUID string, apiClien
"game_uid": gameAccount, "game_uid": gameAccount,
"role_name": stringFromMap(boundAccount, "game_account_role_name"), "role_name": stringFromMap(boundAccount, "game_account_role_name"),
"game_channel": gameChannelText(boundAccount), "game_channel": gameChannelText(boundAccount),
"upstream_order": upstreamOrder, "delivery": upstreamOrder,
}) })
nextStatus := model.OrderStatusDelivering nextStatus := model.OrderStatusDelivering
message := "已提交发货,等待发货结果回传" message := "已提交发货,等待发货结果回传"
+14 -4
View File
@@ -67,7 +67,7 @@ const orderResponseExample = `{
"amount": 105, "amount": 105,
"currency": "POINT", "currency": "POINT",
"buyer_reference": "buyer-001", "buyer_reference": "buyer-001",
"data": { "server": "ios-wechat", "uid": "player-id" }, "data": { "game_account": "4808146277", "game_channel": "ios-wechat" },
"provider_order_no": "", "provider_order_no": "",
"failure_reason": "", "failure_reason": "",
"created_at": "2026-07-30T10:00:00+08:00", "created_at": "2026-07-30T10:00:00+08:00",
@@ -133,7 +133,7 @@ const deliverySubmitResponseExample = `{
"game_account": "4808146277", "game_account": "4808146277",
"game_account_role_name": "巫师哈丁12" "game_account_role_name": "巫师哈丁12"
}, },
"upstream_order": { "delivery": {
"order_no": "provider-1" "order_no": "provider-1"
} }
} }
@@ -142,6 +142,7 @@ const deliverySubmitResponseExample = `{
export const endpoints: EndpointSpec[] = [ export const endpoints: EndpointSpec[] = [
{ {
key: 'list-products', key: 'list-products',
group: 'basic',
method: 'GET', method: 'GET',
path: '/api/client/v1/products', path: '/api/client/v1/products',
title: '商品列表', title: '商品列表',
@@ -187,6 +188,7 @@ export const endpoints: EndpointSpec[] = [
}, },
{ {
key: 'create-order', key: 'create-order',
group: 'basic',
method: 'POST', method: 'POST',
path: '/api/client/v1/orders', path: '/api/client/v1/orders',
title: '创建订单', title: '创建订单',
@@ -225,7 +227,7 @@ export const endpoints: EndpointSpec[] = [
"amount": 105, "amount": 105,
"currency": "POINT", "currency": "POINT",
"buyer_reference": "buyer-001", "buyer_reference": "buyer-001",
"data": { "server": "ios-wechat", "uid": "player-id" }, "data": { "game_account": "4808146277", "game_channel": "ios-wechat" },
"provider_order_no": "", "provider_order_no": "",
"failure_reason": "", "failure_reason": "",
"created_at": "2026-07-30T10:00:00+08:00", "created_at": "2026-07-30T10:00:00+08:00",
@@ -239,6 +241,7 @@ export const endpoints: EndpointSpec[] = [
{ name: 'order', type: 'object', desc: '订单完整对象,字段见下方「订单字段说明」' }, { name: 'order', type: 'object', desc: '订单完整对象,字段见下方「订单字段说明」' },
], ],
notes: [ notes: [
'成功创建返回 HTTP 201;命中幂等(client_order_no 已存在)返回 HTTP 200 且 idempotent=true。',
'client_order_no 是唯一幂等单号,请保证同一商户下不重复;重复请求不会重复扣款,返回 idempotent=true 及既有订单。', 'client_order_no 是唯一幂等单号,请保证同一商户下不重复;重复请求不会重复扣款,返回 idempotent=true 及既有订单。',
'当前无真实支付流程,下单成功即扣款并进入 order_status=paid,余额不足返回 400。', '当前无真实支付流程,下单成功即扣款并进入 order_status=paid,余额不足返回 400。',
'下单成功后请保存 order_no,后续查询/发货/回调均以 order_no 为准;client_order_no 仅用于幂等。', '下单成功后请保存 order_no,后续查询/发货/回调均以 order_no 为准;client_order_no 仅用于幂等。',
@@ -247,6 +250,7 @@ export const endpoints: EndpointSpec[] = [
}, },
{ {
key: 'query-order', key: 'query-order',
group: 'basic',
method: 'GET', method: 'GET',
path: '/api/client/v1/orders/{order_no}', path: '/api/client/v1/orders/{order_no}',
title: '查询订单', title: '查询订单',
@@ -258,6 +262,7 @@ export const endpoints: EndpointSpec[] = [
}, },
{ {
key: 'cancel-order', key: 'cancel-order',
group: 'basic',
method: 'POST', method: 'POST',
path: '/api/client/v1/orders/{order_no}/cancel', path: '/api/client/v1/orders/{order_no}/cancel',
title: '取消订单', title: '取消订单',
@@ -275,6 +280,7 @@ export const endpoints: EndpointSpec[] = [
}, },
{ {
key: 'delivery-link', key: 'delivery-link',
group: 'delivery-link',
method: 'GET', method: 'GET',
path: '/api/client/v1/orders/{order_no}/delivery-link', path: '/api/client/v1/orders/{order_no}/delivery-link',
title: '获取发货链接', title: '获取发货链接',
@@ -296,6 +302,7 @@ export const endpoints: EndpointSpec[] = [
}, },
{ {
key: 'delivery-order', key: 'delivery-order',
group: 'delivery-self',
method: 'GET', method: 'GET',
path: '/api/client/v1/orders/{order_no}/delivery', path: '/api/client/v1/orders/{order_no}/delivery',
title: '查询发货数据', title: '查询发货数据',
@@ -328,6 +335,7 @@ export const endpoints: EndpointSpec[] = [
}, },
{ {
key: 'delivery-bind', key: 'delivery-bind',
group: 'delivery-self',
method: 'POST', method: 'POST',
path: '/api/client/v1/orders/{order_no}/delivery/bind', path: '/api/client/v1/orders/{order_no}/delivery/bind',
title: '发起绑定', title: '发起绑定',
@@ -353,6 +361,7 @@ export const endpoints: EndpointSpec[] = [
}, },
{ {
key: 'delivery-submit', key: 'delivery-submit',
group: 'delivery-self',
method: 'POST', method: 'POST',
path: '/api/client/v1/orders/{order_no}/delivery/submit', path: '/api/client/v1/orders/{order_no}/delivery/submit',
title: '提交发货', title: '提交发货',
@@ -374,7 +383,7 @@ export const endpoints: EndpointSpec[] = [
{ name: 'message', type: 'string', desc: '处理结果说明' }, { name: 'message', type: 'string', desc: '处理结果说明' },
{ name: 'provider_order_no', type: 'string', desc: '平台发货单号' }, { name: 'provider_order_no', type: 'string', desc: '平台发货单号' },
{ name: 'game_account', type: 'object', desc: '账号绑定结果' }, { name: 'game_account', type: 'object', desc: '账号绑定结果' },
{ name: 'upstream_order', type: 'object', desc: '发货提交结果' }, { name: 'delivery', type: 'object', desc: '发货提交结果' },
], ],
notes: [ notes: [
'同一订单重复提交应直接返回已有结果,不应重复发起发货。', '同一订单重复提交应直接返回已有结果,不应重复发起发货。',
@@ -383,6 +392,7 @@ export const endpoints: EndpointSpec[] = [
}, },
{ {
key: 'get-wallet', key: 'get-wallet',
group: 'basic',
method: 'GET', method: 'GET',
path: '/api/client/v1/wallet', path: '/api/client/v1/wallet',
title: '余额查询', title: '余额查询',
+2
View File
@@ -16,6 +16,8 @@ export const endpointSections = [
export interface EndpointSpec { export interface EndpointSpec {
/** 唯一 key,用于折叠面板与锚点 */ /** 唯一 key,用于折叠面板与锚点 */
key: string key: string
/** 接口分组:basic 基础 / delivery-link 发货链接模式 / delivery-self 自建发货页模式 */
group: 'basic' | 'delivery-link' | 'delivery-self'
/** HTTP 方法 */ /** HTTP 方法 */
method: HttpMethod method: HttpMethod
/** 接口路径,路径参数用 {name} 表示 */ /** 接口路径,路径参数用 {name} 表示 */
+39 -19
View File
@@ -19,15 +19,18 @@ const baseUrl =
const deliveryModes = [ const deliveryModes = [
{ {
mode: 'Web 发货页', mode: '发货链接模式',
scene: '商户想要“只返回一个链接”,让用户直接打开平台页面填写 UID', scene: '实现最简:下单后拿一个签名链接,直接跳转平台发货页,由买家在页面上绑定账号并提交',
interfaces: '/api/client/v1/orders/{order_no}/delivery-link', interfaces: '/api/client/v1/orders/{order_no}/delivery-link',
steps: '下单 → 获取发货链接 → 链接给买家 → 平台页完成发货',
recommend: '商户无自建发货页、想最快上线时使用',
}, },
{ {
mode: '自建发货页', mode: '自建发货页模式',
scene: '商户自己有前端页面,在自己的系统里完成发货流程', scene: '商户自己有前端页面,把发货流程嵌在自己的系统里(可预填下单时透传的账号/区服)',
interfaces: 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',
'/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', steps: '下单 → 查询发货数据 → 发起绑定 → 提交发货',
recommend: '商户需要自定义发货交互(展示区服、预填账号)时使用',
}, },
] ]
@@ -48,6 +51,16 @@ interface TocGroup {
} }
function buildToc(): TocGroup[] { function buildToc(): TocGroup[] {
const tocItems = (eps: typeof endpoints) =>
eps.map((ep) => ({
id: `ep-${ep.key}`,
label: ep.title,
children: endpointSections.map((s) => ({
id: `ep-${ep.key}-${s.id}`,
label: s.label,
level: 3 as const,
})),
}))
return [ return [
{ {
title: '开始', title: '开始',
@@ -57,16 +70,16 @@ function buildToc(): TocGroup[] {
], ],
}, },
{ {
title: '接口', title: '基础接口',
items: endpoints.map((ep) => ({ items: tocItems(endpoints.filter((ep) => ep.group === 'basic')),
id: `ep-${ep.key}`, },
label: ep.title, {
children: endpointSections.map((s) => ({ title: '发货链接模式',
id: `ep-${ep.key}-${s.id}`, items: tocItems(endpoints.filter((ep) => ep.group === 'delivery-link')),
label: s.label, },
level: 3 as const, {
})), title: '自建发货页模式',
})), items: tocItems(endpoints.filter((ep) => ep.group === 'delivery-self')),
}, },
{ {
title: '回调', title: '回调',
@@ -321,12 +334,12 @@ function OverviewSection() {
<li> API / API <Text code>AppKey</Text> <Text code>AppSecret</Text></li> <li> API / 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>
<li></li> <li></li>
</ol> </ol>
} }
/> />
<Card className="api-docs__card" size="small" title="发货链路概览"> <Card className="api-docs__card" size="small" title="发货对接方式(二选一,先选好再看对应接口)">
<Table <Table
className="api-docs__table" className="api-docs__table"
size="small" size="small"
@@ -334,13 +347,20 @@ function OverviewSection() {
rowKey="mode" rowKey="mode"
dataSource={deliveryModes} dataSource={deliveryModes}
columns={[ columns={[
{ title: '式', dataIndex: 'mode', width: 140 }, { title: '式', dataIndex: 'mode', width: 130 },
{ title: '适用场景', dataIndex: 'scene' }, { title: '适用场景', dataIndex: 'scene' },
{
title: '接口顺序',
dataIndex: 'steps',
width: 250,
render: (v: string) => <pre className="api-docs__pre">{v}</pre>,
},
{ {
title: '相关接口', title: '相关接口',
dataIndex: 'interfaces', dataIndex: 'interfaces',
render: (v: string) => <pre className="api-docs__pre">{v}</pre>, render: (v: string) => <pre className="api-docs__pre">{v}</pre>,
}, },
{ title: '建议', dataIndex: 'recommend', width: 170 },
]} ]}
/> />
</Card> </Card>