DEV Community

Cover image for When Billing and Provisioning Disagree: The State Problem Inside MVNO Platforms
TelcoEdge Inc.
TelcoEdge Inc.

Posted on

When Billing and Provisioning Disagree: The State Problem Inside MVNO Platforms

A subscriber buys a new data add-on. The payment succeeds. Billing records the purchase. The customer receives a confirmation.

But the network never enables the data.

From the billing system's point of view, the transaction is complete. From the provisioning system's point of view, nothing happened. From the customer's point of view, the operator has taken the money and failed to deliver the service.

This is one of the most difficult problems inside an MVNO platform because a subscriber does not exist in one system state.

The billing platform knows one version of the subscriber. The network knows another. The CRM may hold a third. The payment system has its own transaction state, while the provisioning layer may still be waiting for a response from an external carrier system.

When everything works, these systems appear to behave like one platform.

When something fails halfway through, the differences become visible very quickly.

A Subscriber Is Really a Distributed State

Most subscriber actions look simple from the outside.

Activating a SIM, changing a plan, purchasing an add-on, suspending a line, or porting a number may appear to be a single action. Inside the platform, however, each of these actions can involve several independent systems.

A plan change, for example, may require the customer account to be updated, billing rules to change, new entitlements to be created, network provisioning to complete, and the customer-facing application to display the new plan.

The difficulty is that these systems do not all update at the same time.

Billing may complete in milliseconds. A carrier provisioning request may take several seconds. An external network interface may time out. An event may sit briefly in a queue. One service may restart while another continues processing.

For a short period, different parts of the platform may hold different versions of the truth.

That is not necessarily a failure.

The real problem begins when the platform cannot detect that the states have diverged or does not know how to bring them back together.

The Database Transaction Ends Before the Telecom Transaction Does

In a traditional application, developers often rely on database transactions to protect consistency.

A group of related changes either succeeds together or rolls back together.

Telecom workflows rarely fit inside that boundary.

Consider a subscriber purchasing a roaming add-on. The platform may first create the order, authorize the payment, update the billing account, send a provisioning request, wait for a carrier response, update the subscriber entitlements, and finally notify the customer.

There is no single database transaction covering all of this.

The payment provider is external. The carrier interface is external. Billing and provisioning may use different databases. Notifications may be asynchronous.

Once money has been captured, a simple rollback may no longer be possible. Once the network has enabled a service, deleting a database row does not disable that service again.

The application transaction and the telecom transaction are not the same thing.

This is where platform architecture becomes more important than a successful API response.

A 200 OK Does Not Mean the Workflow Is Complete

One of the most dangerous assumptions in distributed telecom systems is treating an API response as proof that the entire business process has succeeded.

Imagine that the billing service accepts a plan change and returns a successful response.

That response only confirms what the billing service knows.

It does not automatically prove that the network has applied the new entitlement. It does not prove that the SIM profile is correct. It does not prove that every downstream system has received the change.

The same problem works in reverse.

The provisioning system may successfully activate a service, but the confirmation event may fail before reaching billing. The subscriber now has network access while the commercial system still believes the service is inactive.

Neither system is necessarily broken.

They simply disagree.

A reliable MVNO platform therefore needs to understand the difference between request accepted, processing started, network confirmed, and business workflow completed.

Collapsing all of those states into a single success value makes the API simpler, but it makes operations much harder.

Partial Failure Is the Normal Failure Mode

Complete failures are usually easier to handle.

If nothing happens, the platform can often retry the request.

Partial failures are more dangerous because some work has already been completed.

A subscriber activation may successfully create the customer account and charge the first payment before provisioning fails. A plan change may reach the network but fail before billing records the new product. A suspension request may update the BSS while the carrier interface is unavailable.

Now the platform cannot simply start again from the beginning.

Repeating the entire workflow could create a duplicate payment, send the same provisioning instruction twice, or overwrite a state that has already changed.

The platform first needs to understand how far the original workflow progressed.

This is why serious telecom workflows need explicit states rather than a simple success-or-failure flag.

An activation may move through states such as requested, validated, payment confirmed, provisioning pending, network confirmed, and active.

If the process stops, the platform knows where it stopped.

Without that visibility, recovery becomes guesswork.

Retries Can Fix a Failure or Create a Second One

Retries are essential in distributed systems.

They are also one of the easiest ways to make a telecom incident worse.

Suppose the platform sends an activation request to a carrier. The carrier processes it successfully, but the response is lost because the connection times out.

The MVNO platform sees a timeout.

The network sees an active subscriber.

If the platform blindly retries, the carrier may receive the same activation request again.

Whether that retry is safe depends on how the integration was designed.

This is where idempotency becomes critical.

The same logical request should be identifiable across retries. If an activation with the same operation identifier has already been completed, the platform should return the existing result rather than performing the action again.

But idempotency alone does not solve every state problem.

Some external carrier interfaces do not support idempotency keys. Some legacy systems provide weak transaction identifiers. Some operations cannot simply be repeated safely.

In those cases, the platform needs another layer of protection: checking current state before retrying, storing operation history, correlating external references, and reconciling the final result after uncertainty.

A retry strategy cannot be reduced to "try three times and send it to a dead-letter queue."

The business effect of the operation matters.

