CGRateS Destinations Configuration
This guide explains how to configure destinations in CGRateS for OmniCRM. Destinations define WHERE balances can be used - whether that's calling specific numbers (geographic) or using data/voice on specific networks (PLMN).
Overview
CGRateS uses destinations to control where customers can use their balances:
- Geographic Destinations - Number prefixes for calls/SMS TO specific locations (e.g., UK numbers, US toll-free)
- PLMN Destinations - Network codes for data usage and roaming FROM specific networks (e.g., Verizon, Vodafone UK)
When customers use services, CGRateS matches:
- Voice/SMS: The dialed number prefix → Geographic destination
- Data: The network PLMN code → PLMN destination
Critical Rule
- Voice/SMS balances → Use geographic destinations (the number being called TO)
- Data balances → Use PLMN destinations (the network customer is connected on FROM)
Prerequisites
import cgrateshttpapi
import time
OCS_Obj = cgrateshttpapi.CGRateS("ocs.example.com", "2080")
tenant = "your_tenant_name"
tpid = str(tenant) + "_" + str(int(time.time()))
Part 1: Geographic Destinations (Calling TO Places)
Geographic destinations define number prefixes for voice calls and SMS to specific locations.
Domestic Destinations
# ===================================================================
# DOMESTIC DESTINATIONS (US/Canada - NANP)
# ===================================================================
# US/Canada Mobile & Fixed (share area codes)
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_Domestic_All",
"Prefixes": ["1"] # NANP (US/Canada)
}]
})
# US Toll-Free
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_Domestic_TollFree",
"Prefixes": ["1800", "1888", "1877", "1866", "1855", "1844", "1833"]
}]
})
# US Premium Rate
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_Domestic_Premium",
"Prefixes": ["1900"]
}]
})
International Destinations
# ===================================================================
# INTERNATIONAL DESTINATIONS (By Country)
# ===================================================================
# United Kingdom
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_International_UK",
"Prefixes": ["44"]
}]
})
# China
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_International_China",
"Prefixes": ["86"]
}]
})
# Australia - Mobile
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_AU_Mobile",
"Prefixes": ["614"] # Australian mobiles (04xx dialed as 614xx)
}]
})
# Australia - Fixed Line
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_AU_Fixed",
"Prefixes": [
"612", # NSW (Sydney)
"613", # VIC (Melbourne)
"617", # TAS (Hobart)
"618" # SA, WA, NT (Adelaide, Perth, Darwin)
]
}]
})
# Australia - Toll-Free
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_AU_TollFree",
"Prefixes": [
"611800", # Toll-free
"611300" # Local rate
]
}]
})
# Australia - Premium Rate
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_AU_Premium",
"Prefixes": ["6119"] # Premium rate services
}]
})
# Europe (grouped)
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_International_Europe",
"Prefixes": [
"33", # France
"49", # Germany
"39", # Italy
"34", # Spain
"31", # Netherlands
"32", # Belgium
"41" # Switzerland
]
}]
})
# International - All (catch-all, excludes domestic)
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_International_All",
"Prefixes": ["2", "3", "4", "5", "6", "7", "8", "9"] # All except "1" (NANP)
}]
})
Use Cases:
- Domestic plans: "Unlimited calls to US/Canada numbers" →
Dest_Domestic_All - UK calling addon: "100 minutes to UK" →
Dest_International_UK - Australian plan: "3000 minutes to Australian mobiles and fixed lines" →
Dest_AU_Mobile,Dest_AU_Fixed,Dest_AU_TollFree - International bundle: "50 minutes to any international number" →
Dest_International_All
Part 2: PLMN Destinations (Usage FROM Places - Roaming / Data Usage)
PLMN destinations define network codes for data usage and roaming scenarios. Use format mccXXX.mncYYY where:
- MCC = Mobile Country Code (3 digits)
- MNC = Mobile Network Code (2-3 digits)
PLMN Format Rules
- Specific network:
"mcc310.mnc004"→ Only Verizon network 004 - All networks in country:
"mcc310"→ Any US network - Examples:
mcc310.mnc004,mcc234.mnc015,mcc505.mnc057
On-Net (Your Home Network)
IMPORTANT: Define YOUR specific network where YOUR SIMs are provisioned.
# On-Net (Your Home Network)
# This is YOUR operator's PLMN - the network where YOUR customers' SIMs are active
# All domestic on-net data balances should use this destination
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_OnNet",
"Prefixes": ["mcc505.mnc057"] # Example: MCC 505, MNC 57 if this is your home network
}]
})
# Replace mcc505.mnc057 with YOUR actual operator's PLMN code
# All domestic on-net data balances should use the prefixes set out here
# Otherwise they're considered roaming
US Roaming PLMN Destinations
# ===================================================================
# US ROAMING PLMN DESTINATIONS
# ===================================================================
# Verizon Wireless
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_US_Verizon",
"Prefixes": [
"mcc310.mnc004", "mcc310.mnc010", "mcc310.mnc012", "mcc310.mnc013",
"mcc311.mnc480", "mcc311.mnc481", "mcc311.mnc482", "mcc311.mnc483"
]
}]
})
# All US PLMNs (catch-all)
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_US_All",
"Prefixes": ["mcc310", "mcc311", "mcc312", "mcc313", "mcc316"]
}]
})
# Note: This matches ANY network with these MCCs (310, 311, etc.)
# Customer on mcc310.mnc004 (Verizon), mcc310.mnc410 (AT&T), mcc311.mnc580 (US Cellular)
# would ALL match this destination
UK Roaming PLMN Destinations
# ===================================================================
# UK ROAMING PLMN DESTINATIONS
# ===================================================================
# Vodafone UK
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_UK_Vodafone",
"Prefixes": ["mcc234.mnc015"]
}]
})
# EE (Everything Everywhere)
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_UK_EE",
"Prefixes": ["mcc234.mnc030", "mcc234.mnc033"]
}]
})
# All UK PLMNs
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_UK_All",
"Prefixes": ["mcc234"]
}]
})
Roaming Zones (Multi-Country Groups)
Great for regional roaming packages like "Europe Roaming" or "Asia Pacific Roaming".
# ===================================================================
# ROAMING ZONES (Multi-Country Groups)
# ===================================================================
# Zone 1: North America
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_Zone_NorthAmerica",
"Prefixes": [
"mcc310", "mcc311", "mcc312", "mcc313", "mcc316", # USA
"mcc302", "mcc334" # Canada
]
}]
})
# Using MCC-only prefixes provides coverage on ANY network in these countries
# Great for "North America roaming" packages that work on all carriers
# Zone 2: Europe
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_Zone_Europe",
"Prefixes": [
"mcc234", # United Kingdom
"mcc208", # France
"mcc262", # Germany
"mcc222", # Italy
"mcc214", # Spain
"mcc228" # Switzerland
]
}]
})
# Zone 3: Asia Pacific
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_Zone_AsiaPacific",
"Prefixes": [
"mcc505", # Australia
"mcc460", # China
"mcc454", # Hong Kong
"mcc440", # Japan
"mcc520", # Thailand
"mcc525", # Singapore
"mcc530" # New Zealand
]
}]
})
# Catch-all for any roaming (use with caution)
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_Roaming_All",
"Prefixes": ["mcc"] # Matches ANY PLMN (very broad)
}]
})
Use Cases:
- Network-specific roaming: "5GB on Verizon only" →
Dest_PLMN_US_Verizon - Country-wide roaming: "10GB in USA (any network)" →
Dest_PLMN_US_All - Regional roaming: "15GB Europe roaming" →
Dest_PLMN_Zone_Europe - Global roaming: "1GB anywhere" →
Dest_Roaming_All
When to Use Each Approach
| Destination Type | Use Case | Example | Balance Types |
|---|---|---|---|
| Geographic | Voice/SMS to specific countries | "100 minutes to UK numbers" | Voice, SMS |
| On-net PLMN | Domestic data on YOUR network | "100GB on-net data" | Data |
| Specific PLMN | Premium roaming on preferred networks | "5GB on Verizon only" | Data (and roaming voice/SMS) |
| Country-wide PLMN | Roaming in any network in country | "5GB in USA (any network)" | Data (and roaming voice/SMS) |
| Zone PLMN | Regional roaming packages | "10GB Europe roaming" | Data (and roaming voice/SMS) |
Dynamic Destination Updates and Service Access
How Destination Updates Work
Critical Concept: Destinations in CGRateS are referenced by ID, not copied. When you update a destination's prefixes or PLMN codes and load the TariffPlan into the runtime, all existing balances referencing that destination are immediately affected.
This means:
- ✅ No need to update individual customer balances when expanding or restricting service coverage
- ✅ Network-wide changes to all customers using that destination once the tariff plan is loaded
- ⚠️ Changes take effect when you load the TariffPlan - you can modify destinations multiple times before loading, and changes only become active after
LoadTariffPlanFromStorDb
Example 1: Expanding Coverage
You have a destination for European roaming:
# Initial configuration - Only 3 countries
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_Zone_Europe",
"Prefixes": [
"mcc262", # Germany
"mcc208", # France
"mcc222" # Italy
]
}]
})
Customers with balances referencing Dest_PLMN_Zone_Europe can roam in Germany, France, and Italy.
Later, you add Spain and UK:
# Updated configuration - Now 5 countries
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_Zone_Europe",
"Prefixes": [
"mcc262", # Germany
"mcc208", # France
"mcc222", # Italy
"mcc214", # Spain (NEW)
"mcc234" # UK (NEW)
]
}]
})
# Load the tariff plan to make changes active
OCS_Obj.SendData({
'method': 'ApierV1.LoadTariffPlanFromStorDb',
'params': [{
"TPid": tpid,
"DryRun": False,
"Validate": True
}]
})
# Reload the destination cache
OCS_Obj.SendData({
'method': 'CacheSv1.ReloadCache',
'params': [{
"DestinationIDs": ["Dest_PLMN_Zone_Europe"]
}]
})
Result: After loading the tariff plan, all existing customers with balances for Dest_PLMN_Zone_Europe gain access to roam in Spain and UK - no individual balance updates required.
Example 2: Restricting Coverage
Removing a country from a destination blocks access once the tariff plan is loaded:
# Remove Germany from Europe zone
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_Zone_Europe",
"Prefixes": [
"mcc208", # France
"mcc222", # Italy
"mcc214", # Spain
"mcc234" # UK
# Germany (mcc262) REMOVED
]
}]
})
# Load the tariff plan to make changes active
OCS_Obj.SendData({
'method': 'ApierV1.LoadTariffPlanFromStorDb',
'params': [{
"TPid": tpid,
"DryRun": False,
"Validate": True
}]
})
# Reload cache
OCS_Obj.SendData({
'method': 'CacheSv1.ReloadCache',
'params': [{
"DestinationIDs": ["Dest_PLMN_Zone_Europe"]
}]
})
Result: After loading the tariff plan, customers attempting to roam in Germany will be blocked, even if they still have balance remaining for Dest_PLMN_Zone_Europe. The balance exists but doesn't match the PLMN destination anymore.
Example 3: Voice/SMS Geographic Destinations
The same principle applies to geographic destinations for voice and SMS:
# Add Canada to "Domestic" calling
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_Domestic_All",
"Prefixes": [
"1", # Already includes USA (and previously Canada)
# No change needed - "1" prefix already covers both
]
}]
})
# Or create separate North America destination
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_North_America",
"Prefixes": [
"1" # USA + Canada
]
}]
})
Impact: Any balances with DestinationIDs: "Dest_Domestic_All" now work for both US and Canada calls (if using prefix "1").
Service Access Rules
Critical: If a customer attempts to use a service (voice/SMS/data) and no destination matches, the service will be denied, even if they have balances.
Scenario 1: No Matching Destination
# Customer has balance:
{
"BalanceId": "Europe_Data_5GB",
"BalanceType": "*data",
"DestinationIDs": "Dest_PLMN_Zone_Europe", # Only France, Germany, Italy
"Units": 5 * 1024 * 1024 * 1024
}
# Customer roams on network in Spain (mcc214.mnc001)
# Spain is NOT in Dest_PLMN_Zone_Europe
Result:
- ❌ Data session blocked (no matching destination)
- Balance remains unused
- Customer receives "Insufficient Credit" or similar error
Fix: Add Spain to Dest_PLMN_Zone_Europe OR ensure customer has a monetary balance with DestinationIDs: "*any" as fallback.
Scenario 2: No Wildcard Fallback
# Customer has two balances:
{
"BalanceId": "UK_Voice_100min",
"BalanceType": "*voice",
"DestinationIDs": "Dest_International_UK", # Only prefix "44"
"Units": 100 * 60 * 1000000000
}
# NO monetary balance with "*any" destination
# Customer calls Australia (+61)
Result:
- ❌ Call blocked (no destination matches prefix "61")
- UK minutes balance unused (only matches "44")
- No monetary fallback to cover the call
Fix: Add a monetary balance with DestinationIDs: "*any" OR add specific Australia destination to their balance.
Scenario 3: Wildcard Fallback Works
# Customer has:
# Balance 1: UK minutes
{
"BalanceId": "UK_Voice_100min",
"BalanceType": "*voice",
"DestinationIDs": "Dest_International_UK",
"Units": 100 * 60 * 1000000000,
"BalanceWeight": 1200
}
# Balance 2: Monetary with wildcard
{
"BalanceId": "PAYG_Credit",
"BalanceType": "*monetary",
"DestinationIDs": "*any", # Matches ANYTHING
"Units": 5000, # $50
"BalanceWeight": 1000 # Lower priority
}
# Customer calls Australia (+61)
Result:
- ✅ Call allowed
- UK minutes balance NOT used (doesn't match "61")
- PAYG Credit balance used (matches "*any")
- Charged at PAYG rate for Australia
Testing and Simulation
Destination changes can be tested and simulated in non-production environments before being applied to production. This allows you to:
- Verify new PLMN codes are correct
- Test coverage expansion/restriction impact
- Validate that existing balances behave as expected with updated destinations
- Ensure fallback mechanisms work correctly
Recommendation: Always test destination updates in a staging environment with test accounts before applying to production.
Key Takeaways
- Destinations are dynamic - Changes affect all balances referencing them once the tariff plan is loaded
- Load TariffPlan to activate - Use
LoadTariffPlanFromStorDbto make destination changes active in runtime - No destination match = No service - Customers will be blocked if their usage doesn't match any destination
- Wildcard (
*any) is powerful - Use for monetary fallback to prevent unexpected blocking - Cache reload required - Always reload destination cache after loading tariff plan
- Test before production - Destination changes impact all customers once loaded
Rate Profiles for PAYG/Monetary Balances
When using monetary balances (PAYG - Pay As You Go), you need to define Rate Profiles that specify how much to charge per unit for different destinations.
Important Note on CGRateS Flexibility: CGRateS is extremely flexible and can apply different rates and plans based on many factors including:
- Where the customer is calling FROM (PLMN - covered here)
- What they're calling TO (geographic destination - covered here)
- Time of day (peak/off-peak rating)
- Customer tier (VIP, standard, etc.)
- Service quality level
- And many more complex rating scenarios
This guide focuses on the CRM-level configuration for PLMN-based roaming and geographic destination-based rating, which covers the most common use cases. Advanced rating scenarios (time-of-day, customer tiers, quality-based routing) are possible in CGRateS but outside the scope of this CRM-focused documentation.
How Rate Profiles Work
Defining Rate Profiles
Rate profiles define the cost per unit for different usage types. Here are examples for voice, SMS, and data:
# ===================================================================
# VOICE RATES (Per Minute)
# ===================================================================
# Domestic voice: $0.10/minute
OCS_Obj.SendData({
'method': 'ApierV2.SetTPRate',
'params': [{
"TPid": tpid,
"ID": "Rate_Voice_Domestic",
"RateSlots": [{
"ConnectFee": 0,
"Rate": 0.10,
"RateUnit": "60s", # 1 minute
"RateIncrement": "1s", # Per-second billing
"GroupIntervalStart": "0s"
}]
}]
})
# UK voice: $0.25/minute
OCS_Obj.SendData({
'method': 'ApierV2.SetTPRate',
'params': [{
"TPid": tpid,
"ID": "Rate_Voice_UK",
"RateSlots": [{
"ConnectFee": 0.05, # $0.05 connection fee
"Rate": 0.25,
"RateUnit": "60s",
"RateIncrement": "6s", # 6-second blocks
"GroupIntervalStart": "0s"
}]
}]
})
# ===================================================================
# SMS RATES (Per Message)
# ===================================================================
# Domestic SMS: $0.05/message
OCS_Obj.SendData({
'method': 'ApierV2.SetTPRate',
'params': [{
"TPid": tpid,
"ID": "Rate_SMS_Domestic",
"RateSlots": [{
"ConnectFee": 0,
"Rate": 0.05,
"RateUnit": "1", # 1 SMS
"RateIncrement": "1", # Per message
"GroupIntervalStart": "0s"
}]
}]
})
# ===================================================================
# DATA RATES (Per MB) - For Roaming
# ===================================================================
# Roaming on US Premium Networks (Verizon, AT&T): $2.00/MB
OCS_Obj.SendData({
'method': 'ApierV2.SetTPRate',
'params': [{
"TPid": tpid,
"ID": "Rate_Data_Roaming_US_Premium",
"RateSlots": [{
"ConnectFee": 0,
"Rate": 2.00,
"RateUnit": "1048576", # 1 MB in bytes
"RateIncrement": "1024", # Per KB
"GroupIntervalStart": "0s"
}]
}]
})
Rate Slot Fields:
- ConnectFee - One-time charge per session
- Rate - Cost per RateUnit
- RateUnit - Billing unit size (60s, 1MB, 1 message)
- RateIncrement - Minimum chargeable unit
- GroupIntervalStart - When this rate tier starts
Linking Destinations to Rates
After defining rates, link them to destinations using DestinationRates:
# Link Domestic destination to Domestic voice rate
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestinationRate',
'params': [{
"TPid": tpid,
"ID": "DR_Voice_Domestic",
"DestinationRates": [{
"DestinationId": "Dest_Domestic_All",
"RateId": "Rate_Voice_Domestic",
"RoundingMethod": "*up",
"RoundingDecimals": 4
}]
}]
})
# Link UK destination to UK voice rate
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestinationRate',
'params': [{
"TPid": tpid,
"ID": "DR_Voice_UK",
"DestinationRates": [{
"DestinationId": "Dest_International_UK",
"RateId": "Rate_Voice_UK",
"RoundingMethod": "*up",
"RoundingDecimals": 4
}]
}]
})
# Link Verizon PLMN to roaming data rate
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestinationRate',
'params': [{
"TPid": tpid,
"ID": "DR_Data_Roaming_US_Premium",
"DestinationRates": [{
"DestinationId": "Dest_PLMN_US_Verizon",
"RateId": "Rate_Data_Roaming_US_Premium",
"RoundingMethod": "*up",
"RoundingDecimals": 4
}]
}]
})
Creating the Rating Plan
Combine all DestinationRates into a RatingPlan:
OCS_Obj.SendData({
'method': 'ApierV2.SetTPRatingPlan',
'params': [{
"TPid": tpid,
"ID": "RatingPlan_Standard_PAYG",
"RatingPlanBindings": [
# Voice rates (higher weight = more specific)
{"DestinationRatesId": "DR_Voice_UK", "TimingId": "*any", "Weight": 40},
{"DestinationRatesId": "DR_Voice_Domestic", "TimingId": "*any", "Weight": 20},
# SMS rates
{"DestinationRatesId": "DR_SMS_Domestic", "TimingId": "*any", "Weight": 20},
# Data roaming rates
{"DestinationRatesId": "DR_Data_Roaming_US_Premium", "TimingId": "*any", "Weight": 50}
]
}]
})
Loading the Tariff Plan
Finally, load the tariff plan into CGRateS:
# Load tariff plan
OCS_Obj.SendData({
'method': 'ApierV1.LoadTariffPlanFromStorDb',
'params': [{
"TPid": tpid,
"DryRun": False,
"Validate": True
}]
})
# Reload cache
OCS_Obj.SendData({
'method': 'CacheSv1.ReloadCache',
'params': [{
"Tenant": tenant,
"DestinationIDs": ["*all"]
}]
})
See also:
- Defining Products - Complete workflow for creating products
- CGRateS Actions and Topup Behaviors - How to define Actions and balance management approaches
Best Practices
1. Be Specific with On-Net
# Good - specific home network
"DestinationIDs": "Dest_PLMN_OnNet", # mcc505.mnc057
# Bad - too broad, matches competitors
"DestinationIDs": "Dest_PLMN_AU_All", # mcc505 (all AU operators)
2. Use Meaningful Destination Names
# Good - self-documenting
Dest_PLMN_US_Verizon
Dest_International_UK
Dest_PLMN_Zone_Europe
# Bad - unclear
Dest_Data_1
Dest_Voice_Package
3. Group Related Destinations Logically
# Good - logical grouping
Dest_Domestic_All
Dest_Domestic_TollFree
Dest_Domestic_Premium
# Bad - too granular
Dest_Area_Code_212
Dest_Area_Code_213
Dest_Area_Code_214
4. Document PLMN Sources
When defining PLMN destinations, add comments indicating where the MCC/MNC codes came from:
# Verizon Wireless
# Source: https://www.mcc-mnc.com/ (verified 2024-12)
OCS_Obj.SendData({
'method': 'ApierV2.SetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_US_Verizon",
"Prefixes": [
"mcc310.mnc004", # Verizon - Nationwide
"mcc310.mnc010", # Verizon - East
...
]
}]
})
Troubleshooting
Issue: Balance Not Matching Destination
Symptom: Customer has balance but can't use it for specific destination
Check:
# 1. Verify destination exists
OCS_Obj.SendData({
'method': 'ApierV2.GetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_US_Verizon"
}]
})
# 2. Check balance DestinationIDs field
# Ensure it includes the destination or "*any"
# 3. For PLMN: Verify customer is actually on that network
# Check Diameter CCR messages for Visited-PLMN-Id AVP
Issue: Data Usage Counted as Roaming
Symptom: Domestic data usage consuming roaming balance instead of on-net balance
Cause: Customer's PLMN not defined in Dest_PLMN_OnNet
Solution:
# Check which PLMN customer is on (from Diameter CCR)
# Verify balance includes that PLMN:
OCS_Obj.SendData({
'method': 'ApierV2.GetTPDestination',
'params': [{
"TPid": tpid,
"ID": "Dest_PLMN_OnNet"
}]
})
# Ensure Prefixes includes customer's actual network PLMN
# Example: ["mcc505.mnc057"] must match customer's SIM network
Issue: International Calls Not Working
Symptom: Customer has "international minutes" but calls fail
Check:
- Destination prefix: Does dialed number match destination prefix?
- Calling +44-20-xxxx → Needs destination with prefix "44"
- Balance DestinationIDs: Does balance include that destination?
- Check balance has
"DestinationIDs": "Dest_International_UK"or"Dest_International_All"
- Check balance has
- Balance not expired: Check
ExpiryTime - Balance has units: Check
Units > 0
Related Documentation
- CGRateS Actions and Topup Behaviors - How to use destinations in Actions, balance approaches, and rating strategies
- Defining Products - Complete product creation workflow