Table of Contents
- Introduction
- Onboarding as a DOME Service Provider with did:web
- What will I accomplish following this section?
- Pre-requisites
- Install and configure Keycloack as a Verifiable Credential Issuer
- Configure the Credential type and the Claims in the Issuer
- Issue and receive the Verifiable Credential in your Wallet
- Login to the DOME BAE Marketplace instance
- Create a Product Offering in the DOME BAE Marketplace instance
- Logoff from the DOME BAE Marketplace instance
- Distributed components
- Authentication
- Integration API (TMForum)
- Integration of an external Billing Engine in DOME
- Policies
This guide provides detailed, self-contained and actionable technical instructions for integrating and federating a marketplace in DOME.
It is meant to be the reference for what is currently technically available and ready to be used. When additional functionality, components and/or
instruction get available, this guide will be adapted accordingly.
This guide limits on the technical details and therefore is not providing any details about contractual and business aspects of the marketplace integration and federation.
This guide aims for future participants willing to technically integrate and federate a marketplace in DOME. Descriptions and instructions are given as a comprehensive, step-by-step guide in such detail, so that IT and engineering teams can successfully and efficiently perform the necessary steps without profound knowledge of the DOME implementation details.
Nevertheless, this guide focusses on the actual integration of a marketplace in DOME, providing only the information needed to perform the actual setup for integration and federation. More details and in-depth knowledge about DOME and its involved components can be found in the linked resources.
The suggested deployment target infrastructure is Kubernetes. Therefore a sufficient
knowledge of Kubernetes and Helm is expected when following this guide. Knowledge about
ArgoCD is also helpful when using it as GitOps
continuous delivery tool.
This guide requires access to a domain and it's DNS settings, as well as configuring proper certificates.
Therefore also knowledge about cert-manager
and external-dns is recommended.
Authentication requires usage of decentralized identifiers and verifiable credentials, which requires an
appropriate configuration of the related components. Therefore, the reader of this guide should be
familiar with DIDs and VC/VP standards.
Cloud computing is identified as a central piece of Europe’s digital future, giving European businesses and public organisations the data processing technology required to support their digital transformation. The European Commission thereby stepped up its efforts to support cloud uptake in Europe as part of its strategy, notably with the pledge to facilitate "the set-up of a cloud services marketplace for EU users from the private and public sector". DOME is materialising the envisioned online marketplace, providing the means for accessing trusted services, notably cloud and edge services, building blocks deployed under the Common Services Platform and more generally any software and data processing services developed under EU programmes such as the Digital Europe Programme, Horizon 2020 or Horizon Europe.
Relying on Gaia-X concepts and open standards, DOME is providing the finishing touch to the technical building that the Digital Europe Program is creating for boosting the development and adoption of trusted Cloud and Edge services in Europe. It will provide the single point for enabling customers and service providers to meet each other in a trustful manner. DOME is taking the form of a federated collection of marketplaces connected to a shared digital catalogue of cloud and edge services. Each of the federated marketplaces will be independent or connected to the offering of a given cloud/edge infrastructure service provider which, in turn, can be classified as cloud IaaS providers or cloud platform service providers (each of which provide a platform targeted to solve the integration of vertical data/application services from a given vertical domain, like smart cities or smart farming, or the integration of certain type of data/application services, e.g., AI services). DOME is relying on the adoption of common open standards for the description and the management of the lifecycle of cloud and edge service products and offerings around those products, as well as their access or match-making services through a shared catalogue.
After following this guide, you will have a complete and functioning integration of a marketplace in a federated DOME environment.
The following sections provide details about the necessary steps:
- Onboarding: How to perform onboarding as DOME participant (Note, that this topic is currently under discussion and details will be added later).
- Distributed components: How to configure, deploy and operate the different required components. This involves the access node and components required for the IAM.
- Authentication: How to authenticate at services and how to implement the authentication.
- Integration API: How to integrate with the TMForum APIs, especially when using an own marketplace implementation instead of the BAE. Some samples and tutorials are given for core federation scenarios.
- Policies: How access policies are defined, created and enforced (Note, that this topic is currently under discussion and details will be added later).
There are some prerequisites that need to be fulfilled before following this guide:
- Domain: You need control over an own domain and have access to the DNS settings.
- Public access: Certain components need to be publicly accessible under your own domain. Therefore, a suitable infrastructure (like a cloud-hosted Kubernetes cluster) is required for running the components.
Additional prerequisites are provided in the different sections.
We describe here the onboarding process using Verifiable Credentials with the did:web DID method. In production (June 2024) the process will use did:elsi and eIDAS certificates, but this process will be finished in the coming weeks, so for the moment the users will be able to test onboarding and creation of Product Offerings and replication to other marketplaces, even if the actions do not have yet the legal coverage that did:elsi provides.
The user will be able to login with her Wallet in the DOME BAE Marketplace instance (the one operated at this moment by the DOME project) as a Service Provider with a unique identity determined by the domain (e.g., www.in2.es) used when generating the Verifiable Credential used to login to the BAE Marketplace.
Once logged-in, the user will be able to test the creation of a Product Offering using the screens of the DOME BAE Marketplace instance, and publish the Product Offering in the marketplace. The Product Offering will be replicated to all other federated marketplaces connected to the main DOME Marketplace instance.
All Product Offerings and related entities created under this identity will be separated from the other entities created by other identities.
This scenario uses the did:web DID Method, so you need control over a domain and have access to the DNS settings.
Before continuing, you have to create your DID, following the instructions in the section Create (Register) of the did:web specification.
You need to be able to issue a Verifiable Credential to a Wallet, using the DOME format and with the did:web method. There are different possibilities, but the easiest one which ensures compatibility with the current status of the OID4SSI implementation in DOME is to use the Wallet and Issuer provided by DOME.
Wallet: in order to use the Wallet provided by DOME, you do not have to install anything. Just visit with your mobile the URL: https://demo-wallet.fiware.dev/
Issuer: the Issuer is a little bit more involved. Before June, DOME will provide an Issuer acting As-a-Service (for those willing to use it), but for the moment you have to install and operate an instance the Issuer yourself.
The instructions to install and configure the Issuer (which is based on Keycloack) are here: Keycloack VC-Issuer. For a simple installation, the repo includes a containerised deployment so you only have to configure the Issuer with your specific information.
The Wallet should be able to access the relevant endpoints exposed by the Issuer, as described in the instrucions mentioned above.
Follow the instructions in Configure claims for Credential-Types to configure your Issuer for issuance of the Credential required for DOME.
Follow the instructions in section Demo to make Keycloack issue a QR code that can be scanned by your Wallet (remember that your Wallet is at https://demo-wallet.fiware.dev/).
Once you scan the QR code and complete the issuance process, you will have in your Wallet the required credentials to login in the DOME BAE Marketplace.
At this moment, you have in your mobile the credentials required to login to the DOME BAE Marketplace instance with a unique identity associated to your unique domain. Even though this credential does not have the level of legal certainty required for production use, it will allow you to test the features that the DOME BAE Marketplace instance provides to Service Providers.
TODO: add instructions to login to the DOME BAE Marketplace instance.
Once logged in, you are logged as a Service Provider with a unique identity associated to your unique domain. You can start creating Product Offerings and publishing them. The action of publishing the Product Offernings will make them visible to potential customers in the DOME BAE Marketplace instance and all other federated marketplaces which are connected to the DOME main instance.
TODO: add instructions to create and publish Product Offerings.
Once you have finished interacting with the DOME BAE Marketplace instance, you can logoff from it. In case of inactivity, the BAE Marketplace will log you off automatically.
Using your Wallet, you can login at any moment and continue working with the DOME BAE Marketplace. The Wallet has your credentials stored in your device and you can use them at any moment.
Components that need to be operated by a federated participant.
The DOME Access-Node is a set of services for the integration with the DOME Marketplace. A registered participant can use it to act as a federated marketplace in DOME.
The Access-Nodes consists of 3 logical componentes:
The TM-Forum-API Service is a service providing a growing subset of the TMForum API's while using an NGSI-LD context broker as persistence backend and change notificator.
graph TD
;
TM-Forum-API --> Context-Broker;
Context-Broker --> Persistence;
The Blockchain Connector is a software component that facilitates the interaction between the Off-Chain Storage (Context Broker) and the On-Chain Storage (Blockchain). It is composed of the Distributed Ledger Technology (DLT) and the Access Node.
The TM-Forum-API service is a cluster of individual services providing one specific API each, enabling the participant to only run the necessary subset for its use-case. Apart from offering CRUD operations on the managed entities, the service also enables the subscription to notifications based on given queries.
The services are stateless and support horizontal scaling, but require an external cache to avoid having inconsistent caches. Inconsistent caches can result from either changes due to calls to the API, or due to notifications for changes reported by the underlying persistence. If run in a single instance mode, a local cache is acceptable but for larger setups a Redis installation is recommended.
For reasons of convenience, the TM-Forum-API service can be deploying with an Envoy API proxy which provides the individual APIs via a single service, routed based on the path. Another convenient feature is a RapiDoc container, that can be deployed with the TM-Forum-API service that provides a Openapi based API documentation for the deployed services, with the functionality of querying the API too.
The requirement for the persistence is to be compliant to the NGSI-LD API v1.6 enabling the use of different available context brokers. The currently recommended Context-Broker for the access node is Scorpio, mainly due to good cloud integration and overall support. The Scorpio context-broker allows a variety of adjustments to cover the operator's specific needs ( e.g. horizontal scaling utilizing Kafka) and uses Postgresql as it's persistence layer. The Postgresql is extended with Postgis for supporting geospatial data.
The base memory consumption per deployed pod is listed below but is will increase with the amount of traffic, therefor should only be used as a rough estimate.
| Service | Memory (Mi) |
|---|---|
| TM Forum API | 250 |
| NGSI-LD Context Broker (Scorpio) | 400 |
| Persistance Layer (Postgres/Postgis) | 150 |
| External Cache (Redis) | 10 |
Apart from the database service, no other service will maintain a own persistence, therefor only for this service a persistent volume claim has to be dimensioned.
Please follow the instructions in DOME Access-Node | How to deploy.
A configuration file is provided with default values, but you have to complete with your own values following the DOME Access-Node | How to deploy guide.
The values you have to complete are:
| Key | Sample Value | Description |
|---|---|---|
| access-node. desmos. app. operator. organizationIdentifier (line 37) | did:elsi:VATFR-696240139 | DID of the operator in the format did:elsi:VAT{VAT_NUMBER}. VAT_NUMBER is the VAT idetification number of the organization. |
| access-node. desmos. app. privateKey (line 76) | 0x15aa33a07f6680d1bb3e75 24ea3f6ce6ba0eb39a3efa14 6c3d84a0487505d9f8 | Private key of the operator to sign JWT. Alternatively, you can add it as a sealed secret. |
| access-node. dlt-adapter. env. PRIVATE_KEY (line 123) | 0x4c88c1c84e65e82b9ed6b4 9313c6a624d58b2b11e40b4b 64e3b9d0a1d5e4dfajE | Private key of the operator in the Alastria Red-T Blockchain to sign transactions. Alternatively, you can add it as a sealed secret. |
| access-node. dlt-adapter. env. ISS (line 126) | 0xb34dcb3fcccc37d89a4742 617eef81d0920cbd2e0204ce ea2bb3ddd1f8b85876 |
If you want to update the default values, please refer to the How to configure section.
- Add the DOME Helm Chart Repository to your helm installation
helm repo add dome-access-node https://dome-marketplace.github.io/access-node
helm repo update
💡 All releases of the Access-Node reside in the helm-repository https://dome-marketplace.github.io/access-node. In addition to that, all Pre-Release versions(build from the Pull Requests) are provided in the pre-repo https://dome-marketplace.github.io/access-node/pre. The pre-repo will be cleaned-up from time to time, in order to keep the index manageable.
- Install the DOME Access Node
helm install access-node dome-access-node/access-node --namespace <NAMESPACE> -f config/accessnode.yaml
NAMESPACE: The Kubernetes Cluster namespace where the DOME Access Node will be deployed.
The Helm Chart will deploy the required pods:
The chart is released with a set of default values which act as a good starting point for an adoption. These values are also documented, enhancing the understanding. Additionally, the respective charts of the components should be consulted.
To have a starting point, the this minimal config reduces the configuration to items that are likely changed by integrators. Blockchain connector fields present int this file are:
| Key | Description | Default Values |
|---|---|---|
| access-node.desmos.app.profile | allows the environment filtering | test |
| access-node.desmos.app.operator.organizationIdentifier | did of the operator | did:elsi:VATES-S9999999E |
| access-node.desmos.app.broker.externalDomain | must be set since it is used by third parties to retrieve your data; it should be https | http://scorpio:9090 |
| access-node.desmos.app.db.host | host of the db | postgresql-connector |
| access-node.desmos.app.db.port | port of the host of the db | 5432 |
| access-node.desmos.app.db.externalService | should be true if is an external service | false |
| access-node.desmos.app.db.name | name of the db | mktdb |
| access-node.desmos.app.db.password | password to be used | postgres |
| access-node.desmos.app.db.username | username to be used | postgres |
| access-node.desmos.app.db.existingSecret.enabled | should an existing secret be used | false |
| access-node.desmos.app.db.existingSecret.name | name of the secret | desmos-api-secret |
| access-node.desmos.app.db.existingSecret.key | key to retrieve the password from | desmos-db-password |
| access-node.dlt-adapter.env.PRIVATE_KEY | private key to sign transactions | 0xe2afef2c880b138d741995ba56936e389b0b5dd2943e21e4363cc70d81c89346 |
| access-node.dlt-adapter.env.RPC_ADDRESS | node address | https://red-t.alastria.io/v0/9461d9f4292b41230527d57ee90652a6 |
| access-node.dlt-adapter.env.ISS | organization identifier hashed with SHA-256 | 0x43b27fef24cfe8a0b797ed8a36de2884f9963c0c2a0da640e3ec7ad6cd0c493d |
| access-node.postgresql.auth.username | username to be used | postgres |
| access-node.postgresql.auth.password | password to be used | postgres |
Fields to clarify in the original config:
| Key | Comment | Default Values |
|---|---|---|
| access-node.desmos.app.ngsiSubscription.entityTypes | this list ensures that you can work with all type of entities | catalog,product-offering,category,individual,organization,product,service-specification,product-offering-price,resource-specification,product-specification |
| access-node.desmos.app.txSubscription.entityTypes | this list ensures that you can work with all type of entities | catalog,product-offering,category,individual,organization,product,service-specification,product-offering-price,resource-specification,product-specification |
The Blockchain Connector uses the dev, test and prod configuration profiles. On the other hand, DOME uses the profile names sbx, dev and prd. It is important that users use the profile names used by the Blockchain Connector (dev, test, prod), since the application is responsible for carrying out the necessary correspondence and mapping between the profile names of the Blockchain Connector and those of DOME automatically.
The DLT-Adapter is automatically deactivated when it detects that Desmos is down.
Table to clarify the relation between the desmos-api profiles and the DOME-Gitops environments:
| desmos-api profiles | DOME-Gitops environments |
|---|---|
| dev | sbx |
| test | dev |
| prod | prd |
While secrets can be configured via plain helm/k8s entities, another more secure approach is to use Sealed Secrets. To configure custom secrets you have to follow the next steps:
- Create a Plain Secret Manifest File:
- Create a plain secret manifest file named
<secret name>-plain-secret.yaml. - IMPORTANT: Add "*-plain-secret.yaml" to .gitignore file to not push plain secret data to the repository.
apiVersion: v1
kind: Secret
metadata:
name: <secret name>
namespace: <app namespace>
data:
<secret_key>: <base64 encoded value>- Seal the secret:
- Seal the secret by executing the following command:
kubeseal -f <secret name>-plain-secret.yaml -w <secret name>-sealed-secret.yaml --controller-namespace sealed-secrets --controller-name sealed-secrets- Apply the secret configuration:
- Apply the sealed secret configuration to the cluster by running the command:
kubectl apply -f <secret name>-sealed-secret.yaml- Update the Chart Values:
- In the chart values.yaml file, modify the existingSecret section as follows:
existingSecret:
enabled: true
name: <secret name>
key: <secret_key>All components are configured with health and readiness checks to validate their own status, therefor being the base for a validation. These checks are utilized in the kubernetes checks as defined in the helm charts.
TODO: Include RapiDoc Container for validation and add explanation here
- Management/admin APIs.
- Instrumentation, metrics, logs, alerts
The underlying database service holds the persisted data and therefor requires a backup&recovery mechanism when operated in a production environment. The use of managed database is strongly encouraged for safety and convenience.
The TM-Forum-API service used a json based log output by default, which can be parsed easily by log aggregators but can also be replaced if needed. The verbosity is controlled via environment variables and can be fine tuned to the operators needs.
We need to implement Grafana dashboards but for the moment the access node publishes metrics for Prometheus by default in "/actuator/prometheus".
Upgrade to both a different chart version and new configuration can be accomplished with the following command
helm upgrade <RELEASE_NAME> dome-access-node/access-node --namespace <NAME_SPACE> --version <CHART_VERSION> -f values.yaml
Versioning of the main access-node helm chart is handled based on the labels used in the pull requests used to introduce changes and is enforced in the build pipeline. The requester and reviewers must set the label according to the SemVer 2.0.0 versioning scheme.
Versioning of the components and sub-charts is recommended to use the same scheme.
Versioning, release notes, stability considerations
To be filled once feedback from integrators comes in
When encountering timeouts in calls to the TM-Forum-API service it is possible to mitigate the imminent issue by increasing the timeout of the client (called "ngsi") calling the NGSI-LD broker. The necessary client and server configuration can be handed in via additional environment variables.
The DOME IAM-Framework is a set of microservices, that enables users in the DOME ecosystem to authenticate into the DOME Marketplace. The authentication process itself is described further below in the Authentication section.
The DOME IAM-Framework consists of multiple open-source components. The components are not required to be used, as long as alternatives providing the same interfaces are used.
The IAM-Framework consists of following components:
- The Trusted Issuers List service provides an EBSI Trusted Issuers Registry implementation to act as the Trusted-List-Service in the DSBA Trust and IAM Framework. In addition, a Trusted-Issuers-List API is provided to manage the issuers.
- VCVerifier provides the necessary endpoints to offer SIOP-2/OIDC4VP compliant authentication flows. It exchanges VerifiableCredentials for JWT, that can be used for authorization and authentication in down-stream components.
- Credentials Config Service manages and provides information about services and the credentials they are using. It returns the scope to be requested from the wallet per service. Furthermore, it specifies the credentials required and the issuers list endpoints to validate against, when checking access for a certain service.
- The Keycloak-VC-Issuer is plugin for Keycloak to support SIOP-2/OIDC4VP clients and issue VerifiableCredentials through the OIDC4VCI-Protocol to compliant wallets.
- PDP is an implementation of a Policy-Decision Point, evaluating Json-Web-Tokens containing VerifiableCredentials in a DSBA-compliant way. It also supports the evaluation in the context of i4Trust.
- Keyrock is the FIWARE component responsible for Identity Management. Within DOME IAM-Framework, currently Keyrock is being used as the iSHARE-compliant Authorization Registry (see for details: https://dev.ishare.eu/delegation/endpoint.html), where attribute-based access policies are stored and used during the authorization process. Note, that this will be replaced by an ODRL-compliant policy registry. A description of the policies is given in the policies section.
- Kong Plugins allow to extend the API Gateway Kong by further functionalities. Kong Gateway is a lightweight, fast, and flexible cloud-native API gateway. One of the plugins is the PEP plugin, which is especially required within the IAM-components as PEP component and interacts with the PDP mentioned above.
- Waltid manages Keys, DIDs and VCs. It is used by VC Issuer and VCVerifier.
The recommended way of deployment is via the provided Helm charts.
To deploy a setup, the umbrella chart of the iam-components can be used as followed:
-
create a configuration values file according to the own environment, as described here.
-
add helm chart repository to helm installation
helm repo add dome-iam https://dome-marketplace.github.io/iam-components helm repo update💡 All releases of the IAM-components reside in the helm-repository https://dome-marketplace.github.io/iam-components. In addition to that, all Pre-Release versions(build from the Pull Requests) are provided in the pre-repo https://dome-marketplace.github.io/iam-components/pre. The pre-repo will be cleaned-up from time to time, in order to keep the index manageable.
-
install the components using the prepared configuration
helm install <RELEASE_NAME> dome-iam/iam-components --namespace <NAME_SPACE> --version <CHART_VERSION> -f values.yaml
The chart is released with a set of documented default values. The parameters listed below are important to set and should be updated at least:
rbacandserviceAccount: Depending on your requirements, you might need to adapt settings for RBAC and service accountdids of participants: Replace/add the DIDs of the issuer and other participants- In the case of did:key provide correct key in keyfile.json for your issuer
keycloak.frontendUrl: Externally accessible address of the keycloak (should be the same as defined in ingress/route)keycloak.realm: Adapt clients, users and roles according to your needs<tir.com>: replace everywhere with actual TIR URL<dome-marketplace.org>: replace with your own domainkeyrock.initData.scriptData: Adapt the roles as in keycloak realmkong.configMap: Adapt the kong services and their routes
However, it is suggested to consult the respective charts listed below and check their documentation and configuration.
To have a starting point, you can use this values file as a minimal config.
All components are configured with health and readiness checks to validate their own status, therefore being the base for a validation. These checks are utilized in the Kubernetes checks as defined in the helm charts.
The underlying database service holds the persisted data and therefore requires a backup&recovery mechanism when operated in a production environment. The use of managed database is strongly encouraged for safety and convenience.
Upgrade to both a different chart version and new configuration can be accomplished with the following command
helm upgrade <RELEASE_NAME> dome-iam/iam-components --namespace <NAME_SPACE> --version <CHART_VERSION> -f values.yaml
Versioning of the main iam-components helm chart is handled based on the labels used in the pull requests used to introduce changes and is enforced in the build pipeline. The requester and reviewers must set the label according to the SemVer 2.0.0 versioning scheme.
Versioning of the components and sub-charts is recommended to use the same scheme.
To be filled once feedback from integrators comes in
A description of the authentication process can be found in the iam-guide.
When working with the TMForum data models, most of the entities created include information about the parties that are related to them. This includes, thought it is not limited to, the owner, customers, etc.
All the organizations onboarded in DOME should have a Party object, created during the onboarding, that can be retrieved using the TMForum Party Management API.
The Party object of a particular organization can be retrieved quering the Party API, using the Organization ID provided in the mandator of the Verifiable Credential.
GET [Party API Endpoint]/organization?externalReference.name=[VC Org ID]
[{
{
"id": "urn:ngsi-ld:organization:58e41694-594c-42e1-bff9-b249984e42e1",
"href": "urn:ngsi-ld:organization:58e41694-594c-42e1-bff9-b249984e42e1",
"tradingName": "Test Org, S.L",
"externalReference": [
{
"externalReferenceType": "idm_id",
"name": "VATES-B12341234"
}
]
}
}]
Knowing the ID of the Party object is quite relevant as will be needed to create any other entity in the TMForum APIs
DOME allows Service Providers to define their custom Product Categories in addition to the ones provided by the DOME Marketplace. These Product Categories are created as part of the TMForum Product Catalog Management API and are attached to the Service Provider Product Catalog. For a complete reference of the Product Catalog Management API, please refer to the Swagger Doc.
The first step to define a set of categories is creating the Service Provider Product Catalog. This can be done via HTTP making the following POST request to the Product Catalog API
POST [Catalog API Endpoint]/catalog
{
"name": "Provider Catalog",
"description": "A Provider Product Catalog",
"lifecycleStatus": "active",
"relatedParty": [{
"id": "urn:ngsi-ld:organization:58e41694-594c-42e1-bff9-b249984e42e1",
"href": "urn:ngsi-ld:organization:58e41694-594c-42e1-bff9-b249984e42e1",
"role": "owner"
}],
"category": []
}
As part of the Product Catalog it must be included:
- name: A name for the Product Catalog
- description: A description for the Product Catalog
- lifecycleStatus: The status of the Product Catalog. When creating a new entity it should be set to active
- relatedParty: The parties related to the catalogue. At least the owner party must be included providing its ID and the owner role
Once the Product Catalog is ready, root categories can be created. Product Categories are created in the Product Catalog API using the following request:
POST [Catalog API Endpoint]/category
{
"name": "IaaS Service",
"description": "Products offering IaaS Services",
"lifecycleStatus": "active",
"isRoot": true,
}
Note that when creating a root category the isRoot attribute is set to true
New root categories can be attached to the provider catalog updating the category field using a PATCH request.
PATCH [Catalog API Endpoint]/catalog/[Catalog ID]
{
"category": [{
"id": "urn:ngsi-ld:product-category:58e41694-594c-42e1-bff9-b249984e42e1",
"href": "urn:ngsi-ld:product-category:58e41694-594c-42e1-bff9-b249984e42e1"
}]
}
Finally, children categories can be created using the parentId attribute to add the parent category ID and setting the isRoot attribute to false. These children categories doesn't need to be included in the service provider catalog, as they can be reached from its parents to build the whole category tree.
POST [Catalog API Endpoint]/category
{
"name": "Computing Service",
"description": "Products offering Computing Services",
"lifecycleStatus": "active",
"isRoot": false,
"parentId": "urn:ngsi-ld:product-category:58e41694-594c-42e1-bff9-b249984e42e1"
}
There are some considerations to be taken into account regarding the lifecycle status. As defined by TMForum model, the different product catalog elements can be discovered by potential customers when they are in launched state. In this regard, it is adviced to create the different entities in active state, allowing the provider to keep on making modifications before they are discovered.
In the particular case of the catalogue and the categories, it is adviced to keep them in active state until there is a Product Offering within it. This way, potential customers will not browse an empty category.
There are multiple filtering options that allow potential customers to browse the product offering catalog. The TMForum API defines a query language that allows to search by any of the fields included in the particular TMForum model using query params in a GET request.
In general, a query is defined with the following rules:
- The attribute from the TMForum model that is used as filter is provided as a query param of a GET request
- When the attribute value is a nested object, it is possible to query by nested attributes using dots
- Multiple attributes can be used at the same time using different query params, the query will be an AND
- Multiple values separated by comma can be used to create an OR query
- Results can be paged using the start and limit query params
The following is an example of a query retrieving all the Launched Product Offerings of a given provider
GET [Catalog API Endpoint]/productOffering?lifecycleStatus=launched&relatedParty.id=urn:ngsi-ld:organization:58e41694-594c-42e1-bff9-b249984e42e1
As described in the previous section, the different Product Offerings can be categorized using Product Categories. These categories can be used for filtering the results as any other field of the product offering.
The following is an example filtering offerings by category ID
GET [Catalog API Endpoint]/productOffering?category.id=urn:ngsi-ld:product-category:58e41694-594c-42e1-bff9-b249984e42e1
The following is an example filtering offerings by category name
GET [Catalog API Endpoint]/productOffering?category.name=PaaS
Note that the examples in this section are applied to the Product Catalog Management API; nevertheless, the same query mechanism is used in all the TMForum APIs
When dealing with product offerings, the TMForum data model splits the technical and business information in different entities that need to be created.
First of all, the different services and resources that made up the product to be published can be modeled as Service and Resource Specifications.
On the one hand, a Resource Specification defines a class of physical or digital resources that are needed by the offered services to operate. An example of Resource Specification could be physical storage, servers, virtual machines, etc. This model allows providers to provide all the needed information about their resources so they can be procured and instantiated, during the procurement phase, after a product offering is acquired.
Resource Specifications can be created using the Resource Catalog API, making a POST request as follows:
POST [Resource Catalog API Endpoint]/resourceSpecification
{
"name": "Processing Server",
"description": "A Server used by our services",
"lifecycleStatus": "active",
"relatedParty": [{
"id": "urn:ngsi-ld:organization:58e41694-594c-42e1-bff9-b249984e42e1",
"href": "urn:ngsi-ld:organization:58e41694-594c-42e1-bff9-b249984e42e1",
"role": "owner"
}],
"resourceSpecCharacteristic": [
{
"id": "urn:ngsi-ld:characteristic:58e41694-594c-42e1-bff9-b249984e42e1",
"name": "string",
"configurable": false,
"description": "string",
"valueType": "string",
"resourceSpecCharacteristicValue": [
{
"isDefault": true,
"rangeInterval": "string",
"regex": "string",
"unitOfMeasure": "string",
"valueType": "string",
"value": "string",
}
]
}
]
}
The TMForum API is defining the resourceSpecCharacteristic attribute. This attribute can be used to register any information
In addition, the configurable flag can be used to define a characteristic with multiple values. In that scennario, potential customers will be able to select the value they prefer, so the procurement system can instantiate the resources accordingly.
For a complete reference of all the available attributes and options, please refer to the Swagger file of the Resource Catalog API here
On the other hand, a Service Specification defines the different classes of services that can be offered as part of a product offering, so they can be procured and instantiated during the procurement phase.
Service specifications can be created using the Service Catalog Management API, making a POST request as follows:
POST [Service Catalog API Endpoint]/serviceSpecification
{
"name": "Computing Service",
"description": "A computing service offered in our cloud",
"lifecycleStatus": "active",
"relatedParty": [{
"id": "urn:ngsi-ld:organization:58e41694-594c-42e1-bff9-b249984e42e1",
"href": "urn:ngsi-ld:organization:58e41694-594c-42e1-bff9-b249984e42e1",
"role": "owner"
}],
"specCharacteristic": [
{
"id": "urn:ngsi-ld:characteristic:58e41694-594c-42e1-bff9-b249984e42e1",
"name": "string",
"configurable": false,
"description": "string",
"valueType": "string",
"characteristicValueSpecification": [
{
"isDefault": true,
"rangeInterval": "string",
"regex": "string",
"unitOfMeasure": "string",
"valueType": "string",
"value": "string",
}
]
}
]
}
For a complete reference of all the available attributes and options, please refer to the Swagger file of the Service Catalog API here
Once Resource and Service Specification have been defined, the next step is defining a Product Specification. The Product Specification will include links to the Service and Resource Specifications, a set of attachments such as pictures, documentation, etc, and the list characteristics of the product specification.
Product Specifications can be created in the Product Catalog Management API using a POST request, as follows:
POST [Product Catalog API Endpoint]/productSpecification
{
"brand": "FICODES",
"description": "Description of a vCPU Service Product",
"isBundle": false,
"lastUpdate": "2024-07-01T16:26:40.515817138Z",
"lifecycleStatus": "Active",
"name": "vCPU Service Product",
"productNumber": "1",
"version": "0.1",
"attachment": [
{
"attachmentType": "image/png",
"name": "Profile Picture",
"url": "https://myserver.org/media/image.png"
}
],
"productSpecCharacteristic": [
{
"id": "urn:ngsi-ld:characteristic:e368668c-9009-4277-8e06-35fa834b5cab",
"description": "vCPU Service Product Characteristic desc",
"name": "vCPU Service Product Characteristic",
"productSpecCharacteristicValue": [
{
"isDefault": true,
"value": "1"
}
]
}
],
"relatedParty": [
{
"id": "urn:ngsi-ld:organization:98a67a91-0e05-4dda-af43-253de1e4864c",
"href": "urn:ngsi-ld:organization:98a67a91-0e05-4dda-af43-253de1e4864c",
"role": "Owner",
"@referredType": ""
}
],
"resourceSpecification": [
{
"id": "urn:ngsi-ld:resource-specification:fd251d2f-aa13-45b4-bd4e-4bbb154a0b24",
"href": "urn:ngsi-ld:resource-specification:fd251d2f-aa13-45b4-bd4e-4bbb154a0b24",
"name": "vCPU"
}
],
"serviceSpecification": [
{
"id": "urn:ngsi-ld:service-specification:a2fcfb3c-b7ab-45ad-8870-889b2b8017b6",
"href": "urn:ngsi-ld:service-specification:a2fcfb3c-b7ab-45ad-8870-889b2b8017b6",
"name": "vCPU Service"
}
],
"validFor": {
"startDateTime": "2024-07-01T16:21:25.585Z"
}
}
For a complete reference of all the available attributes and options, please refer to the Swagger file of the Product Catalog API here
The compliance profile imformation is stored as Product Specification characteristics, having one characteristic per certification, including the link to the certification file as characteristic value. The following is an example of a profile including 2 certifications:
"productSpecCharacteristic": [
{
"id": "urn:ngsi-ld:characteristic:b4c7d804-72fb-4f4f-b063-fd1e774a3c01",
"name": "ISO 22301:2019",
"productSpecCharacteristicValue": [
{
"isDefault": true,
"value": "https://myserver.com/media/iso22301.pdf"
}
]
},
{
"id": "urn:ngsi-ld:characteristic:5200d37f-0d85-4749-b0c8-5bdd2564bbdf",
"name": "ISO/IEC 27001:2022",
"productSpecCharacteristicValue": [
{
"isDefault": true,
"value": "https://myserver.com/media/iso27001.pdf"
}
]
}
...
]
If such certifications have been verified, the Verifiable Credential issued by the verification service needs to be provided using another characteristic with name Compliance:VC, providing the encoded VC as value.
"productSpecCharacteristic": [
{
"id": "urn:ngsi-ld:characteristic:b4c7d804-72fb-4f4f-b063-fd1e774a3c01",
"name": "Compliance:VC",
"productSpecCharacteristicValue": [
{
"isDefault": true,
"value": "encoded token ..."
}
]
}
...
]
The final step is creating a Product Offering. This entity includes the link to the Product Specification, the terms and conditions, and the pricing model.
Product Offerings can be created in the Product Catalog API using the following POST request:
POST [Product Catalog API Endpoint]/productOffering
{
"name": "My Offer",
"description": "Description of the product offering",
"isBundle": false,
"lastUpdate": "2024-07-01T16:34:49.956115566Z",
"lifecycleStatus": "Active",
"version": "0.1",
"productOfferingPrice": [
{
"id": "urn:ngsi-ld:product-offering-price:3dd1b61d-2ecb-4b86-889c-4ed3c18b44c1",
"href": "urn:ngsi-ld:product-offering-price:3dd1b61d-2ecb-4b86-889c-4ed3c18b44c1",
"name": "VCPU"
}
],
"productSpecification": {
"id": "urn:ngsi-ld:product-specification:f3ef1391-b54e-4a02-b1ba-fdbc7e9295cc",
"href": "urn:ngsi-ld:product-specification:f3ef1391-b54e-4a02-b1ba-fdbc7e9295cc",
"name": "vCPU Service Product",
"version": "0.1"
},
"validFor": {
"startDateTime": "2024-07-01T16:34:50.033Z"
}
}
In order to properly drive the replication process, all major TMForum entities, including ProductOfferings, must carry information about involved stakeholders. In particular, a ProductOffering, within its 'realtedParty' attribute, should include the indentity of the Seller and the identity of operator of the Access Node where the offering is published.
This information will be later propagated to Orders, Products, Bills, etc. related to this offering, together with the same information on the Buyer side.
"relatedParty": [
{
"href": "urn:ngsi-ld:party:221f6434-ec82-4c62",
"id": "urn:ngsi-ld:party:221f6434-ec82-4c62",
"name": "did:elsi:VATES-12341234",
"role": "Seller",
"@referredType": "Organization"
},
{
"href": "urn:ngsi-ld:party:221f6434-ec82-4c62",
"id": "urn:ngsi-ld:party:221f6434-ec82-4c62",
"name": "did:elsi:VATES-12341234",
"role": "SellerOperator",
"@referredType": "Organization"
}
]
For a complete reference of all the available attributes and options, please refer to the Swagger file of the Product Catalog API here
The Product resource represents an instance of a Product Offering procured by a Customer. The Product will include links to the Product Offering and to the service(s) and / or resource(s) realizing the Product.
The Product can be created in the Product Inventory Management API using a POST request, as follows:
POST [Product Inventory Management API Endpoint]/product
{
"id": "urn:ngsi-ld:product:b669d51d-5fc0-4f3a-aa13-532f5b45bbbc",
"href": "urn:ngsi-ld:product:b669d51d-5fc0-4f3a-aa13-532f5b45bbbc",
"description": "Description of the Product",
"name": "VM Product",
"startDate": "2025-10-14T11:00:00Z",
"terminationDate": "2025-12-30T10:00:00Z",
"billingAccount": {
"id": "urn:ngsi-ld:billing-account:c84d03ff-fc74-435c-a54c-fed6e95ff80a",
"href": "urn:ngsi-ld:billing-account:c84d03ff-fc74-435c-a54c-fed6e95ff80a"
},
"productCharacteristic": [
{
"name": "CPU",
"value": 2
},
{
"name": "RAM",
"value": 4
}
],
"productOffering": {
"id": "urn:ngsi-ld:product-offering:f1646ae0-a1c6-4655-b24a-681b1114f88b",
"href": "urn:ngsi-ld:product-offering:f1646ae0-a1c6-4655-b24a-681b1114f88b"
},
"productPrice": [
{
"priceType": null,
"price": null,
"productOfferingPrice": {
"id": "urn:ngsi-ld:product-offering-price:5bfe47e3-2466-4381-a22c-da072b5a333c",
"href": "urn:ngsi-ld:product-offering-price:5bfe47e3-2466-4381-a22c-da072b5a333c"
}
}
],
"productSpecification": {
"id": "urn:ngsi-ld:product-specification:021517fe-650f-4834-92f1-4bf29487c5e3",
"href": "urn:ngsi-ld:product-specification:021517fe-650f-4834-92f1-4bf29487c5e3"
},
"relatedParty": [
{
"id": "urn:ngsi-ld:organization:95fdc12e-6889-4f08-8ff8-296b10e8e781",
"href": "urn:ngsi-ld:organization:95fdc12e-6889-4f08-8ff8-296b10e8e781",
"role": "Seller",
"@referredType": "organization"
},
{
"id": "urn:ngsi-ld:organization:df924e5d-e8c8-4ea4-aca8-edaf5acdc109",
"href": "urn:ngsi-ld:organization:df924e5d-e8c8-4ea4-aca8-edaf5acdc109",
"name": "DOME Foundation",
"role": "SellerOperator",
"@referredType": "organization"
},
{
"id": "urn:ngsi-ld:organization:a2f5ebea-49c9-4015-a9d6-56f2c566f6c9",
"href": "urn:ngsi-ld:organization:a2f5ebea-49c9-4015-a9d6-56f2c566f6c9",
"role": "Buyer",
"@referredType": "organization"
},
{
"id": "urn:ngsi-ld:organization:df924e5d-e8c8-4ea4-aca8-edaf5acdc109",
"href": "urn:ngsi-ld:organization:df924e5d-e8c8-4ea4-aca8-edaf5acdc109",
"name": "DOME Foundation",
"role": "BuyerOperator",
"@referredType": "organization"
}
],
"status": "active"
}
For a complete reference of all the available attributes and options, please refer to the Swagger file of the Product Inventory API here
In order to calculare the bills the following Product's attributes must be present in the Product:
- status: lifecycle status of the Product. The bills will be generated only for products with status active.
- startDate: the date from which the Product starts.
- billingAccount: the reference to the billing account.
- relatedParty: the related parties (Seller/Buyer/SellerOperator/BuyerOperator) involved in the Product.
- productPrice: the list of ProductPrice representing the actual price components paid by the Customer for the purchase. In each ProductPrice entity must be present the reference to the ProductOfferingPrice. The ProductOfferingPrice TMForum entity defines information about the price applied for a service/resourse realizing the Product, according to the Product Offering (e.g., information such as price type, price, charge period etc.). The billing components require the presence of the ProductOfferingPrice's reference on the ProductPrice to calculate the bills.
The ProductOfferingPrice resource represents the price plan applied for a service/resource in a Product Offering. A ProductOfferingPrice could represent also an alteration of the price, for instance to manage discounting. The ProductOfferingPrice may represent a bundle ProductOfferingPrice (i.e., the parent) with references to simple ProductOfferingPrice (i.e., child). A ProductOfferingPrice may participate in more than one bundle relationship. Moreover, a ProductOfferingPrice may include links to ProductOfferingPrice relationships, to manage, for instance, a price alteration such as discount.
The ProductOfferingPrice can be created in the Product Catalog Management API using a POST request, as follows:
POST [Product Catalog Management API Endpoint]/productOfferingPrice
{
"id": "urn:ngsi-ld:product-offering-price:a824e4b5-b235-434b-acc5-5db0199432f3",
"href": "urn:ngsi-ld:product-offering-price:a824e4b5-b235-434b-acc5-5db0199432f3",
"description": "This is a bundle ProductOfferingPrice",
"isBundle": true,
"lastUpdate": "2025-09-18T07:36:39.934918183Z",
"lifecycleStatus": "active",
"name": "Bundle ProductOfferingPrice",
"bundledPopRelationship": [
{
"id": "urn:ngsi-ld:product-offering-price:43afdc36-6981-4019-8f58-d69f56f40f6e",
"href": "urn:ngsi-ld:product-offering-price:43afdc36-6981-4019-8f58-d69f56f40f6e",
"name": "vCore"
},
{
"id": "urn:ngsi-ld:product-offering-price:a0f8fe96-f382-4f56-aae6-6d90cec6797e",
"href": "urn:ngsi-ld:product-offering-price:a0f8fe96-f382-4f56-aae6-6d90cec6797e",
"name": "Floating IPs"
},
{
"id": "urn:ngsi-ld:product-offering-price:b3eb4c12-803f-4fec-8925-9a333d6f587a",
"href": "urn:ngsi-ld:product-offering-price:b3eb4c12-803f-4fec-8925-9a333d6f587a",
"name": "Space (Gold)"
},
{
"id": "urn:ngsi-ld:product-offering-price:5cce5f34-9a42-4a9d-991e-b72845ded1a9",
"href": "urn:ngsi-ld:product-offering-price:5cce5f34-9a42-4a9d-991e-b72845ded1a9",
"name": "vRAM"
},
{
"id": "urn:ngsi-ld:product-offering-price:16a1dc71-7e91-40d2-b07e-d8e5e275cf8a",
"href": "urn:ngsi-ld:product-offering-price:16a1dc71-7e91-40d2-b07e-d8e5e275cf8a",
"name": "Region"
}
],
"validFor": {
"startDateTime": "2025-09-18T07:36:39.928Z"
}
}
POST [Product Catalog Management API Endpoint]/productOfferingPrice
{
"id": "urn:ngsi-ld:product-offering-price:43afdc36-6981-4019-8f58-d69f56f40f6e",
"href": "urn:ngsi-ld:product-offering-price:43afdc36-6981-4019-8f58-d69f56f40f6e",
"description": "A simple ProductOfferingPrice",
"isBundle": fasle,
"lastUpdate": "2025-09-18T07:36:37.895560948Z",
"lifecycleStatus": "active",
"name": "vCore",
"priceType": "recurring-prepaid",
"recurringChargePeriodLength": 1,
"recurringChargePeriodType": "month",
"price": {
"unit": "EUR",
"value": 2
},
"prodSpecCharValueUse": [
{
"id": "urn:ngsi-ld:characteristic:11ab960c-449f-4d56-85aa-139b7371e851",
"description": "",
"name": "vCore"
}
],
"validFor": {
"startDateTime": "2025-09-18T07:36:37.859Z"
}
}
For a complete reference of all the available attributes and options, please refer to the Swagger file of the Product Catalog Management API here
In order to calculare the bills the following ProductOfferingPrice's attributes must be present in the ProductOfferingPrice:
- lifecycleStatus: lifecycle status of the ProductOfferingPrice. The bills will be generated only for product offering price with status active or launched.
- isBundle: a flag indicating if the ProductOfferingPrice is bundle (true) or simple (false).
- bundledPopRelationship: the references to the simple ProductOfferingPrice (i.e., chield) included in a bundle ProductOfferingPrice. If the isBundle attribute is true at least one bundled relashionship must be present.
- priceType: a string representing the type of price. The possible values are: onetime, recurring-postpaid, recurring-prepaid, usage, custom. Notes: usage refers to the pay-per-use as a recurring-postpaid; custom means that only the provider is able to manage the price. In case of bundle ProductOfferingPrice the priceType can be omitted, but in case of simple ProductOfferingPrice the _priceType must be present.
- recurringChargePeriodLength: an integer representing the period of the recurring charge: 1, 2 etc. If the priceType is recurring-prepaid or recurring-postpaid or usage this attribute must be present.
- recurringChargePeriodType: a string representing the period to repeat the application of the price. The possible value are: day, week, month, year. If the priceType is recurring-prepaid or recurring-postpaid or usage this attribute must be present.
- price: the amount of money that characterizes the price. If the isBundle attribute is false (i.e., simple ProductOfferingPrice) this attribute must be present.
- unitOfMeasure: A quantity (i.e., a number and unit) representing how many of an ProductOffering is available at the offered price (e.g., 1 GB). If the priceType is usage this attribute must be present.
- relatedParty: the list of the involved parties (i.e., Seller, Buyer, SellerOperator, BuyerOperator). This TMForum entity does not include by default the relatedParty attribute, therefore the @schemaLocation attribute, according to the ones indicated in the DOME GitHub Schemas repository, must be present.
All the TMForum APIs allow to subscribe to certain events over the different entities managed in the particular API. To do that, the TMForum APIs define a set of endpoints that can be used to register listeners for the different events.
In general, the following events are triggered for a TMForum entity:
- Create: This event is triggered when a new entity is created
- Attribute Value Change: This event is triggered when the value of an attribute of the entity is changed
- State Change: This event is triggered when the lifecycle status of an entity is changed
- Delete: This event is triggered when an entity is deleted
To register a listener for the different events a POST request to the hub endpoint is used. Such an endpoint is available in all the TMForum APIs and receives two params, a query filtering the entities you are interested and the callback to be called when an event is triggered.
The following is an example of creating a listener:
POST [Catalog API Endpoint]/hub
{
"callback": "https://provider.com",
"query": ""
}
Once the listener is registered, the particular TMForum API will call the given callback URL every time an event is triggered. To do that, the TMForum API will send a POST request and encode the particular event as part of the path of the request.
The following is an example request made by the TMForum API when a new Product Offering is created
POST https://provider.com/listener/productOfferingCreateEvent
{
"event": {
"productOffering": {
...
}
},
"eventId": "string",
"eventTime": "2024-05-07T08:24:01.581Z",
"eventType": "string",
"correlationId": "string",
"domain": "string",
"title": "string",
"description": "string",
"priority": "string",
"timeOcurred": "2024-05-07T08:24:01.581Z"
}
The event content will include on the one hand, some information about the event itself, like the time when it was triggered or the event type. On the other hand, the field event will include the updated TMForum entity the event refers to.
It can be seen, that the TMForum API is making the POST request to the /listener/productOfferingCreateEvent, that URL encodes the particular event, addding the model followed by the event type. For a complete list of all the listener URL options please refer to the particular Swagger documentation of the API.
This section refers to Billing and Payment services.
The system must support checking whether recurring payments (for both prepaid and postpaid offerings) have been made for a Product. If payment fails, the provider can pause service/ contact the customer (depends on the contract).
To check the status of recurring payments, the TMForum APIs are used to retrieve and check the status of the TMForum entities.
- Involved TMForum entities:
- CustomerBill (TMF678). This resource represents a customer bill as a regular recurring bill or as an extra bill on demand by the customer or the cloud service provider. The CustomerBill could define the total amount to pay considering more bills generated during the billing process (see the AppliedCustomerBillingRate entity below) belonging to the same billing period.
- AppliedCustomerBillingRate (ACBR) (TMF678). This resource represents a bill created during the billing process. The bill refers to a product , to a periodCoverage (i.e., the time coverage period of the bill) and to a customerBill. More bills can be associated to the same customerBill instance (i.e., aggregation of the bills in a unique payment).
- Product (TMF637). This resource represents a product offering, realized as one or more services and/or resources, procured by a customer.
CustomerBill mandatory attributes
The attributes expected in the CustomerBill (TMF678) entity are:
amountDue: the total amount to pay for the bill in a billing period. If the CustomerBill is considered fully paid this attribute should be set to0. This field decreases based on the payments made;appliedPayment: the list of the performed payments. If the CustomerBill has been fully paid this attribute should be valorised with one or more payments which sum of the paid amounts corresponds to the value of thetaxIncludedAmountattribute;billDate: a date time representing the date of the bill;billNo: identifier of the bill for the customer;billingAccount: a billing account reference. This attribute should correspond to the product's billingAccount;billingPeriod: the time period to which the bill refers;id: identifier of the bill in the DOME Persistence Layer;paymentDueDate: a date time representing the date for which the bill must be paid;relatedParty: the related parties (Seller/Buyer/SellerOperator/BuyerOperator) involved in the CustomerBill;remainingAmount: the amount still to be paid. This field decreases based on the payments made;state: represents the status of the CustomerBill. Allowed values are: new -'bill is ready to validate or to sent', validated - 'bill is checked (manual / automatic)', sent - 'bill is sent with the channel defined in the billingaccount', settled - 'bill is payed', partiallySettled - 'bill is partially payed', onHold - 'bill will not be in further processing until open issues connected to the bill are solved';taxExcludedAmount: the total amount to pay without taxes;taxIncludedAmount: the total amount to pay with taxes. When the CustomeBill is generated theamountDueandremainingAmountshoud correspond to this attribute;taxItem: the list of TaxItem (TMForum678) involved in the bill. In DOME the taxRate is expressed in decimal format (e.g., 0.21) rather than as a percentage (21%);
AppliedCustomerBillingRate mandatory attributes
The attributes expected in the AppliedCustomerBillingRate (TMF678) entity are:
appliedBillingRateType: the type of applied charge (i.e., one-time, recurring-prepaid, recurring-postpaid, usage, dicount, custom);appliedTax: a list of AppliedBillingTaxRate (TMForum 678). In DOME the taxRate is expressed in decimal format (e.g., 0.21) rather than as a percentage (21%);bill: the reference to the CustomerBill;billingAccount: a billing account reference. This attribute should correspond to the product's billingAccount;date: a date time representing the creation date of the applied billing rate according to the bill cycle of the product;id: identifier of the applied customer bill in the DOME Persistence Layer;isBilled: a boolean value. If true thebillattribute should be provided, if false thenbillingAccountshould be provided.periodCoverage: the time period to which the applied customer bill refers;product: the reference to the product;taxExcludedAmount: the amount to pay without taxes;taxIncludedAmount: the amount to pay with taxes;
1 How to retrieve all the CustomerBill
- To retrieve the list of the CustomerBill generated by the billing subsystem you can use the
GETmethod provided by the TMForum specification:
GET [Customer Bill Management API Endpoint]/customerBill
2 How to retrieve all the CustomeBill that have been fully paid
- To retrieve the list of the CustomerBill that have been fully paid you can use the GET method provided by the TMForum specification using filters in the query string in order to get the CusterBill with the attribute
stateset tosettled:
The following is an example of getting all CustomerBill using filters in the query string to specify the state:
GET [Customer Bill Management API Endpoint]/customerBill?state=settled
4 How to retrieve the product(s) associated to a CustomerBill
- To get the product(s) associaed to a Customer Bill, for each customer bill retrieved at previous points you can use the
idof the customer bill to get the list of the AppliedCustomerBillingRate associated to the customer bill (i.e.,billattribute in the ACBR entity). Then, for each retrieved ACBR, you can get the product related to the bill (i.e.,productattribute in the ACBR entity)
The following is an example of getting all AppliedCustomerBillingRate related to a specific customer bill:
GET [Customer Bill Management API Endpoint]/appliedCustomerBillingRate?bill.id.eq=urn:ngsi-ld:customer-bill:c6fbe257-2084-4573-a814-7f86a5b9a1ae
This section outlines the guidelines for integrating an external billing engine with the DOME billing workflow.
The Billing Engine is a core component of the DOME architecture, responsible for calculating the amounts due by consumers for purchased products. Billing is the functionality that determines the charges associated with product acquisition and usage. These charges are computed according to pricing models, which may include discount policies and different charging modes such as one-time payments, subscriptions (i.e. recurring payments), and usage-based charges (i.e. pay-per-use).
The main responsibilities of the Billing Engine are:
- Performing real-time cost estimation (price preview) before a purchase is committed, enabling transparency and informed decision-making.
- Computing the actual bill amounts based on the applicable pricing model (fixed price, pay-per-use), including discounts and charging rules (i.e., one-time, recurring pre-paid, recurring post-paid)
DOME’s billing system is designed to support a wide range of pricing combinations across three main dimensions, as summarized in the following table:
| Option1 | Option2 | Option3 | |
|---|---|---|---|
| Pricing model | Fixed Price | Pay-per-Use | Hybrid (Fixed + Variable) |
| Charge model | One-Time | Recurring (Monthly, Annual) | Custom Period (Every 3 months, 1st of month) |
| Invoice generation model | Pre-Paid (at start of period) | Post-Paid (at end of period) | - |
In addition, the DOME billing system supports advanced features such as Tiered Pricing, enabling different prices based on volume or subscription levels; Promotions and Discounts, allowing temporary promotional pricing; and Multi-Component Pricing, for example a base subscription fee combined with usage-based charges, or a fixed recurring component alongside variable consumption-based charges.
Below are provided some baseline cooncepts about the Pay-per-Use price model enabling the marketing/sales and technical teams to better understand the functional logic.
Pay-per-Use model considers the calulation of price-preview and actual bill to be based on some “consumption metrics” that are continuously collected from the delivery platform. In particular, for the calculation of the price preview during the purchase of a product by a Customer, the usage data can be simulated through the DOME Marketplace dashboard. For the calculation of the consolidated bill, the usage data published in TMForum by the Provider is considered. The Metric in the DOME context represents the measurable resource or service parameter that is monitored and billed according to actual consumption (e.g. CPU, RAM, storage, API calls). In the DOME context, a metric is described by a provider-defined label, which is displayed in the user interface. The name attribute, instead, is used to uniquely identify the metric within the TMForum entity responsible for persisting usage data (i.e., the TMForum Usage entity). Another information is the Quantity, representing the measured consumption value collected for a metric and used to compute the charge associated with the corresponding price component. For instance, using 2 CPUs for 3 hours results in a quantity value of 6. The Provider’s delivery platform collects metric data at a defined Frequency. A higher frequency results in more accurate tracking of the actual resource consumption. The Price Plan linked to a Product Offering specifies the unit price applied to each billing metric (e.g., 2 EUR per CPU/hour). The total charge is calculated by multiplying the consumed quantity by the unit price. For example, if 2 CPUs are used for 3 hours (total quantity = 6 CPU/hours), the resulting cost is 12 EUR.
The DOME ecosystem provides a native DOME Billing Engine that implements the responsibilities described above (i.e. cost estimation and final bill calculation according to pricing logic and charging models). At the same time, the DOME architecture is designed to ensure flexibility for billing scenarios that extend beyond the supported models or that require direct control over billing data. For this reason, providers may maintain full operational and computational autonomy by integrating their own custom billing engine within the DOME billing workflow.
The next sections provide guidelines on how to integrate an external Billing Engine.
This section defines the REST APIs that an external Billing Engine must expose in order to integrate with the DOME billing workflow. These APIs represent the integration contract between DOME and a Billing Engine, allowing DOME to delegate cost estimation and billing calculations while preserving provider autonomy over pricing logic and billing data. The specification focuses on what the APIs must provide, not on how the Billing Engine internally performs billing calculations.
The following assumptions apply to all Billing Engine APIs:
- APIs are exposed as RESTful services;
- Request and response payloads use JSON encoding;
- Monetary amounts include a currency code compliant with ISO 4217;
- Error responses follow standard HTTP status codes.
The Billing Engine APIs are grouped according to the main billing responsibilities:
- Cost Estimation APIs: to obtain a real-time price preview before a purchase is committed;
- Billing Calculation APIs to compute the final bill amounts according to the applicable pricing model.
The following table summarizes the REST APIs that an external Billing Engine must expose to achieve the integration with the DOME ecosystem.
| Category | Endpoint | Method | Mandatory | Description |
|---|---|---|---|---|
| Cost Estimation | /billing/previewPrice |
POST | Yes | Calculates a price preview of a product order. In case of a usage-based product offering, it provides cost extimation according to the customer's usage simulation |
| Billing Calculation | /billing/bill |
POST | Yes | Computes the actual bill amount for a purchased product within a billing period, according to the product offering pricing logic and charging models |
| Billing Calculation | /billing/instantBill |
POST | Yes | Computes the actual bill amount for a product at a given instant in time (i.e., the billing period has the same start and end date), according to the product offering pricing logic |
The Billing Engine APIs rely on a reference data model that combines:
- Standardized entities defined by TM Forum Open API specifications;
- DOME-specific Data Transfer Objects (DTOs) introduced to structure API requests and responses.
This approach allows DOME to maximize interoperability by reusing industry-standard billing models, while preserving flexibility to support platform-specific integration needs.
The Billing Engine APIs reuse entities defined in the TMForum Open API data model. TMForum entities are used as authoritative reference models for core billing concepts such as invoices, bill items, and billing periods, and adopted as defined in the TMForum Open API specifications, without semantic modification.
The following table summarizes the TMForum entities involved in the DOME billing APIs and their corresponding TMForum specifications (version 4).
| TM Forum Entity | Description | TM Forum Specification (v4) |
|---|---|---|
CustomerBill |
Represents a bill issued to a customer, including total amount and billing period | TMF 678 – Customer Bill Management |
AppliedCustomerBillingRate |
Represents an applied billing rate (i.e., bill item) contributing to the final bill amount | TMF 678 – Customer Bill Management |
TimePeriod |
Represents a time interval used to define billing periods and charging intervals | TMF 678 – Customer Bill Management |
Product |
Represents a product offering instance purchased by a customer | TMF 637 – Product Inventory Management |
ProductOrder |
Represents a product order submitted by a customer | TMF 622 – Product Ordering Management |
Usage |
Represents usage or consumption data used for usage-based billing | TMF 365 – Usage Management |
In addition to TM Forum entities, DOME defines a set of DOME-specific Data Transfer Object (DTO) to act as API-level contracts between DOME and external Billing Engines. The DOME DTOs are used to:
- Encapsulate one or more TMForum entities when required;
- Simplify API payloads;
- Provide a stable and controlled integration interface.
DOME DTOs do not redefine billing semantics, but serve as composition and transport structures.
The following table summarizes the DOME DTOs entities involved in the DOME billing API.
| DOME DTO | Description |
|---|---|
BillingPreviewRequestDTO |
Input DTO used to trigger the cost estimation of a product offering during the ordering phase |
BillingRequestDTO |
Input DTO used to trigger billing calculation for a given purchased product and billing period |
InstantBillingRequestDTO |
Input DTO used to trigger billing calculation for a given product on-demand at a given instant in time |
Invoice |
Output DTO representing the result of a billing operation |
The following class diagram depicts the DOME-specific DTOs mentioned above, showing their attributes and, in particular, the TMForum entities they include.

BillingPreviewRequestDTO
The BillingPreviewRequestDTO is a DOME-specific input DTO used to calculate the total order price of an order made by a customer, and aggregates standard TMForum entities.
In particular, to obtain a cost estimation, this DTO aggregates the information about the instance of the order made by the customer and, in case of a usage-based product offering, information about simulated usage of the services/resources that the customer is going to purchase.
| Attribute | Type | Required | Description |
|---|---|---|---|
productOrder |
ProductOrder (TMF622) |
Yes | Istance of the order made by the customer. The order refers one or more services/resources (i.e., order items) |
usage |
List<Usage> (TMF365) |
No | Usage data used in case of pay-per-use plans to simulate the consumptions and calculate the price according to the specified usage |
BillingRequestDTO
The BillingRequestDTO is a DOME-specific input DTO used to calculate the bills due for a product in a specifid billing period, and includes standard TMForum entities.
In particular, this DTO is used by the Billing Engine to evaluate and calculate the billing amounts due for a specific product within a defined billing period. It enables the Billing Engine to verify whether billing charges are applicable for the product in the specified period, according to its pricing components, and to generate the corresponding billing records.
| Attribute | Type | Required | Description |
|---|---|---|---|
productId |
string |
Yes | Identifier of the purchased product instance to be billed |
billingPeriod |
TimePeriod (TMF678) |
Yes | Time interval for which the billing calculation is performed. The BE must check if bills are due for the specified product within the billing period and, in case, calcutate them |
InstantBillingRequestDTO
The InstantBillingRequestDTO is a DOME-specific input DTO used to calculate a bill on demand for a given product at a specific point in time.
In particular, this DTO enables the Billing Engine to verifies whether, at the specified time (the billing period start and end coincide), the product includes price components that must be billed. The referenced product represents a product instance that may not yet be persisted, supporting use cases such as one-time charges (e.g. initial fees prior to order completion).
| Attribute | Type | Required | Description |
|---|---|---|---|
product |
Product (TMF637) |
Yes | Product instance for which billing must be calculated |
date |
OffsetDateTime |
Yes | The point in time at which the billing calculation is requested for the product (i.e. start and end date of billing period coincide |
Invoice
The Invoice is a DOME-specific output DTO representing the invoice returned to the customer as the result of a billing calculation performed by the Billing Engine, and includes standard TMForum entities.
In particular, this DTO includes the invoice summarizing the total amount to be paid, as well as the list of individual bill items corresponding to the product’s pricing components, which together contribute to the final amount due.
| Attribute | Type | Required | Description |
|---|---|---|---|
customerBill |
CustomerBill (TMF678) |
Yes | The customer invoice representing the total amount to pay in a billing period for a product according to the bills items |
appliedCustomerBillingRates |
List<AppliedCustomerBillingRate>(TMF678) |
Yes | Detailed billing rates applied to compute the final amount |
| Endpoint | Method | Description | INPUT | OUTPUT |
|---|---|---|---|---|
/billing/previewPrice |
POST | This API provides the cost estimation (i.e., price preview) of an order made by the customer during the ordering phase | BillingPreviewRequestDTO |
ProductOrder |
As described in the Reference Data Model, the BillingPreviewRequestDTO in input incapsulates the information about the ProductOrder for which is requested cost extimation, and, in case of a pay-per-use, provides also information about the simulated Usage data (otherwise this information won't be present).
In the following are reported the attributes that are expected to be valorized in each involved TMForum entity, to achive price preview calculation.
ProductOrder (TMF622)
This entity represents an order made by a Customer. The required attributes are:
- productOrderItem: A list of
ProductOrderItem(TMF622) as part of the order. The list describes all the items of the order. EachProductOrderItemmust refers in theitemTotalPriceattribute the list ofOrderPrice(TMF622), representing the actual price paid by the Customer for this item of the order. EachOrderPricedefines information about the price anche charge model in the attributeproductOfferingPricewhich is aProductOfferingPriceRef(TMF622) referring aProductOfferingPrice(TMF622). Detailed information about the attributes required in theProductOfferingPriceare reported in ProductOfferingPrice mandatory attribute for billing processing; - relatedParty: The list of the involved parties (i.e., Seller, Buyer, SellerOperator, BuyerOperator).
Usage (TMF635)
This entity represents a usage event that can have charges applied to it. The required attributes are:
- id: The unique identifier;
- ratedProductUsage: A list of RatedProductUsage (TMF635). The list containes an instance of RatedProductUsage, referring in the productRef attribute the Product object of the usage;
- usageDate: The date time of the metering collection, respecting the previous usage event;
- usageCharacteristic: A list of UsageCharacteristic (TMF635) representing the specific metrics of the usage event. In the UsageCharacteristic the attribute name represents the metric (e.g.,CPU/hours, RAM/hours), while the attribute value is used to store the total amount of the consumption for the metric (e.g., if a customer uses 2 CPU for 3 hours the total consumption is 6 CPU/hours, therefore
name=CPU/hoursandvalue=6); - relatedParty: the list of the involved parties (i.e., Seller, Buyer, SellerOperator, BuyerOperator).
The ProductOrder (TMF622) in output MUST provide the total amount to pay in the orderTotalPrice attribute.
| Endpoint | Method | Description | INPUT | OUTPUT |
|---|---|---|---|---|
/billing//bill |
POST | This API computes the actual bill amount for a purchased product within a billing period | BillingRequestDTO |
Invoice |
As described in the Reference Data Model, the BillingRequestDTO in input incapsulates the information about the identifier of the purchased Product (TMF637) and the billing period for which is requested the calculation of the bill, if any.
The Product instance will be retrived from the DOME Persistence Layer through the product identifier. The Billing Engine will check if any bill is due within the specified billing period and calculates them according to the price plan. Detailed information about the attributes required in the Product are reported in Product mandatory attribute for billing processing;
The Invoice DTO in output, as described in the Reference Data Model, incapsulates the information about the generated CustomerBill (TMF678) with the total amount to pay, and the list of the AppliedCustomerBillingRate (TMF678) representing each bill item. Detailed information about the attributes required in the CustomeBill are reported in CustomerBill mandatory attributes, while detailed information about the attributes required in the AppliedCustomerBillingRate are reported in AppliedCustomerBillingRate mandatory attributes.
| Endpoint | Method | Description | INPUT | OUTPUT |
|---|---|---|---|---|
/billing/instantBill |
POST | This API computes the actual bill amount for a product at a given instant in time. The typical usage scenario for this API is during the ordering phase, when purchasing a product with an initial fee to pay. | InstantBillingRequestDTO |
Invoice |
As described in the Reference Data Model, the InstantBillingRequestDTO in input encapsulates the information about the Product (TMF637), not yet be persisted, the Customer is going to purchase and the specific point in time (i.e., an OffesetDateTime) when is required to calculate the bill. The API verifies if the Product contains price components (e.g., one-time prices) that must be billed and calculates the bill.
An Invoice DTO is produced in output.
- The external BE must generate invoices according to a specific billing period (i.e., time period). If your offering has explicit periodicity, use it to generate invoices that fall in that time period OR to lookup existing invoices you've already generated.
- Your engine must returns TMF-compliant invoices. If your invoices lack taxes, DOME applies VAT; otherwise, it respects your system's tax logic. Invoice persistence
- The provider is left free to decide whether the invoices generated through it’s own external BE will be persisted in the DOME persistence layer by DOME or will be the provider itself that take care of it. If no invoices are returned to DOME (either because no invoices are available on the billing period or because they have already persisted) no further actions are required by DOME.
This section will be filled when policies and the authorization process have been defined and specified.
- How can a Service Provider create policies that concern the Products that they offer ?
- How can a Marketplace Operator create policites that concern the Products that they host ?
That only the federated marketplace needs to enforce locally.
That everyone in the federation needs to enforce.
i.e. marketplace -to- Access Node PEP, PDP - when are they needed and when not ?
i.e. Access Node -to- Access Node



