会话定价
HandyCafe 使用基于分段的定价引擎来计算您网吧或游戏中心的会话费用。引擎将每个会话划分为多个分段,每个分段都有其特定的定价上下文,而不是为整个会话应用单一的固定费率。这种方法确保即使会话跨越多个时间段、定价变更、暂停或断开连接时,也能实现准确的计费。
核心概念
在深入了解细节之前,以下是一些关键术语:
| 术语 | 定义 |
|---|---|
| 基础小时费率 | 应用任何倍数之前的每小时价格。在设置 > 定价中设置。 |
| 定价时段 | 具有特定倍数的命名时间段。共有8个时段,每个时段都有颜色编码。 |
| 倍数 | 应用于基础费率的因子。1.0 = 标准价格,0.5 = 半价,2.0 = 双倍价格。 |
| 分段 | 会话中的连续时间段,其中定价上下文(时段、倍数、基础价格)保持不变。 |
| 结算 | 确定会话结束时客户应支付金额的最终计算。 |
基础小时费率
基础小时费率是所有定价计算的基础。它在 设置 > 定价 中设置,代表每小时使用PC的标准价格。
所有内部计算使用 小货币单位(例如,美元的美分,土耳其里拉的库鲁)。如果您的基础费率是每小时3.00美元,内部值为300。这消除了浮点舍入问题。
双货币支持
HandyCafe 支持基础货币和本地货币及其汇率。如果您在国际定价与本地定价不同的国家运营:
- 基础货币。 用于内部定价计算的货币。
- 本地货币。 显示给客户并用于支付的货币。
- 汇率。 基础货币与本地货币之间的转换因子。
如果两种货币相同,汇率视为1.0,不产生影响。
定价时段
共有 8个颜色编码的定价时段,每个代表不同的定价层级:
| 时段 | 颜色 | 典型用途 |
|---|---|---|
| 蓝色 | 蓝色 | 标准费率 |
| 橙色 | 橙色 | 晚上或周末附加费 |
| 红色 | 红色 | 高峰时段溢价 |
| 绿色 | 绿色 | 非高峰折扣 |
| 青色 | 青色 | 学生或会员费率 |
| 灰色 | 灰色 | 假日或特殊定价 |
| 青绿色 | 青绿色 | 夜间费率 |
| 祖母绿 | 祖母绿 | 促销费率 |
每个时段有三个属性:
- 名称。 描述性标签(例如,“高峰时段”或“夜间折扣”)。
- 倍数。 修改基础费率的小数值。常见值包括1.0(标准),0.5(半价),1.5(50%附加费),2.0(双倍价格)。倍数必须为零或正数。
- 时间表数据。 定义时段适用的具体日期和时间的内部表示。这通过时间表网格自动管理。
时段可以单独启用或禁用。禁用的时段将被定价引擎忽略。
时间表网格
定价时间表是一个 7天乘24小时的矩阵(总共168个一小时块)。每个块分配给一个定价时段。时间表决定了在任何给定时刻适用哪个倍数。
网格在 设置 > 定价时间表 中配置。日期从周一到周日,时间从00:00到23:00。要将时段分配给时间块,请在网格中选择该块并选择所需的时段颜色。
引擎如何读取时间表
内部,每个小时块映射到时间表数据中的一个位置。引擎检查每个启用时段的时间表数据,以确定在任何给定的日期和小时哪个时段处于活动状态。
如果没有时段在给定小时设置其位,引擎将回退到 基础费率,倍数为1.0。
当定价时间表功能完全禁用时(在设置 > 定价中),所有会话无论时间如何都使用基础费率和1.0倍数。
定价分段
分段是会话中定价上下文不变的连续时间段。每当发生以下 边界事件 时,定价引擎会创建一个新分段:
| 边界 | 触发 |
|---|---|
| session_start | 新会话开始 |
| session_stop | 会话停止 |
| pause | 收银员暂停会话 |
| resume | 收银员恢复暂停的会话 |
| tick | 时钟跨过小时边界进入不同的定价时段 |
| disconnect | 客户端PC失去网络连接 |
| offline | 客户端PC离线 |
| load_recovery | 服务器重启并恢复运行中的会话 |
每个分段记录:
| 字段 | 描述 |
|---|---|
| session_id | 此分段所属的会话 |
| segment_start | 分段开始时的Unix时间戳 |
| segment_end | 分段结束时的Unix时间戳(如果仍在进行中则为null) |
| pricing_slot_id | 活动定价时段的ID(例如,“蓝色”,“红色”或“基础”) |
| multiplier | 来自定价时段的倍数值 |
| base_price_snapshot | 分段打开时捕获的基础小时费率 |
| amount | 此分段的计算费用(在分段关闭时设置) |
| boundary_reason | 创建此分段的原因 |
为什么要快照基础价格?
base_price_snapshot 捕获分段打开时的基础小时费率。这很重要,因为管理员可能会在会话中途更改基础费率。通过快照,每个分段使用其开始时生效的费率,确保公平和可审计的计费。
成本公式
单个分段的成本计算为:
amount = ceil( (base_price_snapshot * multiplier * duration_seconds) / 3600 )
更准确地说,引擎使用缩放的整数算术来避免浮点错误:
- 倍数缩放为定点整数(乘以1,000,000)。
- 计算完全在128位整数中进行。
- 使用向上取整除法。结果总是向上舍入到下一个小单位。
按分钟计算
如果在设置 > 定价中启用了“按分钟计算”选项,公式略有变化:
amount = ceil( (base_price_snapshot * multiplier * used_minutes) / 60 )
其中 used_minutes = ceil(duration_seconds / 60)。这意味着任何部分分钟都算作完整的一分钟。
会话总费用计算
会话总费用通过三个步骤计算:
步骤1:汇总所有分段
raw_total = sum of all closed segment amounts + open segment partial amount
开放分段的部分金额使用上述公式实时计算,当前时间戳作为分段结束。
步骤2:应用舍入
rounded_total = round_up(raw_total, rounding_step)
舍入总是向 上(向上取整)以保护收入。舍入步长可在设置 > 定价中配置。例如,如果舍入步长为50(代表具有2个小数位的货币中的$0.50),则原始总额$3.27舍入为$3.50。
步骤3:应用启动费用最低值
final_total = max(rounded_total, startup_fee)
启动费用是任何会话的最低收费,无论持续时间如何。如果舍入总额小于启动费用,则收取启动费用。
结算
结算是最终确定会话计费的过程。结算分为两个阶段:
开始结算(仅限预付费)
当预付费会话开始时,会创建一个“开始”结算记录。这记录:
- 计算费用。 系统计算的购买时间费用。
- 收取金额。 客户实际支付的金额(通常与计算费用相同)。
对于“购买时锁定”预付费模式,此锁定金额决定会话的费用,无论会话期间的定价变化如何。
停止结算
当任何会话(预付费或后付费)停止时,会创建一个“停止”结算记录:
| 字段 | 描述 |
|---|---|
| 计算费用 | 从所有定价分段计算的系统总费用 |
| 收取金额 | 实际收取的金额(默认为计算费用) |
| 手动调整金额 | 如果收银员手动调整价格,原始计算费用保留在此处 |
| 佣金率 | 支付方式佣金率(以百分比表示) |
| commission_fee | 计算的佣金金额 |
| fixed_fee | 支付方式固定费用 |
| computed_timeline_snapshot | 会话中每个定价分段的JSON记录 |
时间线快照提供了完整的审计记录,逐段显示费用的具体计算方式。
支付方式费用
每种支付方式可以有两种类型的费用:
佣金(基点)
佣金率以百分比表示。佣金费用通过将此费率应用于收取金额来计算。
示例: 如果收取金额为$10.00(1000小单位),支付方式的佣金率为2.5%,则佣金费用为$0.25(25小单位)。
固定费用
每笔交易扣除的固定费用,无论金额如何。例如,信用卡处理费用为$0.30。
这两种费用都是信息性的。它们代表接受该支付方式的业务成本。它们记录在结算中,但不添加到客户账单中。
增值税(VAT)
增值税在设置 > 定价中配置为百分比(0--100%)。它在计算的会话金额上额外应用:
VAT = amount charged x (VAT rate / 100)
增值税金额在支付对话框中单独显示,以便收银员可以看到税费明细。
预付费定价模式
如会话管理中所述,预付费会话支持两种定价模式:
购买时锁定
当预付费会话开始时,“开始”结算锁定收取金额。在会话期间:
- 会话结束时间根据购买的分钟数固定。
- 即使定价时间表更改,会话也会继续,直到锁定时间到期。
- 停止结算使用开始结算中的锁定金额。
实时时间表
随着定价时段的变化,会话的剩余时间不断重新计算:
- 如果会话进入更便宜的时段,剩余时间延长(客户的钱可以获得更多分钟)。
- 如果会话进入更昂贵的时段,剩余时间缩短。
- 停止结算反映整个会话期间实际应用的定价。
小数位数
用于货币显示的小数位数是可配置的(2--4个小数位)。这影响了金额在UI中的显示方式,但不会改变内部的小单位计算。
示例: 使用2个小数位,$3.50显示为“3.50”。使用3个小数位,它将显示为“3.500”。
实际示例
示例1:简单的后付费会话
- 基础费率:$3.00/小时(300小单位)
- 时间表:全天标准时段(倍数1.0)
- 会话:10:00 AM到11:30 AM(90分钟)
- 启动费用:$0.50
计算:
分段1: (300 * 1.0 * 5400) / 3600 = 450小单位 ($4.50)
总计: max($4.50, $0.50) = $4.50
示例2:跨越两个时段的会话
- 基础费率:$4.00/小时(400小单位)
- 时间表:10:00--12:00标准(1.0),12:00--14:00欢乐时光(0.5)
- 会话:11:00 AM到1:00 PM(120分钟)
- 启动费用:$1.00
计算:
分段1 (11:00-12:00, 标准): (400 * 1.0 * 3600) / 3600 = 400 ($4.00)
分段2 (12:00-13:00, 欢乐时光): (400 * 0.5 * 3600) / 3600 = 200 ($2.00)
总计: $4.00 + $2.00 = $6.00
最终: max($6.00, $1.00) = $6.00
示例3:带暂停的会话
- 基础费率:$2.00/小时(200小单位)
- 时间表:全天标准时段(倍数1.0)
- 会话:开始10:00,暂停10:30,恢复11:00,停止11:45
- 启动费用:$0.50
计算:
分段1 (10:00-10:30, 活动): (200 * 1.0 * 1800) / 3600 = 100 ($1.00)
暂停期间 (10:30-11:00):无费用
分段2 (11:00-11:45, 活动): (200 * 1.0 * 2700) / 3600 = 150 ($1.50)
总计: $1.00 + $1.50 = $2.50
最终: max($2.50, $0.50) = $2.50