diff --git a/backend/internal/service/delivery.go b/backend/internal/service/delivery.go index 8c47ff4..5227e51 100644 --- a/backend/internal/service/delivery.go +++ b/backend/internal/service/delivery.go @@ -48,7 +48,10 @@ func deliverySubmittedUpstream(order *model.FulfillmentOrder) bool { return true } 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 resultDataString(order.ResultData, "provider_order_stage") == deliveryStageSubmitted @@ -144,7 +147,7 @@ type DeliverySubmitResult struct { Message string `json:"message"` ProviderOrderNo string `json:"provider_order_no,omitempty"` GameAccount map[string]interface{} `json:"game_account,omitempty"` - UpstreamOrder interface{} `json:"upstream_order,omitempty"` + UpstreamOrder interface{} `json:"delivery,omitempty"` } type DeliveryLinkAuth struct { @@ -348,7 +351,7 @@ func (s *DeliveryService) submit(orderNo, gameAccount, bindUUID string, apiClien "game_uid": gameAccount, "role_name": stringFromMap(boundAccount, "game_account_role_name"), "game_channel": gameChannelText(boundAccount), - "upstream_order": upstreamOrder, + "delivery": upstreamOrder, }) nextStatus := model.OrderStatusDelivering message := "已提交发货,等待发货结果回传" diff --git a/frontend/src/openapi/endpoints.ts b/frontend/src/openapi/endpoints.ts index bff860f..cae30ff 100644 --- a/frontend/src/openapi/endpoints.ts +++ b/frontend/src/openapi/endpoints.ts @@ -67,7 +67,7 @@ const orderResponseExample = `{ "amount": 105, "currency": "POINT", "buyer_reference": "buyer-001", - "data": { "server": "ios-wechat", "uid": "player-id" }, + "data": { "game_account": "4808146277", "game_channel": "ios-wechat" }, "provider_order_no": "", "failure_reason": "", "created_at": "2026-07-30T10:00:00+08:00", @@ -133,7 +133,7 @@ const deliverySubmitResponseExample = `{ "game_account": "4808146277", "game_account_role_name": "巫师哈丁12" }, - "upstream_order": { + "delivery": { "order_no": "provider-1" } } @@ -142,6 +142,7 @@ const deliverySubmitResponseExample = `{ export const endpoints: EndpointSpec[] = [ { key: 'list-products', + group: 'basic', method: 'GET', path: '/api/client/v1/products', title: '商品列表', @@ -187,6 +188,7 @@ export const endpoints: EndpointSpec[] = [ }, { key: 'create-order', + group: 'basic', method: 'POST', path: '/api/client/v1/orders', title: '创建订单', @@ -225,7 +227,7 @@ export const endpoints: EndpointSpec[] = [ "amount": 105, "currency": "POINT", "buyer_reference": "buyer-001", - "data": { "server": "ios-wechat", "uid": "player-id" }, + "data": { "game_account": "4808146277", "game_channel": "ios-wechat" }, "provider_order_no": "", "failure_reason": "", "created_at": "2026-07-30T10:00:00+08:00", @@ -239,6 +241,7 @@ export const endpoints: EndpointSpec[] = [ { name: 'order', type: 'object', desc: '订单完整对象,字段见下方「订单字段说明」' }, ], notes: [ + '成功创建返回 HTTP 201;命中幂等(client_order_no 已存在)返回 HTTP 200 且 idempotent=true。', 'client_order_no 是唯一幂等单号,请保证同一商户下不重复;重复请求不会重复扣款,返回 idempotent=true 及既有订单。', '当前无真实支付流程,下单成功即扣款并进入 order_status=paid,余额不足返回 400。', '下单成功后请保存 order_no,后续查询/发货/回调均以 order_no 为准;client_order_no 仅用于幂等。', @@ -247,6 +250,7 @@ export const endpoints: EndpointSpec[] = [ }, { key: 'query-order', + group: 'basic', method: 'GET', path: '/api/client/v1/orders/{order_no}', title: '查询订单', @@ -258,6 +262,7 @@ export const endpoints: EndpointSpec[] = [ }, { key: 'cancel-order', + group: 'basic', method: 'POST', path: '/api/client/v1/orders/{order_no}/cancel', title: '取消订单', @@ -275,6 +280,7 @@ export const endpoints: EndpointSpec[] = [ }, { key: 'delivery-link', + group: 'delivery-link', method: 'GET', path: '/api/client/v1/orders/{order_no}/delivery-link', title: '获取发货链接', @@ -296,6 +302,7 @@ export const endpoints: EndpointSpec[] = [ }, { key: 'delivery-order', + group: 'delivery-self', method: 'GET', path: '/api/client/v1/orders/{order_no}/delivery', title: '查询发货数据', @@ -328,6 +335,7 @@ export const endpoints: EndpointSpec[] = [ }, { key: 'delivery-bind', + group: 'delivery-self', method: 'POST', path: '/api/client/v1/orders/{order_no}/delivery/bind', title: '发起绑定', @@ -353,6 +361,7 @@ export const endpoints: EndpointSpec[] = [ }, { key: 'delivery-submit', + group: 'delivery-self', method: 'POST', path: '/api/client/v1/orders/{order_no}/delivery/submit', title: '提交发货', @@ -374,7 +383,7 @@ export const endpoints: EndpointSpec[] = [ { name: 'message', type: 'string', desc: '处理结果说明' }, { name: 'provider_order_no', type: 'string', desc: '平台发货单号' }, { name: 'game_account', type: 'object', desc: '账号绑定结果' }, - { name: 'upstream_order', type: 'object', desc: '发货提交结果' }, + { name: 'delivery', type: 'object', desc: '发货提交结果' }, ], notes: [ '同一订单重复提交应直接返回已有结果,不应重复发起发货。', @@ -383,6 +392,7 @@ export const endpoints: EndpointSpec[] = [ }, { key: 'get-wallet', + group: 'basic', method: 'GET', path: '/api/client/v1/wallet', title: '余额查询', diff --git a/frontend/src/openapi/types.ts b/frontend/src/openapi/types.ts index 655658a..637e237 100644 --- a/frontend/src/openapi/types.ts +++ b/frontend/src/openapi/types.ts @@ -16,6 +16,8 @@ export const endpointSections = [ export interface EndpointSpec { /** 唯一 key,用于折叠面板与锚点 */ key: string + /** 接口分组:basic 基础 / delivery-link 发货链接模式 / delivery-self 自建发货页模式 */ + group: 'basic' | 'delivery-link' | 'delivery-self' /** HTTP 方法 */ method: HttpMethod /** 接口路径,路径参数用 {name} 表示 */ diff --git a/frontend/src/pages/OpenApiDocs.tsx b/frontend/src/pages/OpenApiDocs.tsx index d3b7735..31c3a90 100644 --- a/frontend/src/pages/OpenApiDocs.tsx +++ b/frontend/src/pages/OpenApiDocs.tsx @@ -19,15 +19,18 @@ const baseUrl = const deliveryModes = [ { - mode: 'Web 发货页', - scene: '商户想要“只返回一个链接”,让用户直接打开平台页面填写 UID', + mode: '发货链接模式', + scene: '实现最简:下单后拿一个签名链接,直接跳转平台发货页,由买家在页面上绑定账号并提交', interfaces: '/api/client/v1/orders/{order_no}/delivery-link', + steps: '下单 → 获取发货链接 → 链接给买家 → 平台页完成发货', + recommend: '商户无自建发货页、想最快上线时使用', }, { - 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', + 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', + steps: '下单 → 查询发货数据 → 发起绑定 → 提交发货', + recommend: '商户需要自定义发货交互(展示区服、预填账号)时使用', }, ] @@ -48,6 +51,16 @@ interface 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 [ { title: '开始', @@ -57,16 +70,16 @@ function buildToc(): TocGroup[] { ], }, { - title: '接口', - items: endpoints.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, - })), - })), + title: '基础接口', + items: tocItems(endpoints.filter((ep) => ep.group === 'basic')), + }, + { + title: '发货链接模式', + items: tocItems(endpoints.filter((ep) => ep.group === 'delivery-link')), + }, + { + title: '自建发货页模式', + items: tocItems(endpoints.filter((ep) => ep.group === 'delivery-self')), }, { title: '回调', @@ -321,12 +334,12 @@ function OverviewSection() {