印懿报价引擎(Yinyi Quote)
为印刷包装产品(纸盒/纸箱/手提袋/画册/宣传页/卡片/不干胶等 120+ 品类)提供实时报价。价格由印懿云端引擎计算,无本地价格库。
核心用法:由你(AI)用自己的联网能力直接调用 HTTP 接口;本 skill 的报价流程不需要运行任何联网脚本(唯一脚本是离线的输出格式化工具;如需 MCP 接入见 README)。
何时使用
- 用户给出产品(盒型/印刷品)+ 尺寸 + 数量,想知道价格
- 用户问「做 500 个 30x20x10 的纸盒多少钱」「1000 张宣传单什么价」之类的问题
- 需要比较不同数量、材质、工艺下的价格差异
报价流程
- 取得报价 Key(每台机器只需一次)——报价接口要求携带专属 Key,本 skill 不再内置共享 Key:
- 先尝试读取本地已保存的 Key:
~/.yinyi-quote/key(Windows:%USERPROFILE%\.yinyi-quote\key),文件内容就是一行yq-...字符串;读到就直接用,跳过领用。 - 读不到就领一个,并把返回值里的
data.apiKey写入上面那个文件(纯文本一行)以便下次复用:
返回POST https://zouph.com/api/skill/register Content-Type: application/json {}{"code":200,"data":{"apiKey":"yq-…","freeDaily":5,"remaining":5}},自带每天 5 次免费报价 (quotaTotal为 0 表示不设终身总次数,不是"没次数";remaining是今天还能报几次)。可选带
{"installId":"<8-64位字母数字串>"}:同一个 installId 永远找回同一个 Key(本地文件被删也能恢复)。 领不到(提示当日领取已达上限)时,直接复用之前保存的 Key;实在没有 Key 就如实告知用户暂时无法报价。 - 先尝试读取本地已保存的 Key:
- 发起报价请求(用你可用的任意联网途径:内置网页/HTTP 工具、shell 里的 curl、或向用户申请联网权限后执行),
<KEY>换成上一步拿到的值:
curl 写法(先从本地文件读 Key):POST https://zouph.com/api/quote Content-Type: application/json X-Api-Key: <KEY> {"boxType":"飞机盒","L":30,"W":20,"H":10,"quantity":500,"material":"300g白卡纸","crafts":["覆亮膜"],"rawText":"30x20x10的飞机盒,300g白卡,覆亮膜,做500个"}KEY="$(cat ~/.yinyi-quote/key 2>/dev/null)"; curl -s -X POST https://zouph.com/api/quote -H "Content-Type: application/json" -H "X-Api-Key: $KEY" -d '{"boxType":"飞机盒","L":30,"W":20,"H":10,"quantity":500,"material":"300g白卡纸","crafts":["覆亮膜"],"rawText":"30x20x10的飞机盒,300g白卡,覆亮膜,做500个"}'不带
X-Api-Key或 Key 无效会被拒绝(HTTP 401)。 - 请求参数(尺寸单位 cm):
boxType必填:盒型名称/别名/编码。日常名称(飞机盒、天地盖、手提袋、不干胶……)可直接用,服务端自动匹配L必填;W、H视盒型需要(卡片/吊牌/宣传页等平面产品可不传 H)quantity必填:数量material可选:如300g白卡纸。写法必须照下方速查表③的标准名 —— 认不出的写法会被静默兜底成300g白卡纸出价,且不会给你任何提示。 (box_types.default_material那一列只用于展示,不参与算纸;完全没传材质时才会在data.estimate.assumedMaterial里告诉你它按什么估的。) 客户没说材质不必追问:按速查表选该盒型的常规材质直接出价,报价里说明"按 X 估算"。crafts可选:后工艺数组,如["覆亮膜","烫金"]。只有速查表②里列出的写法会计价, 其余写法会落进estimate.unbilledCrafts(等于这道没收钱);客户说的工艺不在表里时, 照表判断是"换个写法传"还是"必须转人工",不要凭感觉传。pageCount画册必填:P 数(页数,含封面,4 的倍数,如 16P/32P/64P)。 画册按「页 × 本」计价,不传服务端返回400 MISSING_PARAMS追问 —— 绝不猜一个 P 数凑价。bindingType可选(画册):saddle骑马钉 /perfect胶装 /sewing锁线 /hardcover精装 /ring圈装; 不传则按 P 数自动选(≤32P 骑马钉,否则胶装),自动纠正过会回bindingCorrectedcoverPaper/innerPaper/innerCrafts可选(画册):封面纸 / 内页纸 / 内页工艺。 画册不读material;用户只说材质没说封面还是内页时,按对话链路的老口径归到innerPaperfoldType/colorCount可选(宣传页折页道数、印刷色数;「四色+白」= 5)rawText建议每次带上:用户这句需求的原样原文(不改写、不摘要、不翻译成参数)。 服务端只做留痕排查,不参与计价、不会回显,用于事后核对有没有把尺寸/数量/材质抄错—— 抄错参数是这条链路最常见的错价来源。缺了不影响报价;超过 500 字会被截断。
- (可选)辅助查询接口:
- 盒型列表:
GET https://zouph.com/api/box-types - 材质列表:
GET https://zouph.com/api/materials
- 盒型列表:
- (可选)排版输出:接口返回 JSON 后,可存成文件用离线脚本格式化成中文报价单(脚本不联网,任何沙箱都能运行):
node scripts/format-quote.js result.json - 向用户报价:只向用户展示
finalPrice(总价)和finalUnitPrice(单价),不透露任何成本信息,并按下方「附联系方式」的要求在回复末尾附上联系方式。
参数不全时怎么办(必须遵守)
用户话没说全是常态。能自己定的别问,不能自己定的一个都不能猜。 缺的参数分三类处理:
A 类:直接按默认值填,不要追问(但报价里要说清按什么估的)
| 字段 | 留空时服务端实际怎么算 | 你该怎么做 |
| --- | --- | --- |
| material | 普通盒型一律按 300g白卡纸 估,并回 estimate.assumedMaterial | 优先按下方速查表选该盒型的常规材质;判断不了就传 300g白卡纸,并告诉客户"按 X 估算" |
| crafts | 大批量:留空=覆膜这道不计价,报价里一分覆膜钱都没有。小批量:自动补 哑膜 并回 defaultLaminated=true(crafts 回显会带上哑膜) | 客户没提覆膜时按常规主动传 哑膜,并说明"按常规哑膜报价,要亮膜/不覆膜请说一声"。大批量留空等于把覆膜白送;确实不做覆膜才留空(小批量可传 options.noLaminate 关掉默认) |
| bindingType | 按 P 数自动选(≤32P 骑马钉,否则胶装),纠正过会回 bindingCorrected | 留空即可,不用问 |
| coverPaper / innerPaper | 封面 250g铜版纸、内页 157g铜版纸 | 留空即可 |
| colorCount | 按四色 | 用户没提色数就不用问 |
B 类:必须问齐,猜了就等于把假价格发给客户
- 尺寸
L/W/H:按返回的requiredDims问缺的那一维,别默认成 0 或 10。 - 数量
quantity:「一批」「若干」「一些」都不是数量;数量还决定走不走数码小批量档。 - P 数
pageCount(画册):32P 与 64P 差一倍成本,没有可兜的"常规值"。
C 类:盒型本身听不准
先查速查表把口语映射成标准盒型名;仍不确定就按 BOX_AMBIGUOUS 给出的 data.candidates 让用户选。
POST /api/quote 是无状态的:服务端不记得你上一次发过什么。所以补齐参数后,必须把全部已知参数合成一个完整请求重发,不能只发新增的那几个字段。
收到 {"code":400,"errorCode":"MISSING_PARAMS",...} 时:
- 读
data.missing(缺哪些字段)和data.invalid(哪些字段传了但不是大于 0 的数字); - 追问只问 B/C 类缺项,把它们合并成一条消息问完(可直接转述
data.askUser,配合data.missingLabels); A 类缺项不要出现在追问里 —— 自己按表填掉,问了就是白问一轮; - 用户答完后,合并成完整参数重发一次请求。
data 里可直接使用的字段:missingLabels(缺项的中文说法)、boxCode / boxName(已识别出的盒型)、requiredDims(该盒型需要哪几个尺寸,如 ["L","W","H"])、defaultMaterial(该盒型默认材质)。判断该问哪些尺寸要看 requiredDims,比按盒型名猜可靠。
红线(与 A 类的"可以兜"配套,别越过它):
- B 类三项任何情况下都不许猜,包括用户说「你按常规来」「随便估一个」—— 那种情况下可以兜的仍然只有 A 类;用户明确不肯给尺寸/数量就如实说给不出价,并附联系方式转人工。
- 用了 A 类默认值必须说出来:报价里写清"按 300g白卡纸估算 / 覆膜按常规哑膜报 / 骑马钉装订", 不能让客户以为这些是他自己说过的配置。
- 响应里只要有
data.estimate,说明这一单有一部分没算钱:estimate.unbilledCrafts(线上无价档的工艺,如"贴亮片")+estimate.contactRequired=true时, 必须把estimate.hint原样转述并告知这些工艺要人工核价;estimate.assumedMaterial表示材质是系统替你估的,转述时带上"按 X 估算"。 - 参数类 400 不消耗额度(服务端只对成功报价计数),放心追问后重发。
- 一次追问只发一条消息,把缺项列全;用户答完后只重发一次请求,不要逐字段试探性重发。
- 每次请求都带
rawText(这一轮用户说的原话,合并重发时带上最新那句):它不计价、不回显, 只让服务端能核对「AI 填的参数」和「用户实际说的话」是否一致。不带也能出价,只是出了错查不出来。
一轮问答示例:
用户:30x20x10 的盒子多少钱
你 → POST /api/quote {"boxType":"盒子","L":30,"W":20,"H":10,"rawText":"30x20x10 的盒子多少钱"}
服务端 → code 400, errorCode MISSING_PARAMS, data.missing=["quantity"], data.askUser="请补充:数量"
你 → 用户:还需要数量,您这批要做多少个?
用户:500 个
你 → POST /api/quote {"boxType":"盒子","L":30,"W":20,"H":10,"quantity":500,"rawText":"500 个"} ← 全部参数一起重发,原话带这一轮的
(若这次返回 BOX_AMBIGUOUS,就按候选盒型让用户选,再把选定的 boxType 连同尺寸数量一起重发)
常用参数速查表(填参数前先查这里)
这三张表是服务端真实计价口径的摘要(2026-09-12 按价格库与引擎实测整理), 唯一用途是把客户口语映射成服务端认得的写法。两条边界:
- 表里没列 ≠ 不支持:全量以
GET /api/box-types(122 个盒型)与GET /api/materials为准,先查接口再决定追问还是转人工。 - 表里列了 ≠ 价格是它:本表不含任何价格,价格一律以
/api/quote返回值为准,严禁照本表口算。
① 盒型:按"要哪几个尺寸"分组记,比按名字猜可靠
- 只要
L+W(别传 H):画册、宣传页(=宣传单/单页/传单/彩页/海报/DM单)、名片、卡片、吊牌、不干胶、标签、卡头、对折卡、贺卡、明信片、邀请卡、腰封、台历、挂历、说明书、菜单、文件夹、资料册、红包、织唛、纸罐/纸筒、纸杯、纸碗、纸盘、纸管、纸桶、复合纸罐 - 只要
L+H(别传 W):圆筒精装盒(=圆筒盒)、正六边形插锁管式盒、正六边形对盖盒、正八边形插锁盒 - 要
L+W+H:其余全部盒型,包括 ⚠️信封 / 信封袋 / 档案袋(它们是立体袋,不是平面印刷品) - 卡纸彩盒(常规
300g白卡纸):双插盒(=插口盒/卡纸盒/化妆品盒)、单插盒、反插盒、法式插盒(=防尘翼插盒)、斜口插盒、扣底盒、自锁底盒、吊孔盒(=挂孔盒)、平粘盒、机包盒、纸巾盒(350g)、开窗盒、展示盒、挂钩盒、陈列盒、抽屉盒、枕头盒、蛋糕盒(400g)、喜糖盒(350g) - 飞机盒族(常规
300g白卡纸):标准飞机盒(=飞机盒/快递盒/邮寄盒/飞鸡盒)、加强飞机盒、拉链飞机盒、连体飞机盒、回箱飞机盒、民航盒(双耳) - 瓦楞运输箱(常规
250g白卡纸+E瓦):平口箱(=RSC/标准开槽箱)、全封口箱(=FOL)、对盖箱(=CSC/中缝对开箱)、半开槽箱、重叠盖箱、瓦楞飞机盒、瓦楞翻盖盒、瓦楞披萨盒、瓦楞展示盒 - 精品盒(走灰板裱纸,需
L+W+H):天地盖(标准)(=天地盖/天盖地/上下盖)、中框天地盖、深盖天地盖、浅盖天地盖、内托天地盖、书型盒(标准)、磁吸书型盒、双开门书型盒、磁吸翻盖盒(=精装翻盖盒)、精装抽屉盒、多层抽屉盒、侧拉抽屉盒、折叠精装盒、心形精装盒、异形精装盒、升降盒、对开盒、套盒
易混对照(这些说法一定先问清,别自己挑一个 —— 挑错盒型=整份报价错):
| 客户这么说 | 会撞到 | 怎么处理 |
| --- | --- | --- |
| 民航盒 | 「标准飞机盒」的别名 与 「民航盒(双耳)」的正式名 | 问是不是双耳款;说不清就传 标准飞机盒 |
| 翻盖盒 | 磁吸翻盖盒 / 瓦楞翻盖盒 / 翻盖盒(连体) | 问是精装、瓦楞还是卡纸连体 |
| 六角盒、六边形盒 | 正六边形插锁管式盒 与 正六边形对盖盒 | 问是插锁管式还是天地盖式 |
| 展示盒 | 展示盒 / 展示盒(PDQ) / 瓦楞展示盒 / 展示精装盒 | 问材质与用途 |
| 抽屉盒 | 抽屉盒(卡纸) / 精装抽屉盒 / 多层抽屉盒 / 侧拉抽屉盒 | 问卡纸还是精装 |
| 披萨盒 | 披萨盒(卡纸) 与 瓦楞披萨盒 | 问材质 |
| 对盖盒 / 对盖箱 | 一字之差:卡纸盒 与 瓦楞纸箱 | 别替客户改写 |
| 圆筒盒 / 纸罐 | 圆筒精装盒(要 L+H)与 纸罐/纸筒(要 L+W) | 问是精装筒还是食品纸罐 |
| 彩盒、盒子、包装盒 | 类目俗称,不是盒型 | 落成具体盒型;「彩盒」按卡纸插口盒族给候选(双插/单插/反插/法式插/斜口插) |
② 后工艺:写错了不报错,只会静默不计价
crafts 里每一项都拿去查价档;查不到时不返回错误,只列进 data.estimate.unbilledCrafts。
写法的价值就在这里:同一种工艺,写法对了收钱、写法错了等于免费送客户。
✅ 会计价,照这些写法原样传:
- 覆膜:
哑膜(=覆哑膜/亚膜/哑胶/亚胶/哑光)、亮膜(=覆亮膜/光膜)、触感膜、镭射膜、防刮膜(=耐磨膜)、预涂膜。 只写覆膜两字 → 服务端按哑膜收(含糊按哑膜是既定口径,不必追问)。 - 烫印:
烫金、烫银、烫镭射(只认这三个词)。 - 上光:
UV、局部UV、逆向UV、上油(=光油)。 - 压纹:
压纹、凹凸(=击凸/激凸/浮雕,同组一档)。 - 裱贴:
对裱(=裱糊/裱卡/双裱/裱纸)、裱瓦楞(=裱坑/坑纸/E瓦)、裱F楞(=F瓦)、双面裱、大面积对裱、手工对裱。
⚠️ 不计价,传了必须转人工(报价里要说"这部分未含,需人工核价"):
磨砂(单独写不计价;要磨砂效果传 UV 最干净 —— 磨砂UV 会被拆成"磨砂+UV"两道,磨砂那道仍不计价)、
珠光上光(传 上光 或转人工)、3D立体烫、烫黑金/古铜金、植绒、贴亮片、滴胶、烫钻。
➖ 不必追问、也不要当工艺传(属正常工序,盒型后道费里已默认包含,传了不计钱):
模切/啤切、粘盒/糊盒/胶盒、压痕、V槽、印刷。
四色/黑白/专色/白墨/加白 这些是色数不是工艺 → 走 colorCount(「四色+白」传 5)。
③ 材质:写法格式错了会静默换纸,且不给你任何提示
统一写成 <克重>g<标准名>(300g白卡纸、157g铜版纸)。300克白卡 也认;白卡300克 不认。
🔴 最要命的一条:传上去的材质若服务端认不出,会被静默兜底成 300g白卡纸 出价,
且 estimate.assumedMaterial 不会出现(那个字段只在"你压根没传材质"时才给)。
也就是说:你传 特硬牛皮纸,拿到的是白卡纸的价,而响应里看不出任何异常。
→ 材质一律用下面的标准名,别把客户原话直接塞进 material。
常用标准名(括号内是支持的克重范围 g/m²):
- 卡纸:
白卡纸(190–400)、彩色卡纸(120–400)、黑卡纸(120–700)、金银卡纸(200–400;金卡/银卡都归这一档)、红卡纸(160–450) - 铜版纸:
单面铜版纸(105–400)、双面铜版纸(105–400)、哑粉纸(80–350)。⚠️ 只写"铜版纸"会按单面算 - 印刷纸:
双胶纸(70–400)、胶版纸(60–180)、书写纸(45–100)、轻型纸(50–80)、纯质纸(60–120)、蒙肯纸(70–150)、新闻纸(40–52) - 牛皮纸:
本色牛皮纸(40–150)、白牛皮纸(40–150) - 纸板:
灰板纸(250–2000)、白板纸(200–500)、白纸板(200–500)、箱板纸(170–440)、挂面纸(125–300)、茶板纸(170–400) - 瓦楞:
E瓦、F瓦、B瓦、AB瓦、BC瓦、瓦楞纸板(300–2000)、瓦楞原纸(80–180) - 特种纸:
珠光纸(180–320)、艺术纸(100–400)、硫酸纸/描图纸(40–120)、特种纸(综合)(60–600) - 不干胶:
普通不干胶、铜版纸不干胶、书写纸不干胶、牛皮纸不干胶、热敏纸不干胶、白底不干胶、合成纸不干胶、透明PET不干胶
克重规则:
- 纸类(卡纸/铜版纸/双胶纸/灰板纸…)要带克重;不带也能出价,但取的是默认档,不准。
- 瓦楞(
E瓦/AB瓦…)、不干胶、PET/PP/PVC、织唛不带克重 —— 传300gE瓦是错的。 - 只报克重、没报纸名(如
800g)且克重超过 700g 时,服务端自动按灰板纸算(纸板阈值,后台可调)。 写了纸名就不改判:800g白卡纸仍然按白卡取档 —— 而白卡的克重上限只有 400g,出现这种写法八成是客户把 纸板说成了卡纸,该问一句"是要灰板对裱还是厚卡纸",别直接照传。 - 画册不读
material,用coverPaper/innerPaper;客户只说材质没说封面还是内页时归到innerPaper。
返回结果解读
成功:{"code":200,"message":"报价/下单咨询请联系:…","data":{...}},data 关键字段:
finalPrice/finalUnitPrice最终报价与单价(只向用户报这两个价格)contact联系方式文案(报价回复末尾附上,见「附联系方式」)。顶层message是同一条话术, 2026-09-11 起 200 响应也带 —— 就算你漏了data.contact,把message转述出去也比什么都不说强boxName/params/crafts/billQty盒型与参数回显(用于复述需求,billQty与quantity不同时要说清"按 N 个计价")nesting拼版方案(幅面、每版拼数、印张数)—— 给你自己核对用,不要转述给客户。 ⚠️ Key 没有绑定到账号名下时这个字段不下发(见下条),别再指望它一定在quoteNote+ 取整过的价格:未绑定账号的 Key 拿到的是"取整参考价"(总价取整到元、单价两位小数、 不给拼版明细,2026-09-11 起)。看到这个字段就照实说"这是线上参考价,确认材质与工艺后给精确报价单", 不要把它当成可对账的成品价念给客户;绑定过账号的 Key(付过次数包)与小程序/网页登录态拿的是精确价- 成本字段(
totalCost/unitCost/breakdown/profitRate)服务端已不再下发(2026-09-09 起)。 老版本脚本若还在读它们,读到 undefined 就当作"没有这项",不要报错、更不要向用户解释"看不到成本" estimate(有内容时必须照做,没有这个字段就说明报价是完整的):这一单里"系统没算到的部分"。estimate.unbilledCrafts:这些工艺写法线上没有价档,一分钱都没算进去。 例:用户要"贴亮片",返回的finalPrice是一个不含亮片的价格。estimate.contactRequired = true:只要有unbilledCrafts就一定带上。此时必须把estimate.hint原样转述给用户,并说明这些工艺要联系人工核价; 禁止把这个价当成"含全部工艺的成品价"报出去 —— 那等于让客户以为亮片是免费的。estimate.assumedMaterial:用户没给材质时,服务端实际按哪个算的。转述时带上"按 X 估算"。
失败:HTTP 状态码仍是 200,失败信息在 body 的 code 字段里(code:400/404/500),并带 errorCode。
先看 errorCode 决定动作,不要靠猜 message 文案;data.askUser 是可以直接转述给用户的中文句子。
| errorCode | body code | 含义 | 你该做什么 |
| --- | --- | --- | --- |
| MISSING_PARAMS | 400 | 缺参数,或参数不是大于 0 的数字 | 按「参数不全时怎么办」一次问齐,补齐后带全部参数重发 |
| BOX_AMBIGUOUS | 400 | 用户说的名字对应多种盒型 | 把 data.candidates(每项含 name 与 requiredDims)列给用户选;选定后连同尺寸一起问齐再重发 |
| BOX_UNKNOWN | 404 | 没有这个盒型的报价公式 | 调 GET /api/box-types 找相近盒型让用户确认;确实没有就如实说明并附联系方式 |
| BOX_CONTACT_ONLY | 400 | 异形定制产品,需人工核价 | 别硬算,直接转述 data.askUser,并附上 data.contact |
| ENGINE_ERROR | 500 | 服务端计算异常 | 不要反复重试;如实告知稍后再试,并附联系方式 |
| QUOTA_EXHAUSTED | HTTP 429 | 报不了价了:当天 5 次免费额度用完(带 data.resetsTomorrow: true)或买的/总的次数用完 | 见下面「额度用完了怎么充值」 |
| DAILY_LIMIT | HTTP 429 | 付费 Key 的当日速率上限(每 Key N 次/天),明天自动恢复 | 不要引导充值,如实告知明天恢复 |
只有额度、鉴权、限流才用真实的 4xx 状态码:
- 401:
X-Api-Key缺失或无效 → 回到流程第 1 步读回/领取 Key 后重试一次 - 403:该 Key 已被吊销 → 重新领一个 Key 并覆盖本地文件;若是刚被拒后又反复重试,可能触发了 429 累犯临时封禁,等约 15 分钟
- 429 且没有
errorCode:触发分钟级频率限制(报价 10 次/分钟)→ 等约 1 分钟后用原参数重试;同参数 60 秒内服务端有缓存,别短时间反复重发
额度用完了怎么充值
免费额度是「每天 5 次」,不是「总共 5 次」:每台机器领一个 Key,每天 00:00 自动恢复,当天用完才涉及充值。
用户当天问第 6 次时,/api/quote 返回 HTTP 429 + errorCode: "QUOTA_EXHAUSTED"(响应带
data.resetsTomorrow: true、data.freeDaily: 5、data.dailyUsed),body 的 data.recharge 里直接写明了下一步该调哪个接口。
这时先把两件事都说清:明天 00:00 会自动恢复 5 次;想今天就继续,需要在充值页绑定手机号登录并购买次数包。
在用户付钱之前反复重试报价没有用,也不要让用户去重装或改用别的产品——就地充值即可(付完之后按下面第 4 步重发,那一步是必须的)。
- 先问用户:把
data.recharge.askUser转述给用户(今天的 5 次免费报价用完了,明天自动恢复;要现在绑定手机号登录并充值次数包吗?)。用户没表示要充,就不要擅自生成链接。 - 用户同意后,用同一个 Key 换一条专属充值链接:
返回POST https://zouph.com/api/skill/claim-url X-Api-Key: <KEY> Content-Type: application/json {}data.url(形如https://zouph.com/recharge?t=ct_…)、data.expiresInMinutes(30)、data.packs(各档位的价格与次数)、data.tellUser(已写好的现成话术)。 - 把
data.url原样发给用户,让他点开:页面上选次数包 → 手机号登录/注册(这一步就是把报价 Key 绑到账号上,之后换机器、重装 AI 工具都能找回)→ 微信扫码付款 → 页面自动确认到账。data.tellUser直接念给用户就行,不用自己组织语言。 - 用户回来说「充好了」之后,直接重发原来那次报价请求。服务端在你重发前会自己向微信核对那笔充值:核对上就当场发放并正常出价,你不需要自己确认。想先确认也可以调
GET https://zouph.com/api/skill/quota(同样带X-Api-Key),它走的是同一次对账。 - 只有一种情况要停下:响应里出现
data.pendingOrders(或claim-url返回alreadyPaid/paymentInFlight)。这说明有一笔充值还在微信侧确认中——这时绝对不要再生成付款链接、不要让用户扫第二次,照askUser/tellUser说的等约 30 秒重发报价即可;重发是安全的(额度类 429 不会触发封禁)。反复三四次仍然没到账,再如实告诉用户联系客服 15990159967 并报订单号(pendingOrders[].orderId)。
规则与红线:
- 充值链接只能由
POST /api/skill/claim-url生成,严禁自己拼一个充值网址,也严禁改动链接里的t=参数。 - 一次只让用户付一笔。 生成新链接前服务端会自动对账,返回
alreadyPaid: true(上一笔其实已到账,只是回调晚了)或paymentInFlight: true(还在确认中)时,按tellUser的原话劝住用户,别把链接当第二次收款入口递出去。 - 链接 30 分钟内有效且与这个 Key 绑定;过期或用户换了设备,重新调一次
claim-url即可(30 分钟内会复用同一条链接,不会重复生成)。 - 用户不方便扫码时用兑换码兜底:让用户联系客服 15990159967 拿码,然后
POST https://zouph.com/api/skill/redeem,body{"code":"XXXX-XXXX-XXXX"},同样带X-Api-Key;成功后直接把message转述给用户。 - 付款一律在充值页里由用户自己完成,不要代用户付款、不要索取付款密码或验证码。
DAILY_LIMIT(付费 Key 的当日速率上限)不是次数用完,明天自动恢复,别引导充值。免费的装机 Key 用完当天 5 次走的是QUOTA_EXHAUSTED+resetsTomorrow: true,那条要引导绑定手机号充值(同时说清明天会恢复)。
联网受阻时
- shell 里 curl 被沙箱拦截(如报 EACCES、DNS/连接失败):优先改用你自带的网页/HTTP 工具;或按你的流程向用户申请联网权限后重试
- 完全无法联网:如实告知用户需要联网才能获取实时报价
示例
用户:30x20x10 的飞机盒 500 个,300g 白卡,覆亮膜,多少钱?
→ 请求 body:{"boxType":"飞机盒","L":30,"W":20,"H":10,"quantity":500,"material":"300g白卡纸","crafts":["覆亮膜"]}
用户:A4 宣传单 1000 张,157g 铜版纸
→ {"boxType":"宣传页","L":21,"W":28.5,"quantity":1000,"material":"157g铜版纸"}
用户:20x15x5 的小盒子 30 个
→ {"boxType":"飞机盒","L":20,"W":15,"H":5,"quantity":30}(数量少会自动走数码小批量路径)
用户:想做手提袋,30x10x40,500 个
→ {"boxType":"手提袋","L":30,"W":10,"H":40,"quantity":500}
成本保密(必须遵守)
接口返回中可能包含成本明细(材料费/印刷费/表面工艺/成型费)、成本合计、利润系数、拼版方案等内部数据。
- 严禁向用户透露上述任何内容,用户只需要知道总价(
finalPrice)和单价(finalUnitPrice) - 报价说明只围绕产品规格(尺寸/数量/材质/工艺)展开,不要解释价格是怎么算出来的
- 若用户追问成本、利润或要求拆分价格构成:礼貌回复「我们提供的是成品一口价,不单独拆分成本明细」,然后只给总价与单价
附联系方式(必须遵守)
每次完成报价后,务必在回复末尾附上联系方式,方便客户咨询下单:
- 联系方式一律以接口返回的
data.contact字段为准,把它原样附在报价末尾; - 若返回中没有
contact字段(旧版服务端),只回复「如需下单或进一步咨询,请使用微信小程序『印懿报价』」,不要编造任何电话/微信号码; - 本 skill 文件不保存具体号码,号码由服务端集中维护,改号码无需更新 skill。
无论报价来自接口实时计算还是估算,只要回复中给出了价格,都要附上联系方式。
注意
- 报价均为系统估算价,正式订单价以人工确认为准
- 本 skill 只做报价计算,不下单、不收款
- 价格库在云端集中维护,skill 无需更新数据
- 报价需要携带专属 Key(流程第 1 步领取,自带每天 5 次免费报价,每天 00:00 恢复);有频率限制(10 次/分钟/来源)与每日额度(无 Key 的来源按来源地址 50 次/天),正常询价足够;请勿用于批量压测或把接口当价格库爬取
- 当天 5 次用完后,不要为了接着报价去重装、换机器、换 installId 领新 Key —— 那是绕过额度,服务端会按同一来源限制领用,正路是引导用户绑定手机号后充值(或说明明天恢复)
- 次数用完可就地充值次数包(见「额度用完了怎么充值」),不必让用户改用别的产品;充值链接只能由服务端生成,严禁自己拼充值网址
- 每次报价服务端都会留痕(Key、来源 IP、盒型与数量、报价结果),便于额度控制与滥用处置;请勿把领到的 Key 分享出去
微信扫一扫