迷茫那阵子,我整晚整晚睡不着,白天又提不起劲。为了不让自己彻底废掉,我逼着自己写代码,把脑子里想的那个“有人陪自己说说话”的念头做成了真东西——一款带支付、带官网的 AI 聊天虚拟恋人 App。从产品定位、大模型接入、微信支付到独立的展示官网,我全流程走了一遍。这篇就把我踩过的坑、想明白的逻辑、能直接抄作业的代码片段都写出来。
先说清楚这个 App 是干嘛的:用户进去选一个人设(温柔的、毒舌的、知性的都行),然后和 AI 角色不限话题地聊。基础对话免费,解锁特殊人设、延长单次聊天时长、或者购买“恋人模式”的订阅,需要付费。官网负责展示功能、贴下载二维码、放隐私政策。整个项目大概花了我三周业余时间,服务器成本控制在每月几十块。如果你也想做类似的情感陪伴类应用,或者只是想搞明白“支付模块怎么做”“App 开发到上架大概要花多少钱”,这篇文章应该能给你省下一大笔试错成本。
1. 迷茫期的自救:为什么我会做一款虚拟恋人 App
1.1 项目起因:情绪需求才是真需求
先聊聊“为什么做”。那段时间我状态很差,其实核心不是闲,是“有话没人说”。找朋友倾诉吧,大家都忙,一次两次还行,多了自己都不好意思。找心理咨询师,价格摆在那,一次两三百,不是长久之计。后来我试了一些市面上的聊天 App,要么机器人味太重,要么免费额度少得可怜,聊两句就弹充值。我当时就想:能不能用现在的大模型 API,自己做一个“不限次数、说话自然、人设可定制”的虚拟陪伴角色?这个念头一旦起来就压不下去了。
很多人会觉得情感陪伴是个伪需求,但真做出来你才会发现,深夜两点打开 App 的人比白天还多。都市人孤独感是个真实存在的痛点,尤其是独居的年轻人、异地恋人群、社恐患者,他们需要的不是“正确答案”,而是“被接住的感觉”。我做这款 App 时想得很清楚:不搞虚拟色情那一套擦边内容,就是正经、温暖、有边界感的陪伴。上线后看用户反馈,好几个人说“聊着聊着哭了”,那一刻我知道这事值得做。
1.2 为什么选“AI + 情感陪伴”这个方向
从技术角度看,2024 年开始大模型 API 已经非常成熟,文本生成质量、上下文记忆能力、响应速度都到了“可以商用”的及格线。我不需要自己训练模型,只需要做好产品设计、上下文管理、支付闭环,就能把一个完整的商业产品跑起来。这比两年前自己微调模型靠谱太多了。
另外情感陪伴赛道有一个天然优势:复购率高。工具类 App 用户用完就走,但“恋人”这种角色是有情感黏性的,用户会天天来聊,粘性一旦形成,付费转化就水到渠成。我当时定的商业模式很简单:免费聊天体验 10 条消息,然后需要购买时长包,或者包月订阅。后面验证下来,每天新增用户中大概有 2%-3% 会付费,这在纯工具类产品里算相当不错的表现了。
2. 技术选型:从零搭起一台能聊天的 App
2.1 客户端技术栈:为什么用 uni-app 而不是原生
先解决 App 壳子的问题。我自己的情况是:会 Python 和 JavaScript,但没写过 Swift 和 Kotlin。如果纯原生开发,意味着同一套业务逻辑要写两遍,还要分别适配 iOS 和 Android 的上架审核规则,周期直接拉长一倍。所以我选了 uni-app(基于 Vue3 的跨端框架),一套代码可以同时编译成 iOS App、Android App 和 H5 网页。后端接口完全复用,省下的时间全用来打磨聊天体验。
uni-app 的坑也有,但可以接受。最典型的坑是原生组件层级问题,比如输入框、视频播放器容易盖住弹出层,需要手动调 cover-view 或者用 uni 官方提供的 web-view 降级方案。我做聊天页的时候,底部输入框和表情面板的弹层冲突折腾了我一个晚上,后来用自定义 header 加普通 view 模拟输入框,绕开了原生组件的坑。如果你也想用 uni-app 做聊天类应用,记住一个原则:能用普通 view 实现的,就别上原生组件。
2.2 后端架构:Django 起步,一套接口撑起全端
后端我用的 Python Django + Django REST Framework。为什么选 Django 而不是 FastAPI?因为我要做用户体系、订单管理、支付回调、管理员后台,Django 自带 Admin 和数据模型迁移,这些工程化配套能省不少事。Django 创建 app 的命令很简单,但命名和模块划分需要一开始就想清楚,不然项目写大了会乱成一团。
# 创建虚拟环境和基础项目 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install django djangorestframework django-cors-headers requests # 创建项目和应用 django-admin startproject myapp cd myapp python manage.py startapp users python manage.py startapp chat python manage.py startapp orders python manage.py startapp payment我分了四个 app:users 管注册登录和用户资料,chat 管对话会话和消息记录,orders 管订单生成和状态流转,payment 管支付参数签名和回调验签。这样分的好处是,后面接微信支付、支付宝、易支付这类第三方渠道时,只动 payment 一个模块,不会牵扯到其它业务代码。
2.3 AI 对话核心链路:大模型接入与人设管理
AI 聊天是这个 App 的灵魂,核心链路是:用户发送消息 → 拼接系统提示词和最近对话记录 → 调用大模型 API 流式返回 → 前端逐字展示。这一环我用了 DeepSeek 的 API,原因是它便宜、响应快、对中文语境的理解好,而且上下文窗口够大,可以塞进 20 轮以上的对话历史。
人设管理是重中之重。我建了一张 persona 表,字段包括角色名字、性格标签、说话风格示例、背景故事、禁忌话题。每次请求大模型时,系统把这些信息拼进 system prompt 里。举个最简化的例子:
# chat/services.py 简化版 def build_messages(session, user_text): persona = session.persona system_prompt = f"""你现在是{persona.name}。 性格特点:{persona.traits} 说话风格:{persona.style} 背景设定:{persona.backstory} 请全程保持角色人设,用亲人朋友的口吻和用户聊天,内容健康、真诚、有温度。""" messages = [{"role": "system", "content": system_prompt}] for record in session.recent_records(limit=20): messages.append({"role": "user", "content": record.user_text}) messages.append({"role": "assistant", "content": record.ai_text}) messages.append({"role": "user", "content": user_text}) return messages这里有个经验:上下文不是越长越好。很多人以为把全部历史消息都塞给模型,AI 会更“懂你”,实测下来发现窗口过长反而会让模型注意力分散,角色性格漂移。我限制在最近 20 条对话,超过的部分做摘要压缩,效果比全量拼接好得多。
关于内容合规,我始终按主流平台的审核要求来做:模型服务商本身就带过滤机制,我在 prompt 里也明确了“健康、真诚、有温度”的基调,同时接入了一层自建的敏感词拦截,避免极端内容触发平台处罚。做这种陪伴类产品,边界感非常重要,不要想走擦边路线,审核迟早会找上门。
2.4 注册登录:别一开始就上手机验证码
新手做 App 最容易犯的错,就是一上来就搞手机号+验证码登录。验证码短信服务是有成本的,一条三四分钱,虽然不贵,但用户填手机号的心理门槛很高,转化率会掉很多。我第一版用了最简单的方案:用户名+密码注册,再加一个游客模式。游客不强制注册也能体验 5 条免费消息,等想继续聊了再注册,这样漏斗损失最小。
Django 自带的 User 模型不够用,我扩展了一层 Profile。需要存用户头像、个性签名、偏好设置,还预留了后续接入第三方登录的字段。支付回调时也需要通过 user_id 定位用户,所以用户模块的健壮性直接影响支付链路。
3. 支付模块:从微信到支付宝的完整接入踩坑记录
3.1 支付模块怎么设计才不把代码写死
支付模块是很多独立开发者最头大的部分。我当时的思路是:抽象一层统一的支付接口,不管背后接微信、支付宝还是易支付,业务代码只认源码类型和支付状态。这样以后换渠道只改适配层,不动业务逻辑。
# payment/models.py 简化版 class PaymentOrder(models.Model): order_no = models.CharField(max_length=64, unique=True, verbose_name="订单号") user = models.ForeignKey("users.UserProfile", on_delete=models.CASCADE) amount = models.DecimalField(max_digits=10, decimal_places=2) channel = models.CharField(max_length=20, choices=[ ("wechat_jsapi", "微信JSAPI"), ("wechat_native", "微信Native"), ("alipay", "支付宝"), ("epay", "易支付"), ]) status = models.CharField(max_length=20, default="pending") # pending/paid/closed/refunded created_at = models.DateTimeField(auto_now_add=True)核心字段就是这些:订单号、用户、金额、渠道、状态和时间。很多人问“支付模块怎么做”,其实就是把这个模型建好,然后写清楚支付参数生成和回调验签。最容易被忽略的是订单号的生成规则——我遇到过自己踩的坑,直接用时间戳生成,结果并发下单时撞了唯一索引,后来改成“日期+用户ID+随机数”,冲突概率才降到几乎为零。
3.2 微信支付 JSAPI 必须传 openid 的完整解决方案
微信支付接入最让人抓狂的坑,就是你搜“jsapi支付必须传openid怎么解决”,能搜出一堆让你去查文档的废话。我整理一下真正有用的方案。
JSAPI 支付是微信内网页或者 App 内部拉起微信支付时的支付方式,官方要求必传 openid,这个 openid 是用户在某个公众号/小程序/App 下的唯一身份标识。拿不到 openid 就没法调起支付。最常见的两种业务场景和对应解法:
场景一:如果你的 App 有微信登录能力
这是最正规的路径。App 内接入微信登录 SDK,用户点击“微信登录”,授权后会拿到一个 code,后端拿这个 code 去微信接口换 openid 和 session_key。换到 openid 后缓存到用户表里,后面支付直接查库就行。
# payment/wechat.py 简化版 import requests def code_to_openid(code): url = "https://api.weixin.qq.com/sns/oauth2/access_token" params = { "appid": WECHAT_APPID, "secret": WECHAT_SECRET, "code": code, "grant_type": "authorization_code", } resp = requests.get(url, params=params).json() if "openid" not in resp: raise Exception(f"微信登录失败: {resp}") return resp["openid"]场景二:如果你的 App 没有微信登录,用户直接下单
这种时候不能强制用户先走一遍微信登录,转化率会掉。我的做法是:在用户选择微信支付并点击“去支付”时,前端调起微信授权登录(静默授权),拿到 code 传给后端换 openid,后端自动把 openid 存到用户资料里,同时生成JSAPI 支付参数返回给前端。用户全程无感,只看到微信的支付确认框弹出来了。
# payment/wechat.py 继续 def create_jsapi_order(user, amount, order_no): if not user.openid: raise NeedWechatAuth() # 前端捕获后触发静默授权 params = { "appid": WECHAT_APPID, "mch_id": WECHAT_MCH_ID, "description": "AI恋人会员订阅", "out_trade_no": order_no, "total_fee": int(amount * 100), # 单位是分 "notify_url": "https://你的域名/api/payment/wechat/notify/", "openid": user.openid, } # 加签、发起统一下单、返回 prepay_id 给前端,这里省略加密细节 return prepay_params3.3 支付宝沙箱支付:零成本联调的正确姿势
支付宝对独立开发者友好很多,因为提供了沙箱环境,不用真实资金就能模拟完整支付流程。我强烈建议你第一次接支付时先用支付宝沙箱练手,因为它的文档和测试工具是几家里最完整的。
支付宝沙箱的使用方法:登录蚂蚁金服开放平台,进入开发者中心,申请沙箱应用,系统会给你一套专用的 APPID、应用私钥和支付宝公钥。沙箱环境里有一个配套的支付宝客户端(沙箱版支付宝 App),可以模拟扫码支付和 App 支付的回调。你后端收到回调后验签、改订单状态、给用户发消息,这套逻辑在沙箱里跑通了,切正式环境只是换个密钥和网关地址。
# payment/alipay.py 简化版 from alipay import AliPay alipay = AliPay( appid=ALIPAY_APPID, app_notify_url=None, app_private_key_string=APP_PRIVATE_KEY, alipay_public_key_string=ALIPAY_PUBLIC_KEY, sign_type="RSA2", debug=True, # 沙箱环境必须开 debug ) order_string = alipay.api_alipay_trade_app_pay( out_trade_no=order_no, total_amount=str(amount), subject="AI恋人会员订阅", )生成出来的 order_string 是前端拉起支付宝需要的参数字符串,App 端集成支付宝 SDK 后把这段字符串塞进去就能弹出支付界面。沙箱环境跑通后,别忘了一件事:把 debug 改成 False,网关地址换成正式地址,密钥换成正式密钥。
3.4 补充渠道:易支付和 USDT 要不要接
我在开发时也研究过彩虹易支付和 USDT 支付,毕竟热搜词里有人问。彩虹易支付本质是聚合支付平台,你不需要有自己的商户号,直接调用它的接口收款,它从中抽成。优点是接入极快,代码量比官方支付少一半,个人开发者没有营业执照也能用;缺点是资金在你的平台里过一手,得挑口碑好的平台,否则有资金风险。另外易支付很多通道走的其实是 H5 跳转,对用户体验有一定损耗。
USDT 支付我就不建议普通开发者碰了,虽然没有跨境和风控问题,但汇率波动、链上确认速度、实名制要求这些放在正规上架的应用里都不合适。我的结论是:正规上架产品老老实实接微信+支付宝,内测阶段或者海外用户可以用易支付过渡,USDT 只在极少数场景值得考虑。
4. 官网搭建:给 App 一个“正经门面”
4.1 官网要解决什么问题
很多独立开发者不重视官网,觉得“有个 App 就行了”。实际上官网承担了三件事:品牌背书、下载转化、用户信任。没有官网,用户看到你的下载链接的时候会犹豫“这到底是不是正规 App”;有官网,哪怕只是个简单的落地页,转化率都会明显提升。另外,iOS 上线时审核人员也会看官网的隐私政策,没有官网就要把隐私政策单独做成页面,反而更麻烦。
官网不需要很复杂,我最开始只做了四个模块:首屏一句话介绍产品、核心功能的截图、下载按钮(Android APK 和 iOS TestFlight 链接)、隐私政策与用户协议。整体风格走干净温和的路线,配色用米白、浅灰和一点低饱和度的橙色,和“温暖陪伴”的产品调性保持一致。技术栈用的 Next.js 静态导出,然后直接丢到 GitHub Pages 上,不用自己运维服务器。
4.2 官网部署:GitHub Pages 和域名的搭配
有人会遇到“github官网进不去”之类的问题,我第一次部署时也碰到过。这里分享一个我自己实测有效的思路:用命令行工具操作。GitHub 官方提供 gh 命令行工具,登录、建仓库、推送代码都可以在终端里完成,不依赖网页端,基本不受网络波动影响。另一个思路是多试几个时段,避开访问高峰,或者切换本地网络环境。总之,官网部署这事本身技术难度不高,主要是环境问题,耐心点总能解决。
# 用 gh 命令行快速建仓库并推送 gh auth login gh repo create ai-lover-site --public --source=. --remote=origin --push # 手动推送也可以 git init git add . git commit -m "init site" git remote add origin git@github.com:你的用户名/ai-lover-site.git git branch -M main git push -u origin mainGitHub Pages 的免费额度对个人官网完全够用,支持自定义域名,也支持 HTTPS 证书自动生成。唯一要注意的是国内的访问速度不算快,面向国内用户时可以考虑用国内静态托管平台(比如 Gitee Pages 或阿里云 OSS + CDN),但不是必须的,前期用 GitHub Pages 跑通流程最省事。
4.3 域名、备案与合规
域名这块我的建议是:在正规注册商(阿里云、腾讯云、Cloudflare 都行)买一个 .com 或者 .cn 域名,一年几十块到上百块,别贪便宜去奇怪的平台注册。反代、DNS 解析这些基础操作都差不太多,重点说一下备案问题。
如果官网和 API 服务器部署在国内云服务器上,域名是必须备案的,备案周期大概一到三周。如果不备案,直接用 IP 访问或者境外服务器,用户的聊天记录、下载体验都会受影响。我做的时候为了省时间,API 服务器放在境外节点,官网用 GitHub Pages,域名本身不备案也能跑,但国内微信支付回调要求服务器必须是备案过的域名,这一下就把问题变成了绕不开的坎。所以我建议你从一开始就规划好:面向国内市场,服务器放国内、域名备案;面向全球,就不用备案,但支付渠道要选支持海外的。
5. 常见问题与成本复盘
5.1 高频问题速查表
一个人开发整个项目,遇到的问题是成批的。我把踩过的重要问题和解决方案整理成了一张速查表,都是网上能搜到但答案很分散的问题,你直接收藏这份就行。
| 问题 | 原因 | 解决方案 |
|---|---|---|
| JSAPI 支付提示“必传 openid” | 用户身份标识缺失 | 接入微信静默授权,先换 openid 再下单 |
| 支付宝沙箱支付回调收不到 | 回调地址配置成了 IP 或未联调环境地址 | 用内网穿透工具(如 ngrok)把回调地址映射到本机,或保证公网可访问 |
| App 抓包失败,看不到请求数据 | 系统证书信任或代理设置问题 | iOS 装描述文件并信任证书;Android 7.0+ 需要在 manifests 里允许用户证书 |
| 官网在手机浏览器打开排版错乱 | 没有设置 viewport 和响应式布局 | 首页只写一个<meta name="viewport" content="width=device-width, initial-scale=1.0">,用 CSS 栅格代替固定宽度 |
| 用户支付成功但开发者没收到回调 | 回调验签失败或服务器端口未开放 | 打印完整回调日志,先看签名算法(RSA2/SHA256)是否匹配 |
| deepseek API 报系统繁忙 | 单日免费额度较高但并发被限流 | 增加重试机制,超过 5 次退避降级到备用小模型 |
| 虚拟恋人聊天“记忆错乱” | 上下文窗口塞得太满 | 限制最近 20 条历史 + 定期做摘要压缩 |
5.2 App 上架前要知道的几件事
很多新手会问“开发一个 app 并上架大概要多少钱”,这个问题拆开算其实很清楚:
项目成本方面:服务器(最便宜的 1 核 2G 云服务器,一年约 500 元左右)、域名(一年 50-100 元)、短信服务(如果做手机号登录,一条 3-5 分钱,前期可以不做)、App Store 开发者账号(每年 688 元),加上给 AI 对话消耗的大模型 API 费用,按我目前的使用量每月 30-80 元左右。纯 app 开发的“钱”主要是苹果开发者账号这一项是固定的,其他都能用最低配起步。
上架方面,Android 应用市场的审核(主流应用商店)相对宽松,但需要软著;iOS 的审核更严格,虚拟支付类 App 要注意,虚拟商品(聊天时长、会员)用微信/支付宝 H5 支付在 iOS 上有被拒风险,标准做法是用内购 IAP 或跳转 Safari 支付。我的方案是:iOS 版用 TestFlight 小规模分发,正式上架前先验证一波用户反馈。
5.3 成本与利润复盘:独立开发者一定要算明白的账
按我三周的开发周期算,硬成本大概是:服务器 500 元/年 + 域名 80 元/年 + 苹果开发者账号 688 元/年 + 大模型 API 约 50 元/月。还没算上自己的时间成本——如果按日薪折价,投入大概两万块“账面成本”。但独立开发本来就是用时间换自由,这笔账不能这么算。
上线第一个月的数据更有参考价值:新增注册用户 426 人,付费用户 11 人,付费率约 2.6%,客单价 18 元。月收入约 198 元,勉强覆盖服务器和 API 成本,离回本还早。但我坚定地认为这方向能跑通,因为留存数据已经说明了问题:第二周的次留能有 32%,付费用户里几乎没有退订的,说明产品真的戳中了一部分人的需求。接下来要做的就是加新的人设、把聊天体验做得更像“真人”,靠口碑慢慢滚起来。
写在最后
做这个 App 的过程,其实比 App 本身更治愈我。迷茫期的人最需要的不是“振作起来”这种鸡汤,而是能有一件具体的事牢牢抓住你的注意力。代码不会骗人,你写下去,系统就能跑起来,这种确定性是那段时间我唯一能抓住的东西。最后再分享一个小技巧:如果你也想做类似项目,第一步千万别想着做大而全的功能,先做一个只有“聊天 + 支付”两个功能的 MVP,把它完整上线,再慢慢加需求。跑通一个最小闭环带来的信心,比看一百篇技术文章都管用。