二期内容提交
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 柏悦二期 FBA 计费 API
|
||||
version: 2.0.0
|
||||
description: 业务成功和失败均使用 HTTP 200;仅响应体 code 为字符串 "200" 时表示成功。
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/api/platform/v1/fba-pricing/customer-rules:
|
||||
get:
|
||||
summary: 查询客户计费规则版本
|
||||
description: 需要 firstleg:fba-pricing:rule:view 权限
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/fba-pricing/customer-rules/versions:
|
||||
post:
|
||||
summary: 新建客户计费规则版本
|
||||
description: 版本内容不可原地修改;有效期使用 [effectiveFrom,effectiveTo) 半开区间。
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}]
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CustomerRuleVersionRequest'}}}}
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/fba-pricing/customer-rules/{id}:
|
||||
get:
|
||||
summary: 查询客户计费规则版本详情
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/Id'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
delete:
|
||||
summary: 停用客户计费规则版本
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/Id'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/fba-pricing/carrier-rates:
|
||||
get:
|
||||
summary: 查询船司 FBA 价格版本
|
||||
description: 需要 firstleg:fba-pricing:rate:view 权限
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/fba-pricing/carrier-rates/versions:
|
||||
post:
|
||||
summary: 新建船司 FBA 价格版本
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}]
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CarrierRateVersionRequest'}}}}
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/fba-pricing/carrier-rates/{id}:
|
||||
get:
|
||||
summary: 查询船司 FBA 价格版本详情
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/Id'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
delete:
|
||||
summary: 停用船司 FBA 价格版本
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/Id'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/inbounds/{inboundId}/fees/calculate:
|
||||
post:
|
||||
summary: 按审核通过测量快照试算 FBA 费用
|
||||
description: 精确匹配唯一客户规则和唯一船司价格;需要 firstleg:fba-pricing:calculate 权限。
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
requestBody: {content: {application/json: {schema: {$ref: '#/components/schemas/CalculateRequest'}}}}
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/inbounds/{inboundId}/fees/confirm:
|
||||
post:
|
||||
summary: 确认最新费用快照
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/inbounds/{inboundId}/fees/send:
|
||||
post:
|
||||
summary: 手工恢复发送费用快照
|
||||
description: 仅作为异常恢复接口;正常业务由客服测量审核通过后自动计费、发布并完成入库。
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/inbounds/{inboundId}/fees/latest:
|
||||
get:
|
||||
summary: 查询最新费用快照
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/inbounds/{inboundId}/fees/published:
|
||||
put:
|
||||
summary: 调整已发布费用
|
||||
description: 需要 firstleg:fba-pricing:adjust 权限;生成新 SENT 版本并将旧版本标记 SUPERSEDED,不回退 INBOUNDED 状态。
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/AdjustFeeRequest'}
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无调整权限}}
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
|
||||
parameters:
|
||||
TenantId: {name: tenantId, in: query, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
Id: {name: id, in: path, required: true, schema: {type: integer, format: int64}}
|
||||
InboundId: {name: inboundId, in: path, required: true, schema: {type: integer, format: int64}}
|
||||
IdempotencyKey: {name: Idempotency-Key, in: header, required: true, schema: {type: string, maxLength: 128}}
|
||||
schemas:
|
||||
AdjustFeeRequest:
|
||||
type: object
|
||||
required: [subtotalAmount, additionalAmount, reason]
|
||||
properties:
|
||||
subtotalAmount: {type: number, minimum: 0, multipleOf: 0.01}
|
||||
additionalAmount: {type: number, minimum: 0, multipleOf: 0.01}
|
||||
reason: {type: string, minLength: 1, maxLength: 500}
|
||||
CalculateRequest:
|
||||
type: object
|
||||
properties: {pricingAt: {type: string, format: date-time, description: 缺省为服务端当前时间}}
|
||||
CustomerRuleVersionRequest:
|
||||
type: object
|
||||
required: [ruleCode, customerId, customerName, businessType, chargeMode, taxMode, conversionFactor, roundingScale, roundingMode, currency, effectiveFrom]
|
||||
properties:
|
||||
ruleCode: {type: string, maxLength: 50}
|
||||
customerId: {type: integer, format: int64}
|
||||
customerName: {type: string, maxLength: 128}
|
||||
businessType: {type: string, maxLength: 32}
|
||||
chargeMode: {type: string, enum: [KG, CBM]}
|
||||
taxMode: {type: string, enum: [TAX_INCLUDED, TAX_EXCLUDED]}
|
||||
conversionFactor: {type: number, exclusiveMinimum: 0, example: 167}
|
||||
roundingScale: {type: integer, minimum: 0, maximum: 4}
|
||||
roundingMode: {type: string, enum: [UP, DOWN, CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN]}
|
||||
currency: {type: string, pattern: '^[A-Z]{3}$'}
|
||||
effectiveFrom: {type: string, format: date-time}
|
||||
effectiveTo: {type: string, format: date-time, nullable: true}
|
||||
CarrierRateVersionRequest:
|
||||
type: object
|
||||
required: [rateCode, originWarehouseId, originWarehouseName, businessType, channelCode, carrierId, carrierName, destinationCode, chargeUnit, unitPrice, currency, additionalFee, effectiveFrom]
|
||||
properties:
|
||||
rateCode: {type: string, maxLength: 50}
|
||||
originWarehouseId: {type: integer, format: int64}
|
||||
originWarehouseName: {type: string}
|
||||
businessType: {type: string}
|
||||
channelCode: {type: string}
|
||||
carrierId: {type: integer, format: int64}
|
||||
carrierName: {type: string}
|
||||
destinationCode: {type: string}
|
||||
chargeUnit: {type: string, enum: [KG, CBM]}
|
||||
unitPrice: {type: number, exclusiveMinimum: 0}
|
||||
currency: {type: string, pattern: '^[A-Z]{3}$'}
|
||||
additionalFee: {type: number, minimum: 0}
|
||||
effectiveFrom: {type: string, format: date-time}
|
||||
effectiveTo: {type: string, format: date-time, nullable: true}
|
||||
@@ -67,13 +67,160 @@ paths:
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断}
|
||||
'403': {description: 无分配权限}
|
||||
/openapi/v1/inbound-measurements:
|
||||
post:
|
||||
summary: 提交第三方长宽高测量结果
|
||||
description: >-
|
||||
只写 fl_third_party_call_log、fl_inbound_measurement、fl_inbound_measurement_item
|
||||
和 HTTP 幂等结果,不审核、不计费、不入库,也不改变入库单状态。
|
||||
签名串依次为 METHOD、原始 PATH、X-Timestamp、X-Nonce、Idempotency-Key、
|
||||
原始 UTF-8 body 的 SHA-256 小写十六进制,六部分使用 LF(\n)连接且末尾不追加换行。
|
||||
三层语义:Nonce 防短时重放;Idempotency-Key 标识一次 HTTP 写操作;
|
||||
appKey + eventNo 标识第三方业务事件。
|
||||
security:
|
||||
- measurementAppKey: []
|
||||
measurementTimestamp: []
|
||||
measurementNonce: []
|
||||
measurementSignature: []
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/XTimestamp'}
|
||||
- {$ref: '#/components/parameters/XNonce'}
|
||||
- {$ref: '#/components/parameters/IdempotencyKey'}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/InboundMeasurementCallbackRequest'}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体字符串 code 判断;非法签名返回 A0401}
|
||||
'413': {description: 请求体超过网关限制}
|
||||
'415': {description: Content-Type 不支持}
|
||||
/openapi/v1/inbound-measurements/events/{eventNo}:
|
||||
get:
|
||||
summary: 查询第三方测量事件状态
|
||||
description: GET 签名串的 Idempotency-Key 行为空字符串,body 摘要为空字节 SHA-256。
|
||||
security:
|
||||
- measurementAppKey: []
|
||||
measurementTimestamp: []
|
||||
measurementNonce: []
|
||||
measurementSignature: []
|
||||
parameters:
|
||||
- name: eventNo
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: string, pattern: '^[A-Za-z0-9._:-]{1,128}$'}
|
||||
- {$ref: '#/components/parameters/XTimestamp'}
|
||||
- {$ref: '#/components/parameters/XNonce'}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体字符串 code 判断}
|
||||
/api/platform/inbounds:
|
||||
get:
|
||||
summary: 分页查询入库单
|
||||
description: 需要 platform:firstleg:inbound:list 权限;仅使用 V2 四个页签
|
||||
parameters:
|
||||
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: tab, in: query, schema: {type: string, enum: [WAIT_MEASURE, WAIT_REVIEW, WAIT_FEE_SEND, INBOUNDED]}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断}
|
||||
'403': {description: 无查询权限}
|
||||
/api/platform/inbounds/{inboundId}:
|
||||
get:
|
||||
summary: 查询入库单详情
|
||||
description: 需要 platform:firstleg:inbound:view 权限
|
||||
parameters:
|
||||
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断}
|
||||
'403': {description: 无查看权限}
|
||||
/api/platform/v1/inbounds/{inboundId}/measurements/approve:
|
||||
post:
|
||||
summary: 审核通过测量
|
||||
description: 需要 firstleg:inbound:measurement-review 权限;客服审核通过后自动计费、发布费用给客户并完成入库,客户无需确认。
|
||||
parameters:
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: Idempotency-Key, in: header, required: true, schema: {type: string}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败}
|
||||
/api/platform/v1/inbounds/{inboundId}/measurements/reject:
|
||||
post:
|
||||
summary: 驳回测量
|
||||
description: 需要 firstleg:inbound:measurement-review 权限;只退回测量数据修改,已确认托盘和库位占用保持不动。
|
||||
parameters:
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: Idempotency-Key, in: header, required: true, schema: {type: string}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败}
|
||||
/api/platform/v1/inbounds/{inboundId}/measurements/submit:
|
||||
post:
|
||||
summary: 提交测量完成
|
||||
description: 测量提交后立即按总体积拆分普通托盘、分配并确认占用库位,再进入客服待审核;无普通空闲位时共享 A0。
|
||||
parameters:
|
||||
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
responses:
|
||||
'200': {description: 成功时 processStatus=MEASURE_PENDING、measureReviewStatus=PENDING,且库位已 OCCUPIED}
|
||||
'403': {description: 无测量提交权限}
|
||||
/api/merchant/v1/first-leg/orders/{orderId}/inbound-billing:
|
||||
get:
|
||||
summary: 客户查询已完成入库结果和最新已发布费用
|
||||
description: 需要 merchant:order:view 权限;客户只读查看,不需要确认费用,未完成客服审核发布时不可见。
|
||||
parameters:
|
||||
- {name: orderId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断}
|
||||
'403': {description: 非本租户或无订单查看权限}
|
||||
/api/platform/v1/inbounds/{inboundId}/measurements/exception-release:
|
||||
post:
|
||||
summary: 测量异常放行
|
||||
description: 需要 firstleg:inbound:exception-release 权限
|
||||
parameters:
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: Idempotency-Key, in: header, required: true, schema: {type: string}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败}
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
measurementAppKey:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-App-Key
|
||||
description: 分配给测量服务商的应用标识
|
||||
measurementTimestamp:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-Timestamp
|
||||
description: Unix 毫秒时间戳
|
||||
measurementNonce:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-Nonce
|
||||
description: 每次请求唯一的随机串
|
||||
measurementSignature:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-Signature
|
||||
description: HMAC-SHA256 小写十六进制签名
|
||||
parameters:
|
||||
XTimestamp:
|
||||
name: X-Timestamp
|
||||
in: header
|
||||
required: true
|
||||
schema: {type: string, pattern: '^[0-9]{13}$', example: '1785551400000'}
|
||||
XNonce:
|
||||
name: X-Nonce
|
||||
in: header
|
||||
required: true
|
||||
schema: {type: string, minLength: 1, maxLength: 128}
|
||||
IdempotencyKey:
|
||||
name: Idempotency-Key
|
||||
in: header
|
||||
required: true
|
||||
schema: {type: string, minLength: 1, maxLength: 128}
|
||||
TenantId:
|
||||
name: tenantId
|
||||
in: query
|
||||
@@ -93,6 +240,39 @@ components:
|
||||
in: query
|
||||
schema: {type: integer, format: int64, minimum: 1, maximum: 200, default: 20}
|
||||
schemas:
|
||||
InboundMeasurementCallbackRequest:
|
||||
type: object
|
||||
required: [eventNo, warehouseCode, inboundCode, deviceCode, measuredAt, items]
|
||||
properties:
|
||||
eventNo: {type: string, maxLength: 128, pattern: '^[A-Za-z0-9._:-]+$', example: M202608010001}
|
||||
warehouseCode: {type: string, maxLength: 50, example: CN-YW-01}
|
||||
inboundCode: {type: string, maxLength: 40, example: RK202608010001}
|
||||
deviceCode: {type: string, maxLength: 64, example: DEVICE-01}
|
||||
measuredAt: {type: string, format: date-time, example: '2026-08-01T10:30:00+08:00'}
|
||||
items:
|
||||
type: array
|
||||
minItems: 1
|
||||
maxItems: 500
|
||||
items: {$ref: '#/components/schemas/InboundMeasurementItem'}
|
||||
InboundMeasurementItem:
|
||||
type: object
|
||||
required: [itemNo, boxSpecification, lengthCm, widthCm, heightCm, quantity]
|
||||
properties:
|
||||
itemNo: {type: string, maxLength: 32, example: '001'}
|
||||
boxSpecification: {type: string, maxLength: 64, example: '61.5x42x42cm', description: 入库单绑定的箱规明细}
|
||||
lengthCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 50.20}
|
||||
widthCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 40.10}
|
||||
heightCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 30.00}
|
||||
quantity: {type: integer, minimum: 1, maximum: 1000000, example: 5}
|
||||
sourceImageUrl: {type: string, maxLength: 2048, nullable: true, description: 仅随原始报文留档,不直接写文件中心}
|
||||
InboundMeasurementEventResponse:
|
||||
type: object
|
||||
properties:
|
||||
eventNo: {type: string}
|
||||
inboundCode: {type: string}
|
||||
accepted: {type: boolean}
|
||||
status: {type: string, enum: [RECEIVED]}
|
||||
receivedAt: {type: string, format: date-time}
|
||||
AssignRequest:
|
||||
type: object
|
||||
required: [assigneeId, assigneeName]
|
||||
|
||||
Reference in New Issue
Block a user