openapi: 3.0.3 info: title: 海外仓租与出库资金预校验 version: 1.0.0 description: | 仅仓租自动计费。中转按CBM/天、退货按原托份额/天累进,首次或重建预校验读取客户当前仓租配置。 未配置客户使用仓库服务明确返回的两张默认报价表;网络、无效配置或不支持币种均阻断出库,不降级免费。 PlanJson保存配置ID、版本、币种和完整阶梯。有效预占重放与consume使用原快照及冻结金额,不受期间改价影响。 后续部分出库采用客户最新配置,原入库时间与原托份额保持不变。原币支持USD/CNY,结算币为CNY。 实际PDA入库开始计租,实际出库按本次数量生成待审核费用,审核通过后按确认金额扣款;所有海外仓租从余额及有效授信扣除。 头程同单同仓多次入库合并计租,统一沿用首次实际入库时间;其他业务按各批实际入库时间分别计龄。 每满24小时一天,不足24小时向上取整。公开时间均为ISO8601 UTC时间,携带Z,客户端按本地时区显示。 普通业务错误沿用HTTP 200及非200业务code。平台接口要求平台tenant_id=0。 security: - bearerAuth: [] paths: /api/platform/v1/last-leg/storage-rent: get: summary: 原计租批次分页 description: 权限platform:overseas-fee:list。一个原始实收批次一行。 parameters: - {in: query, name: customerId, schema: {type: string}} - {in: query, name: businessNo, schema: {type: string}} - {in: query, name: warehouseId, schema: {type: string}} - {in: query, name: businessType, schema: {type: string, enum: [LASTLEG_ORDER, WAREHOUSE_TRANSFER, RETURN_ORDER]}} - {in: query, name: status, schema: {type: string, enum: [IN_STOCK, CLEARED]}} - {in: query, name: page, schema: {type: integer, minimum: 1, default: 1}} - {in: query, name: size, schema: {type: integer, minimum: 1, maximum: 200, default: 20}} responses: '200': description: 统一响应data包含records、page、size、total、pages content: application/json: schema: allOf: - {$ref: '#/components/schemas/Envelope'} - properties: data: type: object properties: records: {type: array, items: {$ref: '#/components/schemas/Lot'}} page: {type: integer} size: {type: integer} total: {type: integer} pages: {type: integer} /api/platform/v1/last-leg/storage-rent/warehouse-options: get: summary: 计租仓库选项 description: 权限platform:overseas-fee:list,只读取已有仓库快照。 responses: '200': description: data为id、warehouseName对象数组 /api/platform/v1/last-leg/storage-rent/{id}: get: summary: 原批次及逐次出库仓租 description: 权限platform:overseas-fee:list;只返回已实际出库的收费记录,免费出库保留零金额。 parameters: - {$ref: '#/components/parameters/id'} responses: '200': description: 统一响应 content: application/json: schema: allOf: - {$ref: '#/components/schemas/Envelope'} - properties: data: type: object properties: lot: {$ref: '#/components/schemas/Lot'} charges: {type: array, items: {$ref: '#/components/schemas/Charge'}} /api/platform/v1/last-leg/storage-rent/fees/{sourceFeeId}/adjust: post: summary: 审核前调整仓租金额并保存说明 description: 权限platform:finance:fee-source:edit。仅当前待审核且资金已锁定版本可改;金额按原币填写,保留冻结汇率与原计算快照。生成新费用版本。原零元改为非零须先补冻结;原非零费用调高在审核结算时由Finance原子检查差额,余额不足保留原冻结,不登记实扣。 parameters: - {in: path, name: sourceFeeId, required: true, schema: {type: string}} requestBody: required: true content: application/json: schema: type: object required: [expectedVersion, amount, reason, idempotencyKey] properties: expectedVersion: {type: integer, minimum: 1} amount: {type: number, minimum: 0, maximum: 999999999999.99, multipleOf: 0.01} reason: {type: string, minLength: 1, maxLength: 500} idempotencyKey: {type: string, minLength: 1, maxLength: 128} responses: '200': {description: 统一响应,data为调整后的费用版本;状态冲突或缺少说明返回非200业务code} /api/pda/v1/last-leg/storage-rent/preparations: post: summary: 出库前计算仓租并提交余额授信冻结 description: | 权限lastleg:pda:operate及ROLE_OVERSEAS_WAREHOUSE_PDA_OPERATOR。客户与仓库从绑定身份及真实业务来源解析。 ready=false必须等待资金回执;仅ready=true可提交原扫码。先冻结后扣库存,实际扫码后生成待审核仓租,审核通过后实际扣款。 同一原扫码复用idempotencyKey与全部明细;更改货物或数量必须新键。冻结15分钟有效,变更计费天数或汇率月份需重算。 已实际出库的原键返回CONSUMED,调用原扫码接口恢复其幂等结果。零费用无需汇率及资金指令。 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/PrepareRequest'} responses: '200': description: 统一响应data为预校验状态 content: application/json: schema: allOf: - {$ref: '#/components/schemas/Envelope'} - properties: data: {$ref: '#/components/schemas/Preparation'} /api/pda/v1/last-leg/storage-rent/preparations/{id}: parameters: - {$ref: '#/components/parameters/id'} get: summary: 查询原冻结真实回执 description: PDA权限及绑定仓校验同创建。 responses: '200': {description: 统一响应data为Preparation} delete: summary: 取消未使用预占并解冻 description: 已出库不能取消;冻结处理中取消将于迟到成功回执后补解冻。PDA权限及绑定仓校验同创建。 responses: '200': {description: 统一响应data为Preparation} components: securitySchemes: bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT} parameters: id: {in: path, name: id, required: true, schema: {type: string}} schemas: Envelope: type: object properties: code: {type: string, example: '200'} message: {type: string} data: {type: object} Lot: type: object properties: id: {type: string} customerId: {type: string} customerName: {type: string} businessType: {type: string} businessNo: {type: string, description: 原计租来源单号,头程为对应尾程订单号,退货为退货单号} warehouseId: {type: string} warehouseName: {type: string} batchNo: {type: string} inboundAt: {type: string, format: date-time, description: 实际入库UTC时间,带Z} storageDays: {type: integer, description: 已清仓按最后实际出库停止} originalQuantity: {type: number} remainingQuantity: {type: number} quantityUnit: {type: string, enum: [PACKAGE, PIECE]} billingQuantity: {type: number} billingUnit: {type: string, enum: [CBM, PALLET]} ruleCode: {type: string, enum: [TRANSIT_V1, RETURN_V1]} status: {type: string, enum: [IN_STOCK, CLEARED]} settledAmount: {type: number, description: 本原批次已成功扣款的CNY合计,不含处理中及失败记录} chargeCount: {type: integer, description: 本原批次实际出库仓租记录数,包含免租记录} settledChargeCount: {type: integer, description: 已完成结算的仓租记录数,包含免租记录} generatedAmount: {type: number, nullable: true, description: 单币种合计;无记录为0,多币种为null} generatedCurrency: {type: string, nullable: true, enum: [USD, CNY], description: 无记录或多币种为null} generatedAmounts: type: array description: 按原币分别汇总,禁止跨币相加;无记录为空数组 items: type: object properties: currency: {type: string, enum: [USD, CNY]} amount: {type: number} Charge: type: object properties: id: {type: string} outboundNo: {type: string} businessNo: {type: string} quantity: {type: number} storageDays: {type: integer} originalAmount: {type: number} currency: {type: string, enum: [USD, CNY]} settlementAmount: {type: number, description: CNY结算金额} currencyRate: {type: number, nullable: true} status: {type: string, enum: [PENDING_REVIEW, REVIEW_FREEZE_PENDING, REVIEW_FREEZE_FAILED, REJECTED, CONSUMED, SETTLE_FAILED, SETTLED]} createdAt: {type: string, format: date-time} outboundAt: {type: string, format: date-time} PrepareRequest: type: object required: [mode, businessNo, idempotencyKey] properties: mode: {type: string, enum: [DISPATCH, OUTBOUND, OUTBOUND_PALLET, DISCARD]} businessNo: {type: string, maxLength: 128} itemId: {type: string} positionId: {type: string} packages: {type: integer, minimum: 1} cartonMark: {type: string} palletNo: {type: string} idempotencyKey: {type: string, maxLength: 255} cartonMarks: {type: array, items: {type: string}} skuCode: {type: string} productQuantity: {type: integer, minimum: 0} lines: type: array items: type: object required: [itemId, actualPackages] properties: itemId: {type: string} actualPackages: {type: integer, minimum: 0} photoFileIds: {type: array, items: {type: string}} scannedCartonMarks: {type: array, items: {type: string}} confirmAllCartons: {type: boolean} Preparation: type: object properties: preparationId: {type: string, nullable: true} status: {type: string, enum: [NOT_REQUIRED, FREEZE_PENDING, READY, FAILED, EXPIRED, CANCELLED, CONSUMED]} ready: {type: boolean} amount: {type: number} currency: {type: string, enum: [CNY]} originalAmount: {type: number, nullable: true, description: 整托包含多种原币时为null,CNY amount始终可合计} originalCurrency: {type: string, nullable: true, enum: [USD, CNY]} exchangeRate: {type: number, nullable: true} exchangeRateMonth: {type: string, nullable: true} message: {type: string, nullable: true}