Billing and Provisioning Need a Shared Understanding of State

Billing and provisioning do not need to use the same database.

They do need to agree on what subscriber states mean.

If billing defines a customer as active immediately after payment while provisioning defines active only after network confirmation, the platform already has a semantic problem.

The disagreement may remain invisible until something fails.

A better design makes state transitions explicit.

Billing can know that the commercial order is confirmed while the overall service remains pending activation. Provisioning can publish a network confirmation event when the carrier completes the request. Only then does the platform move the service into a fully active state.

This sounds straightforward, but it requires discipline.

Services must publish meaningful events. Consumers must process them reliably. Duplicate events must not create duplicate actions. Failed messages need recovery paths. State changes need timestamps and correlation identifiers.

Most importantly, teams need to stop designing each service as if it were the only system responsible for the subscriber.

It is not.

Event-Driven Architecture Helps, but It Does Not Remove the Problem

Event-driven architecture is often presented as the solution to tightly coupled telecom systems.

It certainly helps.

Billing can publish a PlanChangeConfirmed event without needing direct knowledge of every downstream consumer. Provisioning can react to that event. Analytics can record it. Notifications can inform the subscriber.

The services remain loosely coupled.

But moving communication to an event bus does not automatically create consistency.

Events can arrive twice.

They can arrive late.

Two related events can arrive in an unexpected order.

A consumer can process an event successfully and crash before recording that it was processed.

A service can publish an event while another system is temporarily unavailable.

The architecture therefore needs to assume that delivery is imperfect.

Consumers should be able to process duplicates safely. Events should carry enough context to be traced. State transitions should reject impossible changes. Reconciliation processes should identify workflows that remain incomplete for too long.

Event-driven systems reduce direct dependencies.

They do not remove the need to reason carefully about state.

The Platform Needs to Know When It Is Uncertain

Many systems are designed around two states: success and failure.

Distributed telecom operations often need a third.

Unknown.

A timeout does not always mean failure.

If the platform sends a request to a carrier and receives no response, it may not know whether the carrier rejected the request, never received it, or completed it successfully before the connection disappeared.

Marking the operation as failed may be wrong.

Marking it as successful may also be wrong.

The correct system state may be unknown, verification required.

That state should trigger a different recovery path.

The platform may query the external system, wait for a callback, inspect a later event, or send the workflow to reconciliation.

Treating uncertainty as a first-class state is important because false certainty creates some of the hardest operational incidents.

The platform should not claim to know more than the underlying systems can prove.

Reconciliation Is Not Just a Finance Process

In many telecom environments, reconciliation is associated with invoices and month-end finance operations.

Architecturally, reconciliation is much broader.

It is the process of asking whether systems that should eventually agree actually agree.

Does every subscriber marked active in billing have an active network service? Does every paid add-on have a corresponding entitlement? Does every completed port have the correct number assignment? Does every suspended account have the expected network status? Does every carrier-side activation map back to a valid commercial order?

These checks are not evidence of bad architecture.

They are part of operating distributed systems responsibly.

Real-time processing reduces the delay between events, but it does not eliminate the possibility of divergence. Reconciliation provides a second line of defense when normal workflows fail silently.

The difference between a mature platform and a fragile one is often not whether inconsistencies ever occur.

It is how quickly the platform finds them and how safely it recovers.

Observability Must Follow the Subscriber Journey

Infrastructure monitoring can show that every service is running.

That does not mean the subscriber journey completed.

The API gateway may be healthy. Billing may have normal latency. The event broker may be online. Provisioning workers may be processing requests.

A specific subscriber can still be stuck between systems.

This is why telecom observability needs business context.

Engineers should be able to trace one operation across the entire workflow using a shared correlation identifier. A plan change should be traceable from the original API request through billing, event processing, provisioning, the carrier response, and the final subscriber state.

Without that context, teams end up searching several dashboards and databases to answer one basic question:

What happened to this subscriber?

Good observability does not only show service health.

It shows the state of the business process moving through those services.

The Real Goal Is Controlled Consistency

Perfect, immediate consistency across every telecom system is rarely realistic.

External networks have their own response times. Payment systems have independent transaction models. Distributed services fail in different ways.

The goal is not to pretend these differences do not exist.

The goal is to control them.

A well-designed MVNO platform knows which operations require immediate consistency, which can tolerate eventual consistency, which states are temporary, and which mismatches require intervention.

It records enough information to reconstruct what happened.

It treats retries as business operations rather than generic infrastructure behavior.

It recognizes uncertainty.

It continuously checks whether systems that should agree have actually converged.

That is what makes a distributed telecom platform reliable.

Final Thoughts

Billing and provisioning will not always update at exactly the same moment.

That is not the real problem.

The problem is building a platform that assumes they always will.

Modern MVNO systems depend on APIs, asynchronous events, external carrier interfaces, payment providers, and independently deployed services. Partial failure is unavoidable in that environment.

The architecture therefore needs to be designed around disagreement.

It needs explicit states, traceable workflows, safe retries, meaningful events, reconciliation, and a clear way to represent uncertainty.

When billing says a subscriber is active and the network says otherwise, the platform should not need an operations team searching five systems to discover what happened.

It should already know that the states disagree.

And it should know what happens next.

Top comments (0)