积分系统
了解如何在EasyApp中集成积分系统
概述
EasyApp积分系统是一个完整的用户积分管理解决方案,提供积分获取、消费、交易记录以及防滥用保护功能。系统支持多种积分来源,包括注册奖励、订阅、内购、推广活动等,并具备完善的反欺诈机制。
核心功能
1. 积分管理
- FIFO消费机制: 积分按照先进先出的原则消费,确保用户较早获得的积分优先使用
- 有效期支持: 支持永久积分和临时积分,可设置积分过期时间
- 多来源追踪: 详细记录积分来源(注册、订阅、购买、推广、退款、管理员发放等)
- 实时余额查询: 快速获取用户积分余额,包含永久积分、临时积分和即将过期积分
2. 交易系统
- 完整交易记录: 记录所有积分操作的详细历史,包括获得、消费、过期、退款
- 余额追踪: 每次交易后记录用户余额变化
- 批次管理: 支持积分批次操作,便于管理和追踪
3. 功能计费
- 灵活计费: 为不同功能设置不同的积分消费标准
- 动态配置: 支持运行时调整功能的积分消费成本
- 功能开关: 可动态启用或禁用特定功能的计费
4. 反滥用系统
- 邮箱限制: 限制单个邮箱的注册次数和奖励发放
- 设备指纹: 监控设备指纹,防止多账户滥用
- 风险评分: 基于用户行为计算风险分数,自动识别可疑活动
- 冷却期机制: 设置注册奖励的冷却期,防止频繁创建账户
5. 内购集成
- RevenueCat集成: 完整支持RevenueCat内购平台
- 一次性购买: 支持积分包购买,用户可直接购买积分
- 订阅服务: 支持月度/年度订阅,自动发放订阅积分
数据库配置
积分包配置 (credit_packages)
目前只支持在 sql 中配置积分包,后续会做一套管理系统,支持在管理系统中配置积分包。无需修改 sql 代码,降低使用门槛。
积分包表用于配置可供用户购买的一次性积分包:
CREATE TABLE credit_packages (
id UUID PRIMARY KEY,
name TEXT NOT NULL, -- 积分包名称
credits INTEGER NOT NULL, -- 积分数量
price DECIMAL(10,2) NOT NULL, -- 价格
product_id TEXT UNIQUE NOT NULL, -- RevenueCat产品ID
is_permanent BOOLEAN DEFAULT true, -- 是否为永久积分
is_active BOOLEAN DEFAULT true, -- 是否启用
sort_order INTEGER DEFAULT 0 -- 排序顺序
);RevenueCat内购产品配置示例:
INSERT INTO credit_packages (name, credits, price, product_id) VALUES
('入门包', 1000, 9.99, 'easyapp_credits_1000'),
('热门包', 5000, 39.99, 'easyapp_credits_5000'),
('专业包', 10000, 69.99, 'easyapp_credits_10000'),
('超值包', 50000, 299.99, 'easyapp_credits_50000');配置要点:
product_id必须与RevenueCat控制台中的产品ID完全一致- 积分包通常设置为永久积分 (
is_permanent = true) - 通过
sort_order控制在应用中的显示顺序 - 可通过
is_active临时禁用某个积分包
订阅产品配置 (subscription_products)
订阅产品表用于配置月度/年度订阅服务:
CREATE TABLE subscription_products (
id UUID PRIMARY KEY,
product_id TEXT UNIQUE NOT NULL, -- RevenueCat订阅产品ID
product_name TEXT NOT NULL, -- 产品名称
subscription_type TEXT NOT NULL, -- 订阅类型: 'monthly' 或 'yearly'
credits_per_month INTEGER NOT NULL, -- 每月发放的积分数
price DECIMAL(10,2), -- 价格
currency TEXT DEFAULT 'USD', -- 货币单位
is_active BOOLEAN DEFAULT true -- 是否启用
);RevenueCat订阅产品配置示例:
INSERT INTO subscription_products (
product_id, product_name, subscription_type, credits_per_month, price
) VALUES
('subscription_credit_monthly_basic_1', '高级月费会员', 'monthly', 2000, 9.99),
('subscription_credit_yearly_basic_1', '高级年费会员', 'yearly', 2000, 83.99);配置要点:
product_id必须与RevenueCat控制台中的订阅产品ID完全一致- 月度和年度订阅通常设置相同的
credits_per_month(年度用户每月获得相同积分) - 年度订阅价格通常比月度价格×12要便宜(如示例中的30%折扣)
- 系统会根据订阅类型自动处理积分发放周期
功能计费配置 (feature_credit_costs)
功能计费表定义各项功能的积分消费标准:
INSERT INTO feature_credit_costs (feature_name, credit_cost, description) VALUES
('text2image', 100, '文本生成图片'),
('image2image', 150, '图片到图片转换'),
('receipt_analysis', 50, '收据分析'),
('receipt_analysis_pro', 100, '高级收据分析');RevenueCat集成配置
1. 产品ID映射关系
积分包
- RevenueCat产品ID →
credit_packages.product_id - 用于一次性购买积分包
- 购买成功后立即发放对应积分
接下来,介绍下如何创建一次性积分包产品。
这里您必须有 Apple 开发者账号,并且已经创建了 App,才能创建一次性积分包产品。 如果您忘记了如何创建内购产品,可以回看
1: 首先进入App Store Connect,选择应用内购买。 因为我们创建的是一次性积分包产品,所以要选择应用内购买,不要选择订阅。

点击+,创建一次性积分包产品。
Type选择Consumable,代表非消耗型商品。(积分属于消耗型商品)
Reference Name 和 Product ID: Product ID 按照您在credit_packages表中,您定义的product_id字段,一定要一致,因为在购买时,会根据product_id来确定购买的是哪个积分包。
至于Reference Name,您可以跟product_id一致,也可以不一致,这个是您自己定义的。
Product ID 按照您在credit_packages表中,您定义的product_id字段,一定要一致,因为在购买时,会根据product_id来确定购买的是哪个积分包。
设置价格时,也要保持跟credit_packages表中,您定义的price字段,一致。
了解如何集成 RevenueCat 这一章,详细的介绍了如何创建内购产品,包括:国际化、销售范围、以及审核必备的Screenshot。如果您忘记了,可以回看。这里就不再赘述如何创建内购产品了。
RevenueCat
了解如何集成 RevenueCat 服务
拿EasyApp举例,填写的例子如下:按照credit_packages表,创建了4个积分包

2: 接下来,需要配置RevenueCat

-
选择
Product catalog -
选择
Product -
选择
New Product -
点击
New Product

它会自动拉取刚才您创建的内购产品。选择您期望的积分包。
导入内购产品完成之后,我们需要来配置Offerings,Easyapp 会根据Offerings来拉取积分包。

点击New Offering

- 填写您的
IdentifierDisplay NamePackages。 其中Packages的Identifier,您可以选择Custom,Product就选择您刚才导入的内购产品即可。

拿EasyApp举例,填写如下:

再次强调:
Product ID 按照您在credit_packages表中,您定义的product_id字段,一定要一致,因为在购买时,会根据product_id来确定购买的是哪个积分包。
设置价格时,也要保持跟credit_packages表中,您定义的price字段,一致。
3: 来到EasyAppSwiftUI项目中,在Constants/Constants.swift文件中,配置RevenueCat的creditPackagesEntitlementID的值。
enum RevenueCat {
// ...
/// Credit Packages entitlement ID
static let creditPackagesEntitlementID = "easyapp_credits"
// ...
}到这里,积分包配置就完全完成了。
订阅
- RevenueCat产品ID →
subscription_products.product_id - 用于月度/年度订阅服务
- 根据订阅周期自动发放积分
订阅产品的步骤跟积分包的步骤是一样的,只不过是配置的是订阅产品。

剩余的步骤就参考下面这篇文章即可
填写订阅产品的价格、id、name、订阅时长。这一块在RevenueCat 订阅产品创建有详细介绍,请查看。
拿EasyApp举例,我们创建的订阅产品信息如下:

1: 在 App Store Connect 中,创建订阅完成之后,回到RevenueCat 中,配置Offerings。
2: 在上述创建积分包的步骤中,我们已经详细介绍了如何配置Offerings。这里就不再赘述了。
3: 对于订阅产品,我们除了要创建Offerings,还要创建Entitlements。

- 填写
Identifier - 填写
Description - 关联您在 App Store Connect 中创建的订阅产品
拿EasyApp举例,创建的Entitlements填写如下:

4: 来到EasyAppSwiftUI项目中,在Constants/Constants.swift文件中,配置RevenueCat的creditSubscriptionEntitlementID的值。
enum RevenueCat {
// ...
/// Credit Packages entitlement ID
static let creditSubscriptionEntitlementID = "subscription_credit"
// ...
}创建订阅产品时: Product ID 按照您在subscription_products表中,您定义的product_id字段,一定要一致,因为在购买时,会根据product_id来确定购买的是哪个订阅产品。
设置价格时,也要保持跟subscription_products表中,您定义的price字段,一致。
2. Webhook配置
系统通过RevenueCat Webhook自动处理购买和订阅事件:
支持的事件类型:
INITIAL_PURCHASE: 首次购买/订阅RENEWAL: 订阅续费CANCELLATION: 取消订阅EXPIRATION: 订阅过期PRODUCT_CHANGE: 订阅升级/降级BILLING_ISSUE: 支付问题
Webhook URL配置:
https://your-project.supabase.co/functions/v1/subscription-webhook对于开发环境如何设置Webhook URL配置,我们推荐使用ngrok来设置。
关于ngrok的安装和使用,请参考ngrok。
执行命令:
ngrok http 54321然后配置RevenueCat的Webhook URL为https://your-ngrok-url/functions/v1/subscription-webhook。
如下图所示:

当我们准备上线时,不要忘记配置生产环境的Webhook URL。 RevenueCat 支持配置多个Webhook URL。您可以新增一个Webhook URL,然后专门配置生产环境的Webhook URL。
续订触发时间:
对于测试环境,沙盒订阅触发的时间,您可以在 App Store Connect 中,配置沙盒订阅触发的时间。也就是说,如果您设置的是 5 分钟间隔,那么 Webhook URL 会每 5 分钟触发一次。

3. 用户ID映射
我们已经在EasyApp 登录时,已经将RevenueCat的 app_user_id 设置为Supabase用户的UUID,确保系统能够正确识别用户身份。
// logInRevenueCat
try await logInRevenueCat(userId: response.user.id.lowercasedString)系统配置
动态配置系统
系统支持运行时动态调整配置,无需重启服务:
积分系统配置 (system_config.credit_system):
{
"enabled": true,
"registration_bonus": 3000,
"enable_anti_abuse": true,
"refund_on_failure": true
}功能开关配置 (system_config.features):
{
"image_generation": true,
"receipt_analysis": true
}反滥用配置 (system_config.anti_abuse):
{
"max_registrations_per_email": 1,
"max_bonus_per_email": 3000,
"max_accounts_per_device": 10,
"registration_cooldown_days": 30,
"risk_score_threshold": 70,
"refund_time_limit_hours": 24
}安全特性
- 行级安全 (RLS): 所有数据表启用RLS,确保用户只能访问自己的数据
- 权限控制: Edge Functions使用Service Role进行管理操作
- 参数验证: 所有接口进行严格的参数验证
- 防重复处理: 通过事件ID确保Webhook事件不被重复处理
- 审计日志: 完整记录所有积分操作的审计trail
最佳实践
- 定期清理: 建议定期清理过期的积分记录和交易日志
- 监控报警: 设置积分异常消费和批量操作的监控报警
- 性能优化: 使用预计算视图提高积分余额查询性能
- 备份策略: 定期备份积分相关数据,确保数据安全
- 测试验证: 在生产环境部署前,务必在沙箱环境充分测试
通过以上配置和集成,你将拥有一个功能完整、安全可靠的积分管理系统,支持多种业务场景和变现模式。
Last updated on