定义产品和 CGRateS 配置
本指南解释了如何在 OmniCRM 中定义产品及其相关的 CGRateS 计费配置。
产品及其 CGRateS 操作通常在 Python 脚本中一起定义,这些脚本配置了 CRM 和 OCS(在线计费系统)。
概述
定义完整产品涉及在 两个系统 中进行配置:
- CGRateS/OCS - 定义计费行为(操作、费率、目的地)
- OmniCRM - 定义产品元数据(价格、名称、特性)
这些系统之间的链接是故意松散的,允许您通过定义的 Ansible Play 与 CGrateS 进行交互。
重要提示:CGRateS 能力
CGRateS 是一个极其强大和灵活的计费引擎。 本指南展示了 一种常见的配置模式 用于 OmniCRM 产品,但 CGRateS 还可以做更多事情:
- 高级计费场景:按时间段计费、客户等级、基于通话质量的路由、突发计费
- 复杂的漫游逻辑:漫游时 MO 与 MT 通话/SMS 的不同费率、网络特定定价
- 遗留协议支持:用于 2G/3G 漫游的 CAMEL(MO-MT SMS、USSD)、用��� LTE/5G 的 Diameter
- 复杂的计费:基于预留的计费、信用控制、多层次回退
- 动态路由:基于成本的路由、供应商选择、LCR(最低成本路由)
这只是 CRM 指南 - 它专注于与 OmniCRM 的配置系统良好配合的简单产品定义模式。有关高级 CGRateS 配置,请查阅 CGRateS 文档 或查看 CGRateS 操作和充值行为 以获取余额方法和计费策略。
完整的产品定义工作流程
步骤 1:对 CRM API 进行身份验证
import requests
import json
crm_url = 'https://crm.example.com/'
session = requests.Session()
headers = {
"Content-Type": "application/json"
}
# 获取身份验证令牌
response = session.post(crm_url + '/crm/auth/login', json={
"email": "admin@example.com",
"password": "your_password"
}, headers=headers)
assert response.status_code == 200
headers['Authorization'] = 'Bearer ' + response.json()['token']
print("对 CRM 身份验证成功")
步骤 2:定义库存模板(可选)
库存模板定义可以在配置过程中分配的物理项目类型(SIM 卡、路由器等)。
inventory_list_new = []
# 定义 SIM 卡库存模板
inventory_list_new.append({
"item": "SIM Card",
"itemtext1_label": "ICCID",
"itemtext2_label": "IMSI",
"wholesale_cost": 0.2,
"retail_cost": 1,
"allow_dropdown_staff": True,
"allow_dropdown_customer": True,
"icon": "fa-solid fa-sim-card"
})
# 定义手机号码库存模板
inventory_list_new.append({
"item": "Mobile Number",
"itemtext1_label": "E.164 Mobile Number",
"itemtext2_label": "Type",
"wholesale_cost": 0.2,
"retail_cost": 3,
"icon": "fa-solid fa-phone"
})
# 检查库存模板是否存在,创建或更新
for inventory_template in inventory_list_new:
# 获取现有模板
inventory_list_existing = session.get(
crm_url + '/crm/inventory/item_template/',
headers=headers
)
# 检查模板是否已存在
if inventory_template['item'] in [x['item'] for x in inventory_list_existing.json()]:
# 更新现有模板
inventory_template_id = [
x['inventory_template_id']
for x in inventory_list_existing.json()
if x['item'] == inventory_template['item']
][0]
response = session.patch(
crm_url + '/crm/inventory/item_template/' + str(inventory_template_id),
json=inventory_template,
headers=headers
)
assert response.status_code == 200
print(f"更新库存模板: {inventory_template['item']}")
else:
# 创建新模板
response = session.put(
crm_url + '/crm/inventory/item_template',
json=inventory_template,
headers=headers
)
assert response.status_code == 200
print(f"创建库存模板: {inventory_template['item']}")
库存模板字段:
- item(必需) - 模板名称
- itemtext1_label - 第一个自定义字段的标签
- itemtext2_label - 第二个自定义字段的标签
- wholesale_cost - 您的成本
- retail_cost - 面向客户的成本
- allow_dropdown_staff - 在员工下拉菜单中显示
- allow_dropdown_customer - 在客户下拉菜单中显示
- icon - Font Awesome 图标类
步骤 3:连接到 CGRateS
import cgrateshttpapi
import time
OCS_Obj = cgrateshttpapi.CGRateS("ocs.example.com", "2080")
tenant = "your_tenant_name"
tpid = str(tenant) + "_" + str(int(time.time()))
步骤 4:在 CGRateS 中定义目的地
目的地 定义余额可以使用的地方。它们必须在创建引用它们的操作之前定义。
有两种类型:
- 地理目的地 - 针对特定地点的语音/SMS 的号码前缀(例如,
Dest_AU_Mobile,Dest_International_UK) - PLMN 目的地 - 数据使用和漫游的网络代码(例如,
Dest_PLMN_OnNet,Dest_PLMN_US_Verizon)
关键规则:
- 语音/SMS 余额 → 使用地理目的地(被拨打的号码)
- 数据余额 → 使用 PLMN 目的地(客户连接的网络)
有关完整的目的地定义示例,包括:
- 地理目的地(移动、固定电话、免费电话、国际)
- PLMN 目的地(本网、漫游、区域)
- PLMN 格式规则(
mccXXX.mncYYY) - 何时使用每种方法
步骤 5:定义 CGRateS 操作
操作 是将余额添加到客户账户的机制。在将 CRM 产品链接到操作之前,必须在 CGRateS 中定义该操作。
关键: 操作在初始系统配置期间定义(而不是在配置过程中)。它们指定要添加的余额、到期时间、回滚行为等。
请参见 CGRateS 操作和充值行为 以获取有关以下内容的完整文档:
- 如何使用 Python 定义操作(
OCS_Obj.SendData) - 理解
*topup与*topup_reset(回滚行为) - 单位计算(数据的字节、语音的纳秒、SMS 的计数)
- 字段参考(BalanceId、BalanceType、DestinationIDs、Units、ExpiryTime、Weight)
- 完整的工作示例(多余额计划、数据附加、语音附加)
- 余额消耗规则和优先级
快速回滚参考:
*topup- 添加到现有余额(启用回滚)。适用于:预付费附加、数据包*topup_reset- 替换现有余额(无回滚)。适用于:具有固定津贴的月度计划
步骤 6:在 CRM 中创建产品
现在在 CGRateS 中定义了操作,创建相应的 CRM 产品。
示例:独立 SIM 服务
product_list_new = []
product_list_new.append({
"category": "standalone",
"provisioning_play": "play_psim_only",
"relies_on_list": "",
"contract_days": 0,
"retail_cost": 0,
"retail_setup_cost": 0,
"product_slug": "Mobile-SIM",
"product_name": "仅限移动 SIM",
"comment": "用于手机的物理 SIM 卡",
"provisioning_json_vars": "{\"iccid\" : \"\", \"msisdn\" : \"\"}",
"terms": "必须在 6 个月内激活。如果服务在 12 个月内未使用,则所有信用将丢失。",
"service_type": "mobile",
"residential": True,
"business": True,
"enabled": True,
"inventory_items_list": "['SIM Card', 'Mobile Number']",
"icon": "fa-solid fa-sim-card",
"features_list": "['澳大利亚电话号码 (61xxx)', '最快速度', '最佳覆盖']",
"wholesale_cost": 3,
"wholesale_setup_cost": 1,
"customer_can_purchase": True
})
示例:月度计划附加
product_list_new.append({
"category": "addon",
"provisioning_play": "play_topup_charge_then_action",
"relies_on_list": "",
"contract_days": 30,
"retail_cost": 59.00,
"retail_setup_cost": 0,
"product_slug": "au-premium-plan-1", # 链接到 Action_au-premium-plan-1
"product_name": "AU 高级计划 1",
"comment": "在澳大利亚 100GB 数据,3000 分钟通话,3000 条 SMS,在澳大利亚 6GB 漫游数据",
"provisioning_json_vars": "",
"terms": "后付费计划。每 30 天自动续订。",
"service_type": "mobile",
"residential": True,
"business": True,
"enabled": True,
"icon": "fa-solid fa-mobile",
"features_list": "['在澳大利亚 100GB 数据', '在澳大利亚 3000 分钟', '在澳大利亚 3000 条 SMS', '6GB 漫游数据']",
"wholesale_cost": 45.00,
"wholesale_setup_cost": 0,
"auto_renew": "True",
"customer_can_purchase": True
})
示例:一次性充值附加
product_list_new.append({
"category": "addon",
"provisioning_play": "play_topup_charge_then_action",
"relies_on_list": "",
"contract_days": 0,
"retail_cost": 30,
"retail_setup_cost": 0,
"product_slug": "au-data-addon-20gb", # 链接到 Action_au-data-addon-20gb
"product_name": "AU 数据附加 20GB",
"comment": "在澳大利亚 20GB 数据",
"provisioning_json_vars": "",
"terms": "预付费充值。立即收费。",
"service_type": "mobile",
"residential": True,
"business": True,
"enabled": True,
"icon": "fa-solid fa-mobile",
"features_list": "['在澳大利亚 20GB 数据']",
"wholesale_cost": 22,
"wholesale_setup_cost": 0,
"auto_renew": "False",
"customer_can_purchase": True
})
产品字段描述:
- category(必需) - 产品类别:
standalone- 完整服务(创建新服务记录)addon- 添加到现有服务bundle- 多个服务的包
- provisioning_play(必需) - 要执行的 Ansible playbook(例如,
play_topup_charge_then_action,play_simple_service) - relies_on_list - 该产品依赖的 product_slugs 的逗号分隔列表
- contract_days - 合同持续天数(0 = 无合同,30 = 每月)
- retail_cost(必需�� - 面向客户的每月/定期成本
- retail_setup_cost - 向客户收取的一次性设置费用
- product_slug(必需) - 链接到 CGRateS 操作的唯一标识符(约定:
Action_{product_slug}) - product_name(必需) - 显示名称
- comment - 简短描述
- provisioning_json_vars - 传递给 playbook 的变量的 JSON 字符串
- terms - 条款和条件文本
- service_type - 服务分类(移动、加密狗、固定等)
- residential - 可供住宅客户使用
- business - 可供商业客户使用
- enabled - 产品处于活动状态并可购买
- inventory_items_list - 所需库存项目的 Python 列表字符串
- icon - Font Awesome 图标类
- features_list - 特性要点的 Python 列表字符串
- wholesale_cost - 您的定期成本
- wholesale_setup_cost - 您的一次性成本
- auto_renew - 自动续订的 "True" 或 "False" 字符串
- customer_can_purchase - 客户可以通过自助服务门户购买
另请参见:产品生命周期
步骤 7:通过 API 创建或更新产品
# 获取现有产品
product_list_existing = session.get(crm_url + '/crm/product', headers=headers)
existing_products = product_list_existing.json()
# 处理每个产品
for product in product_list_new:
print(f"处理产品: {product['product_slug']}")
# 检查产品是否已经存在
if product['product_slug'] in [x['product_slug'] for x in existing_products]:
print(f"产品已存在: {product['product_slug']}")
# 获取现有产品的 product_id
product_id = [
x['product_id']
for x in existing_products
if x['product_slug'] == product['product_slug']
][0]
product['product_id'] = product_id
# 更新现有产品
response = session.patch(
crm_url + '/crm/product/' + str(product_id),
json=product,
headers=headers
)
print(f"状态: {response.status_code}")
assert response.status_code == 200
print(f"更新产品: {product['product_slug']}")
else:
# 创建新产品
print(f"创建新产品: {product['product_slug']}")
response = session.put(
crm_url + '/crm/product',
json=product,
headers=headers
)
print(f"状态: {response.status_code}")
assert response.status_code == 200
print(f"创建产品: {product['product_slug']}")
将产品链接到操作
CRM 产品与 CGRateS 操作之间的关键链接是 命名约定:
# 在 CGRateS 中
ActionsId = "Action_au-premium-plan-1"
# 在 CRM 中
product_slug = "au-premium-plan-1"
# 在 playbook 中(自动构造)
cgr_action_name = "Action_" + product_slug
# 结果: "Action_au-premium-plan-1"
Playbooks 如何执行操作
注意: 使用 ExecuteAction 只是添加余额的一种模式。您也可以直接在 playbook 中调用 SetBalance 或其他 CGRateS API。然而,OmniCRM-API/Provisioners/plays/play_topup_charge_then_action.yaml 使用 ExecuteAction 模式,因为它是一种常见的、可重用的方法,将余额逻辑(操作)与配置逻辑(Playbooks)分开。
当使用此模式配置产品时,playbook 从 product_slug 构造操作名称:
# 在 play_topup_charge_then_action.yaml 中
- name: 设置 cgr_action_name 事实
set_fact:
cgr_action_name: "Action_{{ api_response_product.json.product_slug }}"
# 执行操作
- name: 执行 CGRateS 操作
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
body:
{
"method": "APIerSv1.ExecuteAction",
"params": [{
"Tenant": "{{ crm_config.ocs.ocsTenant }}",
"Account": "{{ service_uuid }}",
"ActionsId": "{{ cgr_action_name }}"
}]
}
使用此模式时: 操作 必须在 CGRateS 中存在,否则执行将失败并显示 "找不到操作" 错误。
另请参见:Ansible Playbooks 指南
完整示例:定义新产品
让我们逐步创建一个完整的新产品 "50GB 数据包":
1. 在 CGRateS 中定义操作
请参见步骤 5 中的 简单数据附加 示例,了解如何定义数据附加操作。对于我们的 50GB 示例,操作将遵循相同的模式,但单位不同:
- ActionsId:
"Action_50gb-data-pack"(与下面的 product_slug 匹配) - BalanceType:
"*data" - DestinationIDs:
"Dest_PLMN_OnNet"(用于本网数据使用) - Units:
50 * 1024 * 1024 * 1024(50GB 以字节为单位) - Identifier:
"*topup"(启用回滚)
2. 在 CRM 中创建产品
product_50gb_data = {
"category": "addon",
"provisioning_play": "play_topup_charge_then_action",
"relies_on_list": "",
"contract_days": 0,
"retail_cost": 25.00,
"retail_setup_cost": 0,
"product_slug": "50gb-data-pack", # 必须与 ActionsId 匹配,不带 "Action_"
"product_name": "50GB 数据包",
"comment": "有效期 30 天的 50GB 高速数据",
"provisioning_json_vars": "",
"terms": "数据在 30 天后过期。如果在到期之前再次充值,未使用的数据将回滚。",
"service_type": "mobile",
"residential": True,
"business": True,
"enabled": True,
"icon": "fa-solid fa-database",
"features_list": "['50GB 高速数据', '30 天有效期', '启用回滚']",
"wholesale_cost": 20.00,
"wholesale_setup_cost": 0,
"auto_renew": "False",
"customer_can_purchase": True
}
# 在 CRM 中创建
response = session.put(
crm_url + '/crm/product',
json=product_50gb_data,
headers=headers
)
assert response.status_code == 200
print("产品创建成功: 50gb-data-pack")
3. 验证链接
现在可以配置产品:
- 客户购买 "50GB 数据包"(product_slug:
50gb-data-pack) - Playbook
play_topup_charge_then_action执行 - Playbook 构造操作名称:
Action_50gb-data-pack - Playbook 调用
APIerSv1.ExecuteAction,使用 ActionsIdAction_50gb-data-pack - CGRateS 找到操作并执行
- 客户收到 50GB 余额
另请参见:从 Playbooks 进行计费和支付
常见产品模式
这些模式展示了典型的 CRM 产品配置及其与 CGRateS 操作的链接。有关相应的操作定义,请参��� CGRateS 操作和充值行为。
模式 1:多余额月度计划
用例: 综合月度计划,包含数据、语音、SMS、漫游
CRM 产品:
{
"product_slug": "premium-monthly-plan", # 链接到 Action_premium-monthly-plan
"product_name": "高级月度计划",
"category": "addon",
"retail_cost": 59.00,
"auto_renew": "True",
"contract_days": 30,
"provisioning_play": "play_topup_charge_then_action",
"features_list": "['100GB 数据', '5000 分钟', '5000 条 SMS', '包含漫游']"
}
操作: 使用 *topup_reset 和多种余额类型。请参见 示例 1:多余额月度计划(Python)。
模式 2:简单数据附加(回滚)
用例: 一次性数据购买,如果再次充值则会回滚
CRM 产品:
{
"product_slug": "10gb-addon", # 链接到 Action_10gb-addon
"product_name": "10GB 数据附加",
"category": "addon",
"retail_cost": 15.00,
"auto_renew": "False", # 一次性购买
"contract_days": 0,
"provisioning_play": "play_topup_charge_then_action",
"features_list": "['10GB 数据,支持回滚', '30 天有效期']"
}
操作: 使用 *topup 以实现回滚行为。请参见 CGRateS 操作 - 回滚。
模式 3:固定月度计划(无回滚)
用例: 每月计划,总是重置为完全相同的金额
CRM 产品:
{
"product_slug": "fixed-50gb-monthly", # 链接到 Action_fixed-50gb-monthly
"product_name": "固定 50GB 月度计划",
"category": "addon",
"retail_cost": 35.00,
"auto_renew": "True",
"contract_days": 30,
"provisioning_play": "play_topup_charge_then_action",
"features_list": "['50GB 数据', '每月重置', '无回滚']"
}
操作: 使用 *topup_reset 来防止回滚。请参见 CGRateS 操作 - 重置行为。
高级:充电器和计费计划
重要提示: 本节涵盖基本的按使用付费计费。CGRateS 支持极其复杂的计费场景,包括:
- 差异化漫游费率:漫游时 MO 与 MT 通话/SMS 的不同价格
- 协议特定计费:用于 2G/3G 的 CAMEL(MO-MT SMS、USSD),用于 4G/5G 的 Diameter
- 上下文感知定价:基于时间、地点、客户细分、网络质量的费率
- ���维计费:结合网络类型、漫游状态、目的地和时间段
以下示例展示了适合大多数 OmniCRM 部署的简单、固定费率的 PAYG 配置。
计费工作原理
当客户使用服务(数据、语音、SMS)时:
- CGRateS 检查是否存在单元余额(例如,包含的数据 GB)
- 如果存在单元余额,则从中扣除使用量
- 如果没有单元余额或余额耗尽,CGRateS 将回退到货币余额
- 计费计划 确定价格(例如,$0.10 每 MB)
- 计算出的费用从客户的货币余额中扣除
示例:设置按使用付费的数据费用
# 1. 定义目的地费率(价格)
OCS_Obj.SendData({
"method": "ApierV2.SetTPDestinationRate",
"params": [{
"TPid": tpid,
"ID": "DR_DATA_PAYG",
"DestinationRates": [{
"DestinationId": "Dest_PLMN_OnNet",
"RateId": "RT_DATA_$0_10_PER_MB",
"RoundingMethod": "*up",
"RoundingDecimals": 4,
"MaxCost": 0,
"MaxCostStrategy": ""
}]
}]
})
# 2. 定义实际费率
OCS_Obj.SendData({
"method": "ApierV2.SetTPRate",
"params": [{
"TPid": tpid,
"ID": "RT_DATA_$0_10_PER_MB",
"RateSlots": [{
"ConnectFee": 0, # 无连接费用
"Rate": 0.10, # 每单位 $0.10
"RateUnit": "1048576", # 1 MB(1024 * 1024 字节)
"RateIncrement": "1048576", # 按 MB 计费
"GroupIntervalStart": "0s"
}]
}]
})
# 3. 定义使用此费率的计费计划
OCS_Obj.SendData({
"method": "ApierV2.SetTPRatingPlan",
"params": [{
"TPid": tpid,
"ID": "RP_PAYG_DATA",
"RatingPlanBindings": [{
"DestinationRatesId": "DR_DATA_PAYG",
"TimingId": "*any",
"Weight": 10
}]
}]
})
# 4. 将计费计划链接到计费配置文件(针对特定账户)
OCS_Obj.SendData({
"method": "ApierV2.SetTPRatingProfile",
"params": [{
"TPid": tpid,
"Tenant": tenant,
"Category": "data",
"Subject": "*any", # 或特定账户标识符
"RatingPlanActivations": [{
"ActivationTime": "2024-01-01T00:00:00Z",
"RatingPlanId": "RP_PAYG_DATA",
"FallbackSubjects": ""
}]
}]
})
# 5. 加载资费计划
OCS_Obj.SendData({
"method": "APIerSv1.LoadTariffPlanFromStorDb",
"params": [{
"TPid": tpid,
"DryRun": False,
"Validate": True,
"APIOpts": {}
}]
})
这做了什么:
- 当客户没有数据余额(或用尽)时,数据使用费用为 $0.10 每 MB
- 费用从他们的货币余额中扣除(
*monetary) - 计费增量为 1 MB(向上取整)
示例:语音通话费率
# 为不同目的地定义不同的费率
OCS_Obj.SendData({
"method": "ApierV2.SetTPRate",
"params": [{
"TPid": tpid,
"ID": "RT_VOICE_DOMESTIC_$0_30_PER_MIN",
"RateSlots": [{
"ConnectFee": 0.15, # $0.15 连接费用
"Rate": 0.30, # 每分钟 $0.30
"RateUnit": "60s", # 按分钟计费
"RateIncrement": "60s", # 四舍五入到整分钟
"GroupIntervalStart": "0s"
}]
}]
})
OCS_Obj.SendData({
"method": "ApierV2.SetTPRate",
"params": [{
"TPid": tpid,
"ID": "RT_VOICE_INTL_$1_50_PER_MIN",
"RateSlots": [{
"ConnectFee": 0.25, # $0.25 连接费用
"Rate": 1.50, # 每分钟 $1.50
"RateUnit": "60s",
"RateIncrement": "1s", # 按秒计费(更准确)
"GroupIntervalStart": "0s"
}]
}]
})
充电器配置文件(可选)
充电器将计费应用于特定类型的事件。对于大多数用例,默认充电器就足够了:
OCS_Obj.SendData({
"method": "APIerSv1.SetChargerProfile",
"params": [{
"Tenant": tenant,
"ID": "Charger_Default",
"FilterIDs": [],
"AttributeIDs": ["*constant:*req.RequestType:*none"],
"Weight": 999
}]
})
另请参见:
- CGRateS 操作和充值行为 - 余额管理方法(单元、货币、混合)和计费配置
- CGRateS 目的地 - 如何定义地理和 PLMN 目的地
最佳实践
1. 使用一致的命名约定
# 好 - 清晰的关系
ActionsId = "Action_premium-plan-100gb"
product_slug = "premium-plan-100gb"
# 坏 - 没有清晰的关系
ActionsId = "Action_Plan_A"
product_slug = "premium_100"
2. 在产品之前定义操作
始终在创建 CRM 产品之前创建 CGRateS 操作。如果在执行不存在的操作时,配置 playbook 将失败。
3. 包含 CDR 日志记录
始终添加 *cdrlog 操作以跟踪余额添加:
{
"Identifier": "*cdrlog",
"BalanceType": "*generic",
"ExtraParameters": "{\"Category\":\"^activation\",\"Destination\":\"Product Name\"}",
"Weight": 80
}
4. 使用描述性余额 ID
# 好
"BalanceId": "Premium_Data_100GB"
"BalanceId": "AU_Voice_Domestic__" + str(units)
# 坏
"BalanceId": "data1"
"BalanceId": "balance"
5. 清晰地记录单位
# 好 - 显示计算
Units = 100 * 1024 * 1024 * 1024 # 100GB 以字节为单位
Units = 3000 * 60 * 1000000000 # 3000 分钟以纳秒为单位
# 坏 - 魔法数字
Units = 107374182400
6. 战略性地使用权重
较高的权重 = 较高的优先级,适用于执行和消耗:
# 执行顺序(较高的权重 = 首先执行)
{"Identifier": "*reset_account", "Weight": 700}
{"Identifier": "*topup_reset", "Weight": 90}
{"Identifier": "*cdrlog", "Weight": 80}
# 余额消耗(较高的权重 = 首先消耗)
"BalanceWeight": 1200 # 高级/国内余额
"BalanceWeight": 1100 # 漫游余额
"BalanceWeight": 1000 # 国际余额
7. 首先使用小值进行测试
在定义新产品时,首先使用小余额进行测试:
# 测试
Units = 100 * 1024 * 1024 # 100MB 用于测试
# 生产
Units = 100 * 1024 * 1024 * 1024 # 100GB
故障排除
错误:��找不到操作”
症状: Playbook 失败并显示 "找不到操作" 或 "ActionsId 不存在"
原因: 操作未在 CGRateS 中定义,或命名不匹配
解决方案:
- 验证操作是否存在:查询 CGRateS 以获取该操作
- 检查命名:确保
ActionsId = "Action_" + product_slug - 如果缺失,请定义该操作
错误:“找不到目的地”
症状: 操作执行但未创建余额
原因: DestinationIDs 引用不存在的目的地
解决方案:
- 首先在 CGRateS 中定义目的地
- 对于通用目的地使用
*any - 检查目的地 ID 的拼写
产品创建但未添加余额
症状: 产品成功配置但客户没有余额
原因: 操作存在但没有余额添加操作
解决方案:
- 验证操作是否具有
*topup或*topup_reset操作 - 检查单位值是否正确(不是 0)
- 验证到期时间是否已过
余额未回滚
症状: 使用回滚但未使用的余额消失
原因: 使用了 *topup_reset 而不是 *topup
解决方案:
- 将
Identifier从*topup_reset更改为*topup - 确保 BalanceId 在充值之间保持一致
另请参见:CGRateS 操作和充值行为
总结
本指南��示了一种在 OmniCRM 中配置产品与 CGRateS 的常见方法。这里展示的模式适用于典型的移动虚拟网络运营商(MVNO)用例,包括预付费/后付费计划、数据包和漫游。
请记住: CGRateS 能够处理比这里覆盖的更复杂的场景。如果您需要高级功能,例如:
- 漫游语音和 SMS 的差异化 MO/MT 定价
- 针对 2G/3G 遗留设备的基于 CAMEL 的计费
- 按时间段或季节性费率变化
- 基于客户等级的定价(青铜/白银/黄金)
- 基于网络质量或 QoS 的计费
- 具有多个供应商的最低成本路由
...请直接查阅 CGRateS 文档,并独立于 CRM 产品定义进行计费计划配置。
相关文档
- CGRateS 操作和充值行为 - 有关操作类型和余额行为的详细指南
- Ansible Playbooks 指南 - Playbooks 如何执行操作
- 从 Playbooks 进行计费和支付 - 配置过程中的支付处理
- 产品生命周期 - 管理产品的生命周期
- 概念:产品和服务 - 产品基础知识
- CGRateS 官方文档 - 完整的 CGRateS 参考