# 定价工具 API > 所有接口要求 `X-Atlas-Platform-Id`。首期仅支持 Ozon、市场 `RU`、`rfbs` 和已审核启用的 CEL 规则。报价引擎只读取 Atlas 已持久化的汇率、佣金和运价版本;请求期间绝不直接请求 CBR、CEL 或 Ozon。 ## 1. 统一口径 - API 使用规范单位:采购成本、国内费用为 `CNY` 字符串;重量为 `kg` 字符串;尺寸为 `cm` 字符串。前端的 g/mm 输入必须先转换。 - 所有比例以 `0`–`1` 字符串表示,如 `"0.20"` 是 20%。`desired_markup_rate` 是目标净利润 ÷ 采购成本;`list_price_discount_rate` 是买家相对划线价的折扣率。 - 销售价和划线价均为 `RUB`;`merchandise_value_cny` 是销售价按本次汇率折算得到的 CNY,专门用于选择 CEL 产品类型。 - 引擎枚举“佣金档 × CEL 产品类型 × 运输方式”,再回验佣金价格区间、CEL 货值区间、重量、尺寸及计费重。没有稳定有效组合时不能返回建议售价。 - 系统汇率、方案固定汇率、一次性覆盖及临时佣金率都固化到后续 SKU 报价快照,不会改写全局规则或定价方案。 ## 2. 只读上下文 ### 2.1 当前上下文 `GET /api/pricing/context` 返回当前平台、默认市场、当前工作空间该平台的默认店铺及默认定价方案。没有默认店铺返回 `422 DEFAULT_STORE_REQUIRED`,不猜测目标店铺。 ```json { "data": { "platform": { "id": "uuid", "code": "OZON", "name": "Ozon" }, "market_code": "RU", "store": { "id": "uuid", "name": "Ozon 主店", "currency_code": "RUB" }, "default_pricing_policy": { "id": "uuid", "name": "CEL 常规" } } } ``` ### 2.2 商品类目、物流目录与系统汇率 `GET /api/platform-product-categories?parent_id={uuid|null}&q={keyword}&active_only=true` 返回 header 平台的商品类目。`parent_id`(懒加载树)与 `q`(搜索)不能同时使用。每项有 `id`、`name`、`path`、`has_children`、`pricing_rule_status`: - `available`:当前市场、履约模式下存在唯一有效映射和正式佣金规则; - `missing`:缺少有效映射或规则; - `ambiguous`:多个同优先级映射,普通用户不能猜测。 不暴露佣金类目 ID 让客户端自行映射。 `GET /api/pricing/catalog?fulfillment=rfbs&store_id={uuid}` `store_id` 省略时取默认店铺;传入时必须属于当前工作空间与 header 平台。仅返回当前已启用价卡、服务商和运输方式: ```json { "data": { "providers": [{ "id": "uuid", "code": "CEL", "name": "CEL", "rate_card": { "id": "uuid", "version": "CEL-OZON-RFBS-V6.17", "effective_from": "2026-09-01T00:00:00Z" }, "transport_methods": [ { "id": "uuid", "code": "air", "name": "陆空特快", "speed_label": "5–10 天" }, { "id": "uuid", "code": "land_air", "name": "陆空标准", "speed_label": "10–15 天" }, { "id": "uuid", "code": "land", "name": "陆运经济", "speed_label": "15–25 天" } ] }] } } ``` 若规则仍为 `draft` 或未通过真实账单复核,catalog 不返回它;试算请求返回 `422 PRICING_RULES_UNAVAILABLE`。 `GET /api/pricing/exchange-rate?base_currency_code=CNY"e_currency_code=RUB` 读取最新 CBR `official_reference`: ```json { "data": { "id": "uuid", "base_currency_code": "CNY", "quote_currency_code": "RUB", "rate": "12.33430000", "source": "cbr", "kind": "official_reference", "effective_on": "2026-09-02", "fetched_at": "2026-09-02T02:00:00Z", "is_stale": false } } ``` 没有系统汇率返回 `404 SYSTEM_EXCHANGE_RATE_NOT_FOUND`;超过 72 小时仍返回但 `is_stale=true`,前端必须明确提示。 ## 3. 即时试算 `POST /api/pricing/quote-previews` Headers:`Idempotency-Key` 必填。接口不创建 `pricing_quotes`;`preview_id` 最多可用于后续 SKU 确认 15 分钟,确认时仍会重新计算。 ```json { "store_id": "uuid", "fulfillment": "rfbs", "platform_product_category_id": "uuid", "purchase_cost_cny": "80.00", "package": { "weight_kg": "0.990", "length_cm": "30", "width_cm": "31", "height_cm": "11" }, "pricing": { "pricing_policy_id": "uuid", "transport_method_ids": ["uuid", "uuid", "uuid"], "domestic_shipping_and_label_fee_cny": "5.00", "ad_rate": "0.03", "last_mile_rate": "0.02", "withdrawal_rate": "0.01", "other_rate": "0.02", "desired_markup_rate": "0.20", "list_price_discount_rate": "0.10", "fx": { "mode": "system" }, "temporary_commission_rate": null } } ``` 规则: - `store_id` 可省略,服务端取默认店铺;非空时必须与 header 平台一致。 - `pricing_policy_id` 非空时方案提供默认值;请求中的费用、目标、运输方式和汇率仅覆盖本次试算,不修改方案。 - 无方案时所有费用、费率、目标、汇率模式和至少一个运输方式必填。 - `fx.mode` 为 `system`、`policy_fixed` 或 `one_time_override`;后者必填 `rate`,建议附 `reason`。`policy_fixed` 只对 `fx_strategy=fixed` 方案有效。 - 正式佣金规则缺失时,仅无方案即时试算或方案 `allow_commission_override=true` 可传 `temporary_commission_rate`。它必须被明确标记为临时覆盖。 - 未指定运输方式时取方案已启用的比较方式;仍为空则取方案默认运输方式。它们必须属于同一启用价卡。 返回: ```json { "data": { "preview_id": "opaque-short-lived-id", "expires_at": "2026-09-02T08:15:00Z", "context": { "store_id": "uuid", "platform_id": "uuid", "market_code": "RU", "rate_card": { "id": "uuid", "version": "CEL-OZON-RFBS-V6.17" }, "exchange_rate": { "rate": "12.33430000", "source": "cbr", "effective_on": "2026-09-02", "is_stale": false } }, "recommended_option_id": "candidate-1", "options": [{ "id": "candidate-1", "is_valid": true, "transport_method": { "id": "uuid", "code": "land_air", "name": "陆空标准" }, "logistics_product_type": { "code": "budget", "name": "Budget" }, "commission": { "rate": "0.120000", "source": "manual_rule", "version": "2026-09", "price_range": { "min": null, "max": "1500.00", "max_inclusive": true } }, "prices": { "selling_price_rub": "999.00", "list_price_rub": "1110.00", "merchandise_value_cny": "80.99" }, "weights": { "actual_weight_kg": "0.990", "volume_weight_kg": null, "billable_weight_kg": "0.990", "billing_basis": "actual_only" }, "fees": { "purchase_cost_rub": "986.74", "logistics_fee_cny": "49.6600", "logistics_fee_rub": "612.55", "domestic_fee_cny": "5.0000", "domestic_fee_rub": "61.67", "commission_fee_rub": "119.88", "ad_fee_rub": "29.97", "last_mile_fee_rub": "19.98", "withdrawal_fee_rub": "9.99", "other_fee_rub": "19.98", "total_cost_rub": "1860.76", "profit_rub": "-861.76", "gross_margin_rate": "-0.862" }, "calculation_trace": { "rounding": [], "formula_steps": [], "rule_versions": [] }, "warnings": [] }], "unavailable_options": [{ "transport_method_id": "uuid", "code": "PACKAGE_DIMENSION_EXCEEDED", "message": "最长边超过该方式限制" }] } } ``` 数值只示意响应形状,非真实 CEL 结果。每种运输方式独立成功或列出不可报价原因;一个方式失败不阻断其他方式。推荐仅按完整成本、目标利润和规则有效性计算,不承诺时效。 缺少成本、有效包装规格、类目、汇率或佣金规则时返回 `422` 和可修复字段;不返回伪造价格。 ## 4. 定价方案 方案属于 `store + platform`,币种从店铺读取。方案资源的核心形状: ```json { "id": "uuid", "store_id": "uuid", "platform_id": "uuid", "name": "CEL 常规", "note": null, "status": "active", "is_default": true, "fulfillment": "rfbs", "rate_card": { "id": "uuid", "version": "CEL-OZON-RFBS-V6.17", "provider": { "code": "CEL", "name": "CEL" } }, "default_transport_method_id": "uuid", "comparison_transport_method_ids": ["uuid", "uuid"], "fees": { "domestic_shipping_and_label_fee_cny": "5.00", "ad_rate": "0.03", "last_mile_rate": "0.02", "withdrawal_rate": "0.01", "other_rate": "0.02" }, "desired_markup_rate": "0.20", "list_price_discount_rate": "0.10", "allow_commission_override": false, "fx": { "strategy": "system", "fixed_cny_to_rub_rate": null }, "revision": 1 } ``` `GET /api/stores/{store_id}/pricing-policies?status=active&cursor={opaque}&limit=20` 按 `is_default DESC, updated_at DESC, id DESC` 返回方案。路径店铺必须属于当前工作空间与 header 平台。 `GET /api/pricing-policies/{policy_id}` 返回完整方案。 `POST /api/stores/{store_id}/pricing-policies` Headers:`Idempotency-Key` 必填。请求体采用上方形状的可写字段:创建时 `rate_card_id` 代替 `rate_card`,运输方式以 UUID 数组提交。首个 active 方案强制默认;后续 `is_default=true` 在同一事务取消旧默认。 `PATCH /api/pricing-policies/{policy_id}` Headers:`If-Match`、`Idempotency-Key` 必填。仅改提交字段;变更履约、价卡或运输方式时服务端重新校验所有关联。变更只影响未来试算/SKU 新确认,绝不重算旧报价。 `POST /api/pricing-policies/{policy_id}/set-default` Headers:`Idempotency-Key` 必填。仅 active 方案可设默认。 `DELETE /api/pricing-policies/{policy_id}` Headers:`Idempotency-Key` 必填。将方案置为 `archived`,不物理删除快照。删除默认方案时,若还有 active 方案则返回 `422 DEFAULT_PRICING_POLICY_REPLACEMENT_REQUIRED`,必须先选择替代默认;否则允许无默认方案。 ## 5. SKU 确认衔接 即时试算不落 `pricing_quotes`。商品编辑模块将定义“确认 SKU 报价”:接收 `preview_id`、SKU、最终选中候选及可选一次性覆盖,重新计算后以事务写入 `pricing_quotes + pricing_quote_options`,固化输入、汇率、佣金、CEL 规则版本和费用拆分。 客户端不能提交预览中的价格、物流费或规则 ID 作为确认事实。预览过期、规则/汇率更新或包装规格变化时,服务端拒绝旧预览并要求重新试算。临时切换方案或运输方式只进入本次 SKU 快照,绝不修改默认方案。 ## 6. 后台维护边界 普通卖家端不提供佣金类目、佣金规则、物流价卡或汇率历史的写接口。它们由受控运营后台、seed/migration 或 Worker 维护;若将来开放运营 API,必须独立鉴权、审计、版本发布和回滚。