充值和补充系统
OmniCRM 充值系统提供一个 自助服务预付费充值门户,供客户通过 自助服务门户 添加信用或延长服务有效期。此功能通常用于:
- 移动数据服务 - 预付费 SIM 卡和仅数据服务
- 热点服务 - WiFi 热点加密狗和便携式互联网设备
- 固定无线服务 - 预付费互联网接入
概述
充值系统允许客户通过简化的多步骤结账流程购买额外的服务天数,并集成了 Stripe 支付处理。
主要特点:
- 自助服务客户门户(无需员工干预)
- 灵活的时长选择(1-30 天)
- 购买前实时使用情况显示
- 基于 Stripe 的安全支付处理
- 如果充值失败,自动退款
- 发票和交易生成
- 服务激活的配置系统集成
访问充值门户
充值门户通过 公共 URL 访问,客户可以在不登录 CRM 的情况下访问:
客户如何访问:
- 当余额低时通过 SMS 发送的直接链接
- 打印材料上的二维码
- ���助服务门户上的链接
- 客户支持共享的链接
门户会根据客户请求的 IP 地址或 IMSI 自动检测客户的服务。
充值流程
充值流程由 4 个步骤 组成:
步骤 1:数据选择
客户选择他们想要购买的服务天数。
界面:
- 滑块控制 - 选择 1 到 30 天
- 实时价格计算 - 根据选择显示总费用
- 到期日期显示 - 计算并显示服务将何时到期
- 当前使用情况显示 - 在充值前显示剩余余额/到期
示例显示:
定价配置:
- 每天的价格通过环境变量
REACT_APP_TOPUP_PRICE_PER_DAY配置 - 默认:每天下 $10 美元
- 货币通过
REACT_APP_CURRENCY_CODE设置
步骤 2:账单信息
客户提供交易的联系信息:
- 名字
- 姓氏
- 电子邮件地址
这些信息用于:
- 发票生成
- 支付收据电子邮件
- 交易记录
- 退款处理(如有必要)
步骤 3:支付
通过 Stripe Elements 进行安全支付处理。
支持的支付方式:
- 信用卡(Visa、Mastercard、Amex)
- 借记卡
- 数字钱包(Apple Pay、Google Pay)如果在 Stripe 中启用
安全功能:
- 符合 PCI 标准的 Stripe 集成
- OmniCRM 中不存储卡信息
- 支持 3D Secure 身份验证
- 加密支付传输
支付流程:
- 显示带有卡输入的 Stripe Elements 表单
- 客户输入支付信息
- 为确切金额创建支付意图
- 卡立即被扣款
- 处理支付成功/失败
::: note ::: title 注意 :::
如果支付成功但充值配置失败(例如,网络错误,OCS 无法访问),系统会自动向客户的支付方式发起 全额退款。 :::
步骤 4:完成
成功屏幕:
您的服务已延长。新到期日期:2025年1月17日
收据已发送至:<customer@example.com> 交易 ID:TXN-123456
失败屏幕:
如果充值失败,系统会显示错误并自动处理退款:
我们无法完成您的充值。您的付款已被退款。
错误:无法连接到计费系统
请重试或联系支持。
后端处理
当客户完成支付时,以下操作会自动发生:
1. 支付验证
系统验证:
- 支付意图状态为
succeeded - 支付金额与选择的天数匹配(
days × price_per_day) - 支付意图未被处理过(防止重复充值)
2. 充值操作
- API 端点: POST /oam/topup_dongle
- 验证 service_uuid 和 IMSI
- 调用 OCS/CGRateS 添加余额
- 创建配置作业 (play_topup_hotspot)
3. 记录创建
系统创建多个数据库记录:
- HotspotTopup 记录 - 跟踪充值交易
- payment_intent_id
- service_uuid
- imsi
- 购买的天数
- topup_amount
- 状态(成功/失败/退款)
- 交易记录 - 财务交易
- 标题:“热点充值 - 7 天”
- 金额:topup_amount(正数)
- 链接到 service_id 和 customer_id
- 发票记录 - 支付发票
- 包含充值交易
- 立即标记为已支付
- 支付参考:Stripe payment_intent_id
- 支付交易 - 抵消信用交易
- 标题:“支付 [发票标题]”
- 金额:topup_amount(负数 - 信用)
- 将发票支付链接到客户账户
4. 配置作业
创建一个配置作业,使用 playbook play_topup_hotspot,其:
- 连接到 OCS/CGRateS API
- 向账户添加余额
- 延长到期日期
- 创建活动日志条目
- 发送确认通知(如果配置)
API 等待配置完成(以 0.2 秒的间隔轮询,最多 25 次迭代)后返回成功给客户。
5. 失败时自动退款
如果支付后任何步骤失败:
if topup_provisioning_failed:
refund = stripe.Refund.create(
payment_intent=payment_intent_id,
reason='requested_by_customer' # 自动系统退款
)
status_message = "充值失败。正在退款..."
退款会自动处理,客户会在屏幕上收到通知。
API 端点
充值端点
POST /oam/topup_dongle
Content-Type: application/json
{
"service_uuid": "123e4567-e89b-12d3-a456-426614174000",
"imsi": "310120123456789",
"days": 7,
"payment_intent_id": "pi_1234567890abcdef",
"topup_amount": 70.00
}
响应(成功):
{
"result": "OK",
"status": 200,
"provision_id": 456,
"payment_intent_id": "pi_1234567890abcdef",
"service_uuid": "123e4567-e89b-12d3-a456-426614174000",
"invoice_id": 789
}
响应(失败):
{
"result": "Failed",
"Reason": "OCS connection timeout",
"status": 500
}
验证检查:
- 所有必需字段存在(service_uuid、imsi、days、payment_intent_id、topup_amount)
- topup_amount 与 days 匹配:
topup_amount × 100 == days × 1000(以分为单位) - Stripe 中存在支付意图
- 支付意图金额匹配:
payment_intent.amount == topup_amount × 100 - 支付意图状态为
succeeded - 支付意图未被处理过(检查
HotspotTopup表)
使用端点
检索客户的当前使用��况和服务信息:
GET /oam/usage
响应:
{
"imsi": "310120123456789",
"service": {
"service_uuid": "123e4567-e89b-12d3-a456-426614174000",
"service_name": "移动数据 - 0412345678",
"service_status": "活动"
},
"balance": {
"expiry": "2025-01-10T23:59:59Z",
"unlimited": true
},
"requestingIp": "203.0.113.45"
}
此端点使用请求的 IP 地址自动识别客户的服务。
配置
环境变量
在 OmniCRM-UI 的 .env 文件中配置这些:
# 充值门户配置
REACT_APP_TOPUP_PRICE_PER_DAY=10
REACT_APP_CURRENCY_CODE=AUD
REACT_APP_SELF_CARE_NAME="YourCompany"
# Stripe 配置
REACT_APP_STRIPE_PUBLISHABLE_KEY=pk_live_...
Stripe 配置
充值系统使用 Stripe 支付意图:
- 在您的 Stripe 控制面板中启用支付意图
- 配置 Webhook 以接收支付状态更新(可选但推荐)
- 设置支付方式(卡、钱包等)
- 测试模式 - 在开发中使用测试密钥
# 开发
REACT_APP_STRIPE_PUBLISHABLE_KEY=pk_test_...
# 生产
REACT_APP_STRIPE_PUBLISHABLE_KEY=pk_live_...
Playbook 配置
配置 playbook play_topup_hotspot.yaml 必须:
- 接受
days变量 - 连接到 OCS/CGRateS API
- 向账户添加余额
- 更新服务到期日期
示例 playbook 结构:
- name: 充值热点服务
hosts: localhost
tasks:
- name: 向 OCS 添加余额
uri:
url: "{{ ocs_api_url }}/add_balance"
method: POST
body:
imsi: "{{ imsi }}"
days: "{{ days }}"
service_uuid: "{{ service_uuid }}"
余额不足通知
系统可以在客户余额不足时发送自动通知:
短信通知:
当 OCS 事件触发时(Action_Balance_Low、Action_Balance_Out、Action_Balance_Expired):
电子邮件通知:
在 OCS/CGRateS 行动计划中配置以发送余额警报。
通知触发器:
Action_Balance_Low- 余额低于阈值(例如,剩余 2 天)Action_Balance_Out- 余额耗尽Action_Balance_Expired- 服务到期
每个通知都包含充值门户链接,方便客户访问。
故障排除
常见问题
“支付系统不可用”
- 原因: Stripe 库加载失败或无效的可发布密钥
- 修复:
- 检查
REACT_APP_STRIPE_PUBLISHABLE_KEY是否设置正确 - 验证 Stripe 账户是否处于活动状态
- 检查浏览器控制台是否有 JavaScript 错误
- 检查
“充值失败。正在退款...”
- 原因: 配置作业失败(OCS 无法访问,playbook 错误等)
- 修复:
- 检查配置日志:
GET /crm/provision/provision_id/<id> - 验证 OCS/CGRateS API 是否可访问
- 检查 playbook
play_topup_hotspot.yaml是否有错误 - 检查 Ansible 日志
- 检查配置日志:
“支付意图已处理”
- 原因: 客户尝试重复使用同一付款(例如,成功后刷新)
- 修复: 这是为了防止重复收费而设计的。客户如有需要应开始新的充值。
“支付意图金额不匹配”
- 原因: UI 计算与后端验证不匹配
- 修复:
- 验证
REACT_APP_TOPUP_PRICE_PER_DAY是否与后端期望一致(默认 $10) - 检查货币配置是否一致
- 清除浏览器缓存并重试
- 验证
监控充值
查看充值记录:
查询 HotspotTopup 表以查看所有充值尝试:
SELECT
hotspot_topup_id,
service_uuid,
days,
topup_amount,
status,
payment_intent_id,
created
FROM hotspot_topup
WHERE status = 'Failed'
ORDER BY created DESC;
检查配置状态:
GET /crm/provision/provision_id/<provision_id>
显示充值配置作业的详细状态。
Stripe 控制面板:
在您的 Stripe 控制面板中监控支付、退��和失败的交易,链接为 <https://dashboard.stripe.com>
安全考虑
支付安全:
- 所有卡数据由 Stripe 处理(符合 PCI Level 1 标准)
- OmniCRM 数据库中不存储敏感支付数据
- 支付意图防止未经授权的收费
- 客户端和服务器端均进行金额验证
防欺诈:
- 重复支付意图检测防止重复收费
- IP 地址跟踪以进行使用关联
- IMSI 验证确保充值到正确的服务
- 自动退款限制财务风险
访问控制:
- 充值门户是公共的(按设计 - 客户需要访问)
- 使用端点需要有效的服务识别(IP 或 IMSI)
- 后端验证防止任意服务充值
- 管理员可以通过 CRM 界面查看所有充值记录
最佳实践
对于运营商:
- 测试退款流程 - 定期测试失败场景以确保退款正常
- 监控失败的充值 - 设置高失败率的警报
- 保持 playbooks 简单 - 充值 playbooks 应该快速且可靠
- 验证 OCS 连接性 - 确保 OCS API 始终可访问
- 审查定价 - 根据需要更新
REACT_APP_TOPUP_PRICE_PER_DAY
对于客户:
- 收藏充值 URL - 需要时快速访问
- 保存余额不足通知 - 短信中包含直接链接
- 保持电子邮件更新 - 收据发送到文件上的电子邮件
- 出行前检查到期 - 在离开覆盖区域前充值
对于开发者:
- 处理 Stripe webhooks - 实现 webhook 处理程序以获取支付状态更新
- 实现幂等性 - 在处理前始终检查 payment_intent_id
- 广泛记录 - 充值失败需要详细的故障排除信息
- 测试错误路径 - 验证退款自动化是否正常工作
- 监控性能 - 配置轮询应在 <5 秒内完成
相关文档
payments_process- 一般支付处理concepts_provisioning- 配置系统概述integrations_stripe- Stripe 集成细节payments_transaction- 交易管理payments_invoices- 发票处理