凌晨1点,最后一个commit push上去。
13个commit,60+文件,两天。
Picboil从"功能能跑",变成了"接近生产级"。
今天把这两天的核心思考摊开——做AI出海产品,定价、国际化、管理后台,这三件事到底怎么做才对。没有玄学,全是具体踩坑。
一、定价系统:套餐设计不是定数字,是定用户预期
很多AI工具的定价逻辑是这样的:
成本1块钱/张4K图,加30%利润,售价1.3块钱/张,定个"38块钱30张"。
这套逻辑有什么问题?
问题在于:你不知道自己在卖什么。
用户买的不是"30张图",用户买的是"稳定的图片生成能力"。但你的定价让用户觉得你卖的是"消耗品"。消耗品的逻辑是:用完再买,没有预期,不知道什么时候钱就没了。
Picboil的套餐设计是另一套逻辑:
免费体验:先让你感受产品,积分够出几张图,看得见效果。
基础套餐:低门槛日常用,按量付费,适合偶尔玩玩的用户。
Pro订阅:月付,解锁高清模型,稳定使用,不占用单次积分。适合高频用户,有预期支出,不怕哪天积分突然清零。
4K分辨率:专业用户,出图质量最高,积分消耗也最高。
为什么要这样分?
因为我自己就踩过坑。
早年在别的平台付费,买完发现——积分用完就没了,下次还得重新买。没有稳定供应,没有预期支出,那感觉就像住酒店,押金什么时候扣光的都不知道。
订阅解决的不是定价技巧,是用户预期管理。
但订阅背后,必须有成本矩阵支撑。
你得知道自己在卖什么:
一张4K图片的成本 = API调用费用 + 服务器费用 + 图片存储费用 + 带宽费用
Pro月费定价能不能覆盖这个成本?单次购买和订阅的ROI差多少?
没有成本矩阵,你定38块钱一个套餐,可能每卖一张图亏5毛。
你自己不知道。
亏着亏着,平台就倒了。
Picboil 的成本矩阵是这样的——基于 Google Gemini API 实际计价:
会员订阅计划(USD)
积分消耗 = 模型系数 × 分辨率系数(向上取整)
毛利估算(基于充值包 $0.13~0.20/cr)
关键结论:Pro+4K 是利润主力,NB2 是甜点区间。
付费后模型解锁的时机也很关键。
Stripe webhook回调是异步的,用户支付成功后,订阅状态更新可能有延迟。
如果用户付完钱,模型还是锁着的,他会觉得"我付了钱但没享受到服务"。差评。
修复方案:isActiveMember的判断要同时检查past_due和current_period_end。即使Stripe回调还没到,只要支付成功了,current_period_end就有值,就能提前解锁模型。
这个细节不做,用户体验就差一截。
Day 4那天我还修了一个经典的积分精度bug。
Math.ceil和Math.round在多语言环境下的表现完全不同。
Math.ceil(49.1) = 50,Math.ceil(49.9) = 50,但Math.round(49.9) = 50。
用户充值50块钱,账户里可能显示49.9。
"这平台偷偷扣我钱。"
他不会去研究Math.ceil和Math.round的区别。客服解释不清楚,差评。
就这么简单。
修复:统一用Math.round。用户的50,就是50.0,一分钱都不会多收。
但这背后暴露的问题是:积分系统里的所有数学运算,都要过一遍精度检查。不是积分,是所有涉及金钱计算的地方。
CSP安全加固也是Day 4的重点。
生产环境的Content Security Policy,把unsafe-eval关掉了。
开发环境需要unsafe-eval来支持HMR(热模块替换),不然每次改代码都要重新编译。但生产环境如果还开着,那就等于在用户浏览器里开了一个后门。
攻击者可以利用unsafe-eval执行任意JavaScript代码。
这个bug修完之后,用户数据在浏览器端的安全性提升了一个档次。
用户感知不到,但他们在你的网站上输入的每一个字符,都是安全的。
二、国际化:翻译只是最后一步,不是第一步
大多数团队做国际化是这样开始的:
1. 找一套i18n库 2. 把现有文案翻译成韩文、日文、英文 3. 扔上去
然后呢?
Google搜索"AI image generator",韩国用户搜到的页面标题是中文。
日本用户点进来,hreflang标签指向中文版。
这不是出海,这是"语言包换皮"。
Picboil踩过的坑,列一下:
坑1:hreflang标签全错
最初只有en和zh两个语言版本,ko和ja页面没有hreflang标签。搜索引擎不知道该把哪个版本推给哪个用户。韩国用户搜"AI图片生成工具",搜到的可能是中文版。
这个坑的代价是什么?你的SEO流量全部漏给中文版。韩国用户想来,来不了,看到的是中文内容,关掉页面走人。
修复:每个语言版本补充独立的hreflang标签 + x-default。韩国用户搜到韩文版,日本用户搜到日文版,中文用户搜到中文版。sitemap.xml也要四语言全覆盖。
hreflang不难配置,难的是意识到要做这件事。很多产品上线半年了,sitemap里还是只有中文链接,英文版根本不在搜索引擎里。
坑2:Stripe定价硬编码中文
用户选了韩文界面,套餐价格显示的还是人民币符号。
因为Stripe的产品名称和描述是在代码里写死的中文。
这套系统上线三个月,韩文用户看到的一直是"¥38",日文用户看到的是"¥38"。
他们不知道这是人民币,他们以为工具在胡乱定价。
"这什么垃圾产品,价格乱标。"
他们不知道这是开发者的疏漏,他们只会觉得被骗了。
修复:Stripe产品描述全部走i18n,改成locale-neutral格式。韩文用户看到₩4,900,日文用户看到¥490,中文用户看到¥38。
这不是简单翻译,是整套定价数据结构的重构。
Stripe的product和price ID要按语言分开创建,但price amount统一用整数存储(最小货币单位),前端按locale格式化成对应符号。
这意味着:后台数据库里只有一个价格,但Stripe那边有四个price ID,前端根据用户语言动态渲染。
没有这个架构,你的定价就永远是乱的。
坑3:积分计算精度问题
Math.ceil和Math.round在多语言环境下的表现不一致,这个坑在前面的定价章节提过,但国际化场景下更严重。
韩文和日文的数字格式和中文不一样,千位分隔符、小数点符号都可能不同。
如果你的积分计算用的是toLocaleString(),在某些locale下会显示成"49,9"而不是"49.9"。
用户看到账户余额是"49,9",会认为平台扣了他0.1积分。
"充值的时候明明是50,怎么变成49了?"
修复:统一在前端渲染前用固定格式,后端数据库只存原始数字,不做本地化处理。本地化只在最后一步做。
坑4:维护成本爆炸
加了新的文案,四套语言文件要同步更新。靠人工记着哪改过哪没改过,迟早漏。
漏了会怎样?某个页面有英文残留,某个按钮还是中文,用户一眼就看出来"这产品没做完"。
Picboil的解法:i18n审查流程——新增文案必须同步四种语言,漏了CI不通过,不让合并。
代码层面,禁用链式三元判断locale。所有用户可见文本走t('key'),不允许locale === 'zh' ? '中文' : 'English'这种写法。
一旦有人写了这种代码,ESLint直接报错。
Picboil的国际化架构是这样的:
src/messages/ en.json # 英文 zh.json # 中文 ko.json # 韩文 ja.json # 日文所有翻译key统一管理,新增一个key要同时出现在四个文件里。
定价数据存在数据库,不硬编码,靠locale-neutral格式渲染到前端。
出海选韩文和日文,不是因为市场最大,是因为竞争最小。
英文市场红海一片,Midjourney、Leonardo、DALL-E全在那。中小团队进去就是炮灰。
韩文市场:用户对本地化产品接受度高,付费意愿强,但竞争产品少。Kakao生态做得好,本地竞品的功能普遍比英文产品弱。
日文市场:同上,用户习惯用本土产品,黏性高。日本用户对订阅制的接受度比中国用户高很多。
中文市场:Picboil本身就是中文产品,天然优势,不需要额外出海动作。
三个市场,三套用户习惯,三套定价策略。
不是"翻译完就出海",是"理解市场后再进去"。
三、管理后台:没有数据,你连用户在干什么都不知道
很多人问:"为什么要做管理后台?"
简单说:因为没有它,你就是睁眼瞎。
你开了一个AI图片生成工具,用户充值、付费、订阅、消耗积分——这些数据如果只有你自己能看到,你怎么运营?
哪个套餐卖得最好?哪些用户在大量充值?你的成本是多少?利润是多少?某个用户说积分没到账,你怎么查?
没有管理后台,这些问题一个都回答不了。
你只能靠用户反馈。用户说"我充了100没到账",你才知道出问题了。
但用户不反馈呢?用户直接走人,不告诉你原因。
你的流失率是多少?不知道。用户为什么流失?不知道。下个月该做什么优化?还是不知道。
Picboil管理后台的五个核心模块:
1. 套餐管理
套餐名称、描述、价格、积分数量、每个套餐包含哪些模型权限。这些都要能随时改,不用发版,不用重新部署。
定价不是一次定完的。第一个月试水,发现基础套餐定低了,成本覆盖不住,第二周就要调。
没有管理后台,你得改代码、发版、等着CDN缓存失效。
有管理后台,点两下就改完了,改完即时生效。
更重要的是:你能看到每次调价前后的收入变化。调价之后,付费用户多了还是少了?客单价涨了还是跌了?
这些数据决定了你的下一个决策。
2. 充值记录
用户的每一笔充值都有记录:金额、时间、支付渠道(Stripe/微信/支付宝)、支付状态(成功/失败/待确认)、关联的账户ID。
任何一个用户说"我充了钱没到账",你5秒钟能查到:支付成功了没有、钱去哪了、积分有没有到账。
没有这条记录,你只能对用户说"我帮你查一下",然后在那干瞪眼。
充值记录还有另一个作用:识别异常。
如果某个账户在短时间内充值了10次,金额都是最小档,你要不要查一下?这是用户在薅羊毛,还是黄牛在套现?
没有数据,你看不见。
3. 订阅管理
哪些用户在订阅Pro会员?订阅什么时候到期?续费率多少?月环比收入变化是多少?
续费率决定了你下个月的预期收入。如果这个月续费率突然掉了,从80%掉到60%,你要马上知道原因。
是产品出问题了?是竞争对手在做促销?还是某个bug导致用户体验下降了?
订阅管理让你能追溯到每个订阅的详细状态:active、past_due、canceled、trialing。
更重要的是:你能看到即将到期的订阅列表,提前做续费提醒。
很多订阅产品的续费率低,不是因为用户不想续,是因为用户忘了到期时间。提前3天发一封邮件,续费率能提升15%。
4. 收入统计
今天的收入、本周的收入、本月的收入,用图表展示。
不是给你看的,是给投资人看的,给合作伙伴看的,给你自己做决策用的。
你需要知道:收入是在增长还是在下滑?哪个套餐贡献最多?哪个渠道来的用户付费意愿最强?
自然流量来的用户付费率是多少?付费渠道投放来的用户付费率是多少?
这两个数据放在一起,你能判断:要不要加大投放,或者优化自然流量。
没有收入统计,你的决策就是在盲打。
5. 成本矩阵
这是核心中的核心。
你知道生成一张4K图片,成本是多少吗?
单张成本 = API调用费用 + 服务器费用 + 图片存储费用 + 带宽费用
你知道你的定价能不能覆盖这个成本吗?
Pro月付¥68,但每个订阅用户月均消耗的API成本可能是¥45,加上服务器和存储,平摊下来¥52。你一单赚¥16。
你知道哪个套餐在亏钱,哪个在赚钱吗?
4K-20张¥128,听起来很贵,但4K的API成本是普通图的3倍,20张4K的成本是¥105,你这单只赚¥23。
如果你的4K用户大多是日均1张图,那每张4K的实际成本可能达到¥8,你这单亏¥35。
没有成本矩阵,这些都是糊涂账。
有了成本矩阵,你才知道:要不要调价,要不要砍掉某个套餐,要不要推一个新套餐。
很多工具做了一年,还在卖38块钱10张图,不知道自己一单亏5毛。
管理后台的技术实现也有讲究。
前后台权限要分开。管理员能看所有用户数据,但普通用户只能看自己的。
API要加权限校验。后台管理接口不能裸着随便调,要检查admin role。
数据导出功能要有。运营者需要把数据导出来做Excel分析,不能一辈子困在浏览器里看图表。
四、这套体系背后的开发节奏
Day 4,我做了这些:
7个commit,29个文件改动。
修复积分精度问题(Math.ceil→Math.round):充值50显示49.9的问题从此消失。
安全加固:CSP生产环境移除unsafe-eval。用户浏览器里跑的代码更安全。
登录限流fail-close:防止暴力破解。用户输错5次密码,等15分钟再试,而不是无限制重试。
nodemailer升级到6.10.0(0漏洞):邮件验证码系统更可靠。
会员支付后模型立即解锁:isActiveMember检查past_due和current_period_end,支付成功立即生效,不用等Stripe回调。
那天Day 4结束时,Picboil的核心功能基本没有明显的生产bug了。
"基本"这个词,我说得心虚。
Day 5早上9点,打开GitHub,三个issue。
ISSUE-001:文生图页面刷新后模型选择器会闪一下。
用户反映:选好了Pro模型,页面一刷新,模型变成免费的了。
排查后发现问题:服务端渲染时,系统不知道用户之前选了啥,返回默认模型。浏览器加载完,localStorage里存着Pro模型,页面又跳回去。两套模型同时渲染,React说"不对劲",直接报错。
这个bug的根因是SSR和CSR的模型状态不一致。服务端认为用户没选过模型,返回默认项;客户端从localStorage里读到了用户之前的选择,试图更新UI。两边打架,React报错。
修法:初始状态统一用默认模型,浏览器加载完再从localStorage同步用户偏好。
就像ATM取钱,先显示"系统繁忙",再弹出余额——而不是余额和"系统繁忙"同时显示。
ISSUE-002:所有页面控制台都在报错。
地球icon的SVG路径是坏的。坐标缺少分隔符,互相矛盾。浏览器控制台一排红字。
我用的是自己写的SVG图标,没仔细校验path数据。上线三个月,没人告诉我。
直到有一天,一个对前端略懂的用户截图发给我:"你们网站控制台全是红字,是不是有bug?"
我才知道。
修法简单到可笑:换成lucide-react的标准地球图标。六行代码,一排报错消失。
有时候解决问题和制造问题的代码量,是一样的。
ISSUE-003:定价页面是中文的。
对,定价页面是中文。选了韩文界面,套餐价格还是中文。
Stripe的产品名称是硬编码的中文,上线三个月,韩文用户看到的一直是¥38。
修复:四套语言文件同步新增12个定价相关key,Stripe产品名和描述改成locale-neutral格式。
然后是管理后台。
这是Day 5最重的活。
套餐管理、充值记录、订阅管理、收入统计、成本矩阵——六个新页面前后端全套。
新增的AdminShell布局组件,统一的表格封装组件,分页组件,权限校验……
一天时间,从设计到上线。
还要兼顾全局SVG图标迁移到lucide-react,70+处替换,净减200+行代码。
Day 5晚上,做了一次全面审计。
嵌套事务积分泄漏:之前有个fulfillTopUp函数,嵌套调用了addTopUpCredits,事务嵌套事务,积分可能多扣。
SSE竞态条件:用户生成图片时,如果网络波动导致SSE连接断开,error handler没正确处理,连接可能挂起不退出。
死代码清理:有好几个地方写了永远不会执行的代码,比如某个被注释掉的状态更新,一行一行慢慢删。
这些都是"不影响功能"的bug,但积累到一定程度,系统就会变得不可预测。
全面审计之后,Picboil的稳定性上了一个台阶。
两天,13个commit,60+文件。
从"功能能跑"到"接近生产级"。
五、可复用的开发清单
如果你也在做AI产品,这两天的经历里有几个可以预埋的清单:
定价系统:
积分计算用Math.round,不是Math.ceil。Math.ceil会多收用户积分,Math.round才是正确逻辑。所有涉及金钱计算的地方都要检查精度。
Stripe产品描述走i18n,不走硬编码。定价数据结构要支持locale-neutral,四套语言对应四套Stripe price ID。Price amount用整数存储,前端按locale格式化。
套餐设计考虑成本矩阵。算清楚单张成本再定价,不要卖一单亏一单。成本矩阵要能实时看到每个套餐的利润空间。
订阅 vs 按次:给高频用户提供订阅(稳定收入预期),给低频用户提供按次(低门槛入门)。
付费后立即解锁:isActiveMember判断要同时检查past_due和current_period_end,不能只等Stripe回调。
积分消耗模型要可预测。不同分辨率对应不同积分,用户选了就知道扣多少,不能随机浮动。
CSP安全:生产环境关闭unsafe-eval,Stripe webhook验签,登录限流fail-close。
国际化:
hreflang标签 + x-default,每个语言版本独立配置。sitemap.xml四语言全覆盖。这是SEO的基本功,不做流量全漏。
定价数据走locale-neutral格式,不走硬编码。韩元/日元/人民币要正确显示,不能全是人民币符号。前端按locale动态渲染,后端只存原始数字。
四套语言文件同步维护,CI卡住不让漏。禁止链式三元判断locale,所有文本走t('key')。ESLint规则强制执行。
小数精度问题:在任何涉及计算的i18n场景都要注意Math.ceil和Math.round的区别。前端本地化只做最后一步显示,不做中间计算。
出海选市场:英文红海竞争,中文天然优势,韩文日文竞争少付费意愿强。不是翻译完就出海,是理解市场后再进去。
管理后台:
充值记录必须能5秒钟查到任何用户的任何一笔交易。用户说"钱没到账",你要有地方查。每一笔充值的时间、金额、渠道、状态都要有记录。
成本矩阵必须能实时看到每个套餐的利润空间。单张成本、日均用量、月利润预估都要有。这是定价决策的依据。
订阅管理必须能看到续费率、到期时间、收入预期。续费率突然下降要能马上发现。即将到期的订阅列表要能提前做续费提醒。
套餐管理必须能随时调整价格和积分配置,不用发版。定价是持续优化的,不是一次定完的。
后台API要加权限校验。管理员和普通用户的数据隔离,不能裸着随便调。API要支持数据导出,方便做Excel分析。
审计清单(每次发版前过一遍):
安全:事务不错乱(嵌套事务用tx?参数模式)、限流fail-close、输入有校验、Stripe webhook验签、CSP生产环境关闭unsafe-eval、nodemailer升级到最新版。
健壮性:边界条件不挂(base64上传上限20MB,4K图片能通过)、错误处理有日志(createLogger不是console.log)、SSE error后要break、不会死循环或挂起、membership缓存真LRU。
可维护:代码统一(图标库统一用lucide-react)、i18n无硬编码、命名规范一致、死代码清理、命名typo修正。
可观测:关键路径有createLogger日志、异常能被记录、日志级别正确(error/warn/info)、Stripe静默return全部加log.warn。
结尾
两天,13个commit,60+文件。
做完这些,Picboil才真正接近一个"能持续运营的产品"。
不是功能完备,是问题出现的时候,有人知道,有人修,有人确保不会再出现。
生产级不是没有bug,是bug的闭环速度够快。
袁锐钦 · AI编程实践者
Picboil正在内测。如果你对AI图片生成有需求,或者对国际化/出海定价有具体问题,评论区见。
转发给你身边做AI产品的朋友——他也可能在定价/国际化/管理后台这几个坑里踩过。
如果对你有帮助,点个赞。我会持续分享AI产品开发过程中的真实踩坑记录。
夜雨聆风