.wpb_animate_when_almost_visible { opacity: 1; }
United Way - Product Ordering Management
Order and follow up your Orange Wholesale access
1.0

Table of Contents

This document is a complement to TMF 648 documentation regarding the technical details mandated by the TM Forum applied to our application (https://www.tmforum.org/resources/specification/tmf622-product-ordering-management-api-rest-specification-r19-0-0/)

Release content October 2023

  • Adding the orderTerm information in the order (#orderterm)
  • Adding a comment at order level (#orderTakingNote)
  • Adding new states for the order (see PO and POI lifecycle)
  • Adding the trading name information (#geographicsubaddress)
  • Adding the API notifications (/hub)

Authentication prerequisite

Access to this API is secured by the OAuth 2.0 framework with the Client Credentials grant type, which means that you will have to present an OAuth 2.0 access_token whenever you want to request this API.

It's easy to negotiate this access_token: just send a request to the proper token negotiation endpoint, with a Basic Authentication header valued with your own client_id and client_secret.

For this API, the token negotiation endpoint is: https://api.orange.com/oauth/v3/token.

A technical guide is available to learn how to negotiate and manage these access_token.

SDK to manage token lifecycle could help you to implement cache token.

Scopes

Scopes restrict specific request verbs for any resource of this api. You must specify at least one when requesting for an access_token. This is done by adding a scope parameter within the access token request. Scopes are additive and shall be space separated.

As an example:

curl -X POST \
-H "Authorization: Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-d "grant_type=client_credentials&scope=owf:united-way:scope1 owf:united-way:scope2" \
https://api.orange.com/oauth/v3/token

Scopes available in this api are explained below.

ScopeDescription
owf:united-way:product-order:v1:readonlyAllow GET, HEAD http request for any resource of this api
owf:united-way:product-order:v1:writeAllow POST http request for any resource of this api. PUT and DELETE http request are not available for this API.
  • If your client will only do GET requests, you may request an access_token with '&scope=owf:united-way:product-order:v1:readonly'.
  • If your client will do GET and POST requests, you must request an access_token with '&scope=owf:united-way:product-order:v1:readonly owf:united-way:product-order:v1:write'.

Scopes are not fine-grained permissions. While an access_token can allows your client application to do GET or POST request, the request can be forbidden at the resource level.

We strongly encourage you to register a dedicated client application to subscribe to all United Way apis. You will be able to request an access_token with all scopes required to do a complete scenario over all needed apis.

Important

Please pay particular attention to properly handle authentication error responses in your application. See the section Errors

Base URL

The Base URL is the first part of the full invocation URL, just before the resource paths defined in the API reference.

The Base URL is comprised of the scheme ('https'), the authority (i.e. the Fully Qualified Domain Name) and the API base path.

Whenever you request this API and encounter a 404 NOT FOUND HTTP error response, please check first that the Base URL is correct.

The Base URL for this API is: https://api.orange.com/united-way/product-ordering-management/v1/

The documentation below assumes that, whenever you make requests on this API, you are prepending the Base URL to the resource paths defined for this API.

Resources

ResourceDescription
ProductOrderProduct Order is a type of order which can be used to place an order between a customer and a service provider or between a service provider and a partner

ProductOrder

The below table describes the mandatory attributes required for any productorder

NameType / FormatDescriptionExample
productOrderSpecificationStringdefine the action for this ProductOrder, in case of a new configuration the value should be Acquisition, in case of Termination the value should be Termination, in case of Modification the value depends on the operationSpecification proposed in the catalog for the productOfferingAcquisition
relatedPartyRelatedParty[]your organization informationsee below
productOrderItemProductOrderItem[]the list of ProductOrder items represents the offer you want to ProductOrder including different characteristics chosensee below
externalIdentifierExternalIdentifier[]An ID and its informations (type, owner) given by the consumer and only understandable by him (to facilitate his searches afterwards).see below

Business rules for Product Order

To be set in an order, Product Order must respect several rules, otherwise the order will be rejected. See below for more details:

CodeBusiness error messageDescription
PRO_0001_Athe productOrderSpecification is mandatoryProductOrdeSpecification is missing, please complete this
PRO_0002_AThe externalIdentifier is mandatoryThe externalIdentifier is missing, please complete this
PRO_0003_AExternalIdentifier of type CustomerIdentifier is invalidExternal id is filled in several times, a unique external id is required
PRO_0004_AThe productOrderSpecification [xxxx] is unknowYou have specified a productOrderSpecification other than those authorised
PRO_0005_AThe ExternalIdentifier [xxxx] already existsExternalIdentifier already exists
PRO_0006_Athe ProductID is mandatoryIn the case of a modification or cancellation, you do not specify a ProductID

Business rules for Eligibility

To be set in an order, the eligibility must respect several rules, otherwise the order will be rejected. See below for more details:

CodeBusiness error messageDescription
ELI_0001_AThe code IMB is mandatory for the given addressYou are faced with a multi-building case, please complete the IMB code
ELI_0002_AThis adress isn't eligible for the selected offerThe address that is not eligible for the desired offer
ELI_0003_AThe format of address is not validthe address format is not accepted for geographical eligibility

Sub resources

ResourceDescription
RelatedPartyA reference to a party playing a role in this ProductOrder (RelatedParty with role buyer).
ProductOrderItemA ProductOrder item describes an ordering action to be performed on a productOffering or a product
ProductOrderItemRelationshipUsed to describe relationship between ProductOrder items.
ProductA product to be created defined by a value or an existing product defined by reference.
ProductOfferingA product offering represents an entity that can be ordered from a provider's catalog. This sub-resource includes pricing information.
RelatedPlaceRefOrValueA related place defines a place described by reference or by value linked to a specific entity.
GeographicSiteBuildingA polymorphic entity of RelatedPlaceRefOrValue to manage address by buildingCode.
GeographicAddressa sub entity of GeographicSiteBuilding which contains address indications.
GeographicSubAddressa sub entity of GeographicAddress which contains additional indications about an address.
ExternalIdentifierAn ExternalIdentifier which describes the unique order reference on the consumer side.
AppointmentAn appointment may be required for some orders
AgreementAn agreement is required to post an order
OrderTermAn orderterm can be set to the order depending on the configuration

Agreement

The agreement is mandatory to post an order.You need to set the number of the contract Conditions Générales Accès et Collecte. Example:

"agreement": 
[ 
  { 
    "id": "TESTFTTHAcess1",
    "@type": "AgreementItemRef"
  } 
],
NameType / FormatDescriptionExampleMandatory
idStringagreement id"TESTFTTHAcess1"yes
@typeStringAgreements related to current contract"AgreementItemRef"yes

Business rules for Agreement

To be set in an order, the Agreement must respect several rules, otherwise the order will be rejected. See below for more details:

CodeBusiness error messageDescription
AGR_0001_AThe agreement id is mandatoryAgreement id missing in the product offering type contract
AGR_0002_AThe number of agreement [xxx] is unknownYour contract is not valid, please contact your Commercial Service.
AGR_0003_AThe product Offering is not covered by the agreementYour contract is not valid, please contact your Commercial Service.

RelatedParty

RelatedParty with role buyer

The relatedParty with the "role": "buyer" is mandatory.

NameType / FormatDescriptionExampleMandatory
idStringid of your organization"ea69228c-600a-4058-8e4e-e13fcc8bf89f"yes
roleStringshoud be buyer"buyer"yes
@referredTypeStringshoud be organization"organization"yes
nameStringname of your organization"ABSOLIGHT"no

Example:

"relatedParty":[
   {
      "@referredType":"organization",
      "id":"ea69228c-600a-4058-8e4e-e13fcc8bf89f",
      "name":"ABSOLIGHT",
      "role":"buyer"
   }
],

To find information about your organization call the Party management API (see Party management API getting started for more information).

Example:

GET /api/v1/organization/<organizationId>
{
   "id":"ea69228c-600a-4058-8e4e-e13fcc8bf89f",
   "isHeadOffice":true,
   "isLegalEntity":true,
   "name":"ABSOLIGHT",
   "organizationType":"COMPANY",
   "tradingName":"ABSOLIGHT",
   "contactMedium":[],
   "organizationIdentification":[
      {
         "identificationId":"00353831",
         "identificationType":"RCE"
      },
      {
         "identificationId":"418565404",
         "identificationType":"SIREN"
      }
   ],
   "@type":"Organization",
   "href":"/api/v1/organization/ea69228c-600a-4058-8e4e-e13fcc8bf89f"
}

RelatedParty with other roles

Others party can be mandatory for an order. The expected parties are listed in the catalog, depending on the offer and the type of operation (see Catalog Management API getting started for more informations).

Business rules for RelatedParty

To be set in an order, the RelatedParty must respect several rules, otherwise the order will be rejected. See below for more details:

CodeBusiness error messageDescription
PAR_0004_AIndividual %ID is not validThe givenName and familyName of a relatedParty must not exceed 50 characters, the fullName 101 characters, and the \n characters are not allowed in those fields
PAR_0005_AContactMedium Type email and phone are mandatory for individual ID%A relatedParty with type individual must have at least a contactMedium with mediumType PHONE and MAIL
PAR_0001_AThe related party role and referred type are not conformed to the expected catalog configurationThe role of a party must correspond to the expected role given in the catalog configuration, the allowed referredType are individual or organization and the referredType
PAR_0002_AA buyer is mandatory in relatedPartyA relatedPartywith role buyer must be set in an order
PAR_0003_AThe related party with role %s is mandatory for productOfferingId %sDepending on the catalog configuration, expected parties must be set at the correspondant productOffering level

ProductOrderItem

A productOrder contains a list of productOrder items, representing the desired components in terms of offer and characteristics. Like the representation of the catalog offer, the productOrder items are organised like a tree. Some productOrder items may "bundle" other productOrder items using "relationship" attributes.

  • The bundling productOrder items are associated with the following catalog ProductOffering type : Contract, play set.
  • The leaf productOrder items are associated with the following catalog productOffering type : Atomic offer

Warning: If the list of productOrder items doesn't represent a tree, or if at least one productOrder item is not bundled by another one, the productOrder will be rejected.

NameType / FormatDescriptionExampleMandatory
idStringunique id, used for relationship between productOrder items"1"yes
actionStringcan be add, modify, noChange or delete depending on productorderSpecification"add"yes
productOrderItemRelationshipproductOrderItemRelationship[]Information about the relationships of the productorder itemsee belowconditional
productProductRefOrValuecontains informations about the desired product (exemple characteristics)see belowconditional

Example of productOrderItem which contains product with productOffering of type atomicOffer and its characteristics:

...
{
   "action":"add",
   "id":"O40140084008",
   "product":{
      "productOffering":{
         "id":"O40140084008",
         "name":"Raccordement"
      },
      "productCharacteristic":[
         {
            "id":"FONC40140084010",
            "valueType":"object",
            "name":"Type de point de livraison",
            "value":{
               "@type":"CharacteristicChoiceValue",
               "id":"VF0000140140084010",
               "name":"DTIO/PTO"
            }
         },
         {
            "valueType":"object",
            "id":"FONC40140084008",
            "name":"Multi-accès",
            "value":{
               "@type":"CharacteristicChoiceValue",
               "id":"VF0000240140084008",
               "name":"Non"
            }
         },
         {
            "valueType":"object",
            "id":"FONC40140084003",
            "name":"Type de raccordement",
            "value":{
               "@type":"CharacteristicChoiceValue",
               "id":"VF0000140140084003",
               "name":"Raccordement sur prise existante"
            }
         },
         {
            "valueType":"string",
            "id":"FONC40140084011",
            "name":"Réfèrence PTO",
            "value":"FI-9786-6362"
         }
      ],
      "productSpecification":{
         "id":"PS40140084008",
         "name":"Accès passif"
      }
   }
},
...

ProductOrderItemRelationship

Describe the relation between productOrder items.

NameType / FormatDescriptionExampleMandatory
idStringid of the productOrder item wich has a relation with the current productOrder item"1"yes
relationshipTypeStringRelationship type"bundles"yes

Example:

...
"productOrderItem":[
    {
        "id": 1,
        "productOrderItemRelationship": [
            {
            "id": 2,
            "relationshipType": "bundles"
            },
            {
            "id": 3,
            "relationshipType": "bundles"
            }
        ],
        ...
    },
    {
        "id": 2,
        ...
    },
    {
        "id": 3,
        ...
    }

]
...

Product

Describe the product of a productOrder item.

NameType / FormatDescriptionExampleMandatory
placeRelatedPlaceRefOrValuesee below(yes for the productOrderItem contract when productorderSpecification is Acquisition)
productCharacteristicsCharacteristic[]key value objectsee belowyes
productOfferingProductOfferingRefcontains information about the product offeringsee belowyes
isBundleBooleantrue if the productorder item is bundled by another onetrueyes
idStringid of the product inventory assettrue(yes in the productOrderItem contract if productorderSpecification is a value of Modification and Termination)

Example of product with productOffering of type contract with the RelatedPlaceRefOrValue of type GeographicSiteBuilding:

...
"product":{
   "isBundle":true,
   "place":[
      {
         "@type":"GeographicSiteBuilding",
         "role":"deliveryAddress",
         "geographicAddress":[
            {
               "@type":"GeographicAddress",
               "geographicSubAddress":[
                  {
                     "buildingName":"OULLINS C",
                     "@type":"GeographicSubAddress"
                  },
                  {
                     "levelNumber":"_NA_",
                     "levelType":"staircase",
                     "@type":"GeographicSubAddress"
                  },
                  {
                     "levelNumber":"0",
                     "levelType":"floor",
                     "@type":"GeographicSubAddress"
                  }
               ]
            }
         ],
         "buildingCode":"IMB/69149/C/ZJU1"
      }
   ],
   "productCharacteristic":[],
   "productOffering":{
      "id":"GOC40140084001",
      "name":"Just Fibre TEST"
   }
},
...

ProductOffering

Describe the product offering of a productOrder item.

NameType / FormatDescriptionExampleMandatory
idStringunique id coming from Product catalog management API"GOC40140084001"yes
hrefStringurl to get more information about the productOffering"http://..."no
nameStringDescription of the product offering"Just Fibre TEST"no

Example:

"productOffering":{
   "id":"GOC40140084001",
   "name":"Just Fibre TEST"
}

RelatedPlaceRefOrValue

The RelatedPlaceRefOrValue can be declined in various types, however, this API only manages the GeographicSiteBuilding and GeographicAddress TMF type.

GeographicSiteBuilding

To verify the call, you can use the Catalog APIs who drive the product.

NameType / FormatDescriptionExampleMandatory
roleStringrole of the address"deliveryAddress"yes
@typeStringobject type"GeographicSiteBuilding"yes
buildingCodeStringbuilding code of the the address (find with Aero API)"IMB/69149/C/ZJU1"yes
geographicAddressGeographicAddress[]information about the geographicAddress (to set geographicSubAddress)see belowconditional

To find a buildingCode for a specific address, you should call the Operator eligibility API (see Operator eligibility France getting started form more information):

 POST /api/productOfferingQualification
{
    "category": {
        "name": "ftth"
    },
    "contextType": "fulltext",
    "place": {
        "nonFormattedAddress": {
        "fullText": "9 grande rue 69600 oullins"
       }
    }
}

Example: deliveryAddress

{
  "place": [
    {
      "buildingCode": "ID-9501800009PT",
      "@type": "GeographicSiteBuilding",
      "geographicAddress": [
        {
          "cityCode": "95018",
          "streetCode": "4990",
          "geographicSubAddress": [
            {
              "levelNumber": "ESCALIER-A",
              "levelType": "staircase",
              "@type": "GeographicSubAddress"
            },
            {
              "levelNumber": "ETAGE-RDC",
              "levelType": "floor",
              "@type": "GeographicSubAddress"
            },
            {
              "buildingName": "BATIMENT-2",
              "@type": "GeographicSubAddress"
            }
          ],
          "@type": "GeographicAddressRivoli",
          "city": "ARGENTEUIL",
          "postcode": "95100",
          "streetName": "DE LA TOUR BILLY",
          "streetNr": "2",
          "streetType": "RUE",
          "geographicLocation": {
            "geoCodeX": "2.247034308421",
            "geoCodeY": "48.945790571654",
            "@type": "GeographicLocation",
            "@baseType": "GeographicLocation"
          },
          "@baseType": "GeographicAddressRivoli"
        }
      ],
      "role": "deliveryAddress",
      "@baseType": "GeographicSiteBuilding"
    }
  ]
}

GeographicAddress

NameType / FormatDescriptionExampleMandatory
geographicSubAddressgeographicSubAddress[]list of geographicSubAddresssee belowyes
@typeStringobject type"GeographicAddress"yes
cityStringcity nameVANVESyes (In case of shippinAdress, otherwise the order will be rejected)
postcodeStringZIP code92170yes (In case of shippinAdress, otherwise the order will be rejected)
streetNameStringstreet nameRABELAISyes (In case of shippinAdress, otherwise the order will be rejected)
streetNrStringstreet number14no
streetTypeStringstreet typerueno

Example: shippingAddress

  "place": [
    {
      "city":"ANTONY",
      "postcode":"92160",
      "streetName":"BLANCHE DE CASTILLE",
      "streetNr":"16",
      "streetType":"RUE",
      "geographicSubAddress":[]
      "@type":"GeographicAddress",
      "role":"shippingAddress"
      "@baseType":"GeographicAddress"
    }
  ]

GeographicSubAddress

The geographicSubAddress is used to set the informations building, staircase, floor and TradingName.

NameType / FormatDescriptionExampleMandatory
buildingNameStringbuilding name"OULLINS C"conditional
levelNumberStringlist of geographicSubAddress"NA" , "0",...conditional
levelTypeStringlist of geographicSubAddress"staircase" or "floor"conditional
subUnitNumberString (35)Trading name of the client"Garage Test"conditional
subUnitTypeStringIf a tradingName is set to the order, the value of the subUnitType must be 'TradingName'"tradingName"conditional
@typeStringobject type"GeographicSubAddress"yes

To find a GeographicSubAddress information for a specific buildingCode, you should call the TAO webservice (for more information, a documentation is available on your Espace opérateur: Mon compte> Mon espace documentaire).

Example of complete GeographicSiteBuilding:

"place":[
   {
      "@type":"GeographicSiteBuilding",
      "role":"deliveryAddress",
      "geographicAddress":[
         {
            "@type":"GeographicAddress",
            "geographicSubAddress":[
               {
                  "buildingName":"OULLINS C",
                  "@type":"GeographicSubAddress"
               },
               {
                  "levelNumber":"_NA_",
                  "levelType":"staircase",
                  "@type":"GeographicSubAddress"
               },
               {
                  "levelNumber":"0",
                  "levelType":"floor",
                  "@type":"GeographicSubAddress"
               },
                                          {
                  "subUnitNumber": "Garage Test",
                  "subUnitType": "tradingName",
                  "@type": "GeographicSubAddress"
               }
            ]
         }
      ],
      "buildingCode":"IMB/69149/C/ZJU1"
   }
],

Business rules for Place

To be set in an order, the Place must respect several rules, otherwise the order will be rejected. See below for more details:

CodeBusiness error messageDescription
PLA_0001_AA place is mandatory for the productOfferingExpectedPlace is missing in the productOffering [xxxx]
PLA_0002_AA Place with role [xxxx] is mandatory for the ProductOffering [xxxx]ExpectedPlace has no role. Please, complete ExpectedPlace with role in the productOffering [xxxx]
PLA_0003_AThe place with Type type [xxxx] is not validBuildingCode is missing in geographicSiteBuilding of productorderItem [xxxx], please complete the BuildingCode
PLA_0004_AA place is not mandatory for the productOffering [xxxx]Please, remove place for the productOffering
PLA_0005_AThe place type type [xxxx] is unknowYou haven't completed any Delivery Adress or Shipping Adressn please, complete a Place
PLA_0006_AThe place with Type type [xxxx] is not validThere are several reasons for this error : (1) The format input is not correct ; (2) Shipping Address inpunt isn't valid (city, postCode or streetName) ; (3) The role for the place's Productoffering [xxxx] is missing
PLA_0007_AThe SubAdress is mandatoryThe subAdress is missing in the productOrderItem [xxxx], please complete the SubAdress
PLA_0009_ATrading Name is mandatoryplease complete your TradingName
PLA_0010_ATrading Name is not validTrading Name must not exceed 45 characters
PLA_0011_AThe SubAdress is not validPlease, complete a correct BuildingCode

Business rules for Resources

To be set in an order, the Resources must respect several rules, otherwise the order will be rejected. See below for more details:

CodeBusiness error messageDescription
RES_0001_AThe geographicSubAddress is not validReferencePto %s does not match with the [productOrder]'s geographicSubAddresses
RES_0002_AThe PTO reference xxx is unknowReferencePto %s not found for the quote's geographicSiteBuilding
RES_0003_AThe Reference PTO is not validNo ReferencePto found that match the productOrder's geographicSubAddresses

ExternalIdentifier

The externalIdentifier with the "externalIdentifierType": "customerIdentifier" is mandatory. Its value must not exceed 30 characters, be unique for each productOrder, and will not include the space character.

NameType / FormatDescriptionExampleMandatory
idString (30)Unique customer order reference"my-unique-order-ref"yes
externalIdentifierTypeStringshoud be customerIdentifier"customerIdentifier"yes
ownerString (255)name of your organization"ABSOLIGHT"yes
@typeStringshoud be ExternalIdentifier"ExternalIdentifier"yes

Example:

"externalIdentifier":[
   {
      "id":"myExternalId",
      "externalIdentifierType":"customerIdentifier",
      "owner":"myOrganization",
      "@type":"ExternalIdentifier"
   }
]

Appointment

NameType / FormatDescriptionExampleMandatory
idStringappointment reference value"IOC-BOA-44373567-0000015694579-ERDV"yes
hrefStringurl to get more information about the appointment"http://my-appointment-url"yes
@typeStringshoud be AppointmentRef"AppointmentRef"yes

Example:

"appointment": {
  "id": "IOC-BOA-44373567-0000015694579-ERDV",
  "href": "http://appointment-svc.appointment-management/api/v1/appointment/IOC-BOA-44373567-0000015694579-ERDV",
  "@type": "AppointmentRef"
}

To create an appointment, you should call the eRDV webservice (for more information, a documentation is available on your Espace opérateur: Mon compte> Mon espace documentaire).

Comment appointment: The comment of the appointment must be used to send information on the OT of the technician. You should use this comment to send information about address complement such as trading name, and also the contact of the relatedParty with role operatorDeliveryDriver (corresponding to the technical interlocutor of the operator). Note that by default, only the contact of the relatedParty with role operatorInterlocutor (operator interlocutor in charge of the follow and administration of orders) is send in the OT of the technician.

Business rules for Appointment

Others Appointment can be mandatory for an order. To be set in an order, the Appointment must respect several rules, otherwise the order will be rejected. See below for more details:

CodeBusiness error messageDescription
APO_0001_AThe appointment ID[xxx] is not consistent with ProductOrder configurationSeveral raisons for this case : (1)Product ID type of intervention incorrect characteristic. (2)The priority of the appointment is not the same in the order and in the appointment. (3)The service address is different from that indicated in the delivery address. The information relating to the appointment is incomplete (nature of the product, type of service). (4)The [xxx]deliveryWorkOrder role is not the same as the order creation role. When an appointment is created, the type of intervention must match the [xxx]role of type deliveryWorkOrder. (5)You must fill in the correct Installed Product Name
APO_0002_AThe appointment ID [xxxx] is not validThe appointment ID does not have a confirmed or initiated intervention. Please check the status of the intervention appointment with status [xxxx].
APO_0003_AThe appointment ID[xxxx] is not consistent with ProductOrder configurationThe [xxx]deliveryWorkOrder role is not the same as the order creation role. When an appointment is created, the type of intervention must match the [xxx]role of type deliveryWorkOrder . Or You must fill in the correct Installed Product Name
APO_0004_AThe appointment ID[xxx] is not consistent with ProductOrder configurationAn appointment is expected, please enter this in the order body
APO_0005_AThe appointment ID is not mandatory with ProductOrder configurationIn the case of a modification or cancellation, You have entered an appointment when this is not expected in the body of an order
APO_0006_AThe appointment ID %s is not valid because it 's a testIn the case of discovery environnement, you have fictitious IDs
APO_0007_AThe appointment ID is unknowThe appointment ID is unknown in the appointment database

OrderTerm

Depending on the configuration of the order, an orderTerm can be set (for exemple if a GTR is selected, an orderTerm is set). An orderTerm correspond to a commitment period and is a configuration defined by the API Catalog management. The orderTerm is set to the order after the order validation depending on the commitment duration selected in the order.

Example:

"itemTerm": [ 
    { 
        "description": "orderterm description ?", 
        "duration": { "amount": 12, "units": "month", "@type": "Quantity" }, 
        "name": "Garantie de Temps de Rétablissement", 
        "@type": "OrderTerm" 
    } 
]
NameType / FormatDescriptionMandatory
descriptionStringDescription of the ordertermyes
@durationStringThe duration is given in monthyes
@nameStringName of the orderTermyes
@typeStringordertermyes

Note

Error note

If an error is encountered during the validation process of the order, it is rejected and an error note is added. The list of the different business error message are listed in this document.

Example:

"note": [
    {
        "author": "System",
        "date": "2023-05-25T11:38:04+02:00",
        "text": "067 The individual bbbe65f7-32d4-4539-8efe-beac37e65d0c does not have the correct role",
        "@type": "errorNote"
    }
]
NameType / FormatDescriptionMandatory
authorStringauthoryes
datedateDate when the error was raisedyes
textStringCode and message of the business erroryes
@typeStringerrorNoteyes

Order note

You have the possibility to fill a comment when creating the order using the note. This comment is visible by anyone reading the order. Example:

"note": [
    {
        "author": "Comment author",
        "date": "2023-05-25T11:38:04+02:00",
        "text": "Order comment",
        "@type": "OrderTakingNote"
    }
]
NameType / FormatDescriptionMandatory
authorStringAuthor of the orderyes
datedateDate when the error was raisedyes
textStringCode and message of the business erroryes
@typeStringOrderTakingNoteyes

Notifications

Register listener

The registration of a listener is done by creating a HUB resource unique to the listener (equivalent of a subscription). The HUB resource is attached or bound to the API and its attribute specify the POST event callback address of the listener.

The hub is created via a POST api/hub call.

The POST call sets the communication endpoint address the service instance must use to deliver notifications (by default on all supported events). Note that a query expression may be supplied. The query expression may be used to filter specific event types and/or any content of the event. The query expression structure used for notification filtering is the same than the one used for queries i.e. GET.

Note that you must save the id returned at the end of the subscription as the get method is not available. The scope 'readonly' must be use to post and delete a hub.

POST /hub
Accept: application/json
{
  "callback": "https://listener.com"
}

Notification available

For the API order management, the following notifications are defined:

Notifications related to CancelProductOrder:

  • CancelProductOrderCreateEvent
  • CancelProductOrderStateChangeEvent
  • CancelProductOrderInformationRequiredEvent

Those notifications can be used to filter events. The example below shows how to register to a listener only for productorder creation:

{
  "callback": "https://listener.com",
  "query":"eventType = ProductOrderCreateEvent" 
}

Unregister listener

To unregister a listener, the HUB resource corresponding to the listener must be destroyed.

DELETE hub/{id}

This clears the communication endpoint address that was set by creating the Hub.

DELETE /api/hub/{id}
Accept: application/json

ProductOrder life cycle

Each ProductOrder follows a unique worklflow (state machine) with different states. See TMF documentation or below for more information.

ProductOrder Lifecycle

Warning: The productOrder api delivers the productOrder asynchronously. When the productOrder is POST you get a response with the status AKNOWLEGDED.INIT. When the productOrder is being initialized, it changes to the AKNOWLEGDED.ACCEPTED status. When the productOrder is being delivered, it changes to the INPROGRESS status When the productOrder could be executed without anomaly, it will have the COMPLETED status. If a problem occurs during the delivery process, a productOrder item status may be positionned to CANCELLED, FAILED, PENDING (an action from your part is needed), HELD (temporary technical issue) and error notes will be posted at the appropriate level of the productOrder structure.

** It is not possible to PATCH the status of the productOrder. if an error has occurred on your productOrder, you must create a new one via the POST method**

ProductOrderItem life cycle

Each ProductOrder item follows a unique worklflow (state machine) with different states. See TMF documentation or below for more informations.

ProductOrderItem Lifecycle

Warning: The Product Ordering Management API delivers the productOrder items asynchronously. When the productOrder item are POST you get a response with the status AKNOWLEGDED.INIT. When the productOrder item is being initialized, it changes to the AKNOWLEGDED.ACCEPTED status. When the productOrder item is being delivered, it changes to the INPROGRESS status When the productOrder item could be executed without anomaly, it will have the COMPLETED status. If a problem occurs during the delivery process, a productOrder item status may be positionned to CANCELLED, FAILED, PENDING (an action from your part is needed), HELD (temporary technical issue) and error notes will be posted at the appropriate level of the productOrder structure.

CancelProductOrder life cycle

Each CancelProductOrder follows a unique worklflow (state machine) with different states. See TMF documentation or below for more informations.

CancelProductOrder Lifecycle

Query Resources patterns

Query Resources with attribute selection

In every GET request, you can add a fields parameters to filter the response body with a subset of attributes.

Example:

GET /api/v1/productOrder?fields=description,orderDate
[
   {
      "description":"ProductOrder illustration Ariane",
      "href":null,
      "id":"e7dee14c-cd85-495a-9931-ef3c06f2559b",
      "orderDate":"2021-07-22T11:27:22.000+02:00"
   },
   {
      "description":"ProductOrder illustration Ariane",
      "href":null,
      "id":"37cf411f-5258-409a-9703-66cf965c9f43",
      "orderDate":"2021-07-22T11:27:29.000+02:00"
   }
]

To improve response time, only request fields that you really need. Especially when requesting a list of productOrder.

Note that attributes id and href are always returned, even if fields=none.

Query Resources with attribute filtering

According to TMF630 REST API Design Guidelines, you can filter data by specifying attributes in the querystring. However, not all attributes can be used as a filter criteria. Herein, the exhaustive list of available filtering parameters with the associated allowed operators:

  • id
  • description
  • state
  • productOrderSpecification
  • href
  • orderDate
  • agreement.id
  • agreement.href
  • productOrderItem
  • productOrderItem.id
  • productOrderItem.product.productOffering.id
  • externalIdentifier.id
  • externalIdentifier

The operations available for the attributes (date, integer and string) are:

  • = or .eq= : equal to
  • >= or .gte= : greater than or equal to
  • > or .gt= : strictly greater than
  • <= or .lte= : lower than or equal to
  • < or .lt= : strictly lower than
  • <> or .ne= : Not equal

Example:

GET /api/v1/productOrder?fields=state&state=INPROGRESS&orderDate.gt=2013-04-20
[
    {
        "href": "/api/v1/productOrder/2a89ed67-5cf8-429d-9a3d-5153d481ff55",
        "id": "2a89ed67-5cf8-429d-9a3d-5153d481ff55",
        "state": "INPROGRESS"
    },
    {
        "href": "/api/v1/productOrder/7f8bb1aa-da62-41e6-be85-38b6f42827ae",
        "id": "7f8bb1aa-da62-41e6-be85-38b6f42827ae",
        "state": "INPROGRESS"
    },
    {
        "href": "/api/v1/productOrder/0f9e6ecd-2bee-4448-b0cb-c6cdb29bccb7",
        "id": "0f9e6ecd-2bee-4448-b0cb-c6cdb29bccb7",
        "state": "INPROGRESS"
    }
]

For detailed information on parameters, check the API reference

Query Resources with iterators

When requesting collections, you should set pagination query parameters.

  • offset: Requested index for start of resources to be provided in response requested by client.
  • limit: Requested number of resources to be provided in response requested by client.

After each request, explore the http headers to retrieve the number of results

  • X-Result-Count: The number of matching resources in the JSON response.
  • X-Total-Count: The total number of matching resources.

If X-Total-Count is bigger than X-Result-Count, you need to request again by incrementing the offset query parameter with the X-Result-Count value. You can limit the number of result per page with limit.

Note that you can't request more result per page than the default. Be sure to read the header X-Result-Count.

For example, to retrieve only the second element in the list

GET /api/v1/productOrder?fields=none&limit=1&offset=1
[
    {
        "id": "9240353c-cd38-447c-9437-9d4aa229d5ff",
        "href": "/api/v1/productOrder/9240353c-cd38-447c-9437-9d4aa229d5ff"
    }
]

Accept-Range is ignored.

Sorting

The query parameter sort is used to order resources to be provided in response (used - if you want descending).

Example:

GET /api/v1/productOrder?fields=state&sort=-orderDate
[
    {
        "href": null,
        "id": "7f8bb1aa-da62-41e6-be85-38b6f42827ae",
        "state": "INPROGRESS"
    },
    {
        "href": null,
        "id": "0f9e6ecd-2bee-4448-b0cb-c6cdb29bccb7",
        "state": "INPROGRESS"
    }
]

Errors

Failure to code a proper management of the error responses in your application may affect its resilience. Access to the API may be revoked if your application generates too many mishandled errors.

Your application must parse the returned HTTP response to check if an error is returned instead of a 200 OK. Orange APIs uses appropriate HTTP status codes to indicate any request processing error, providing detailed information about the underlying fault. This helps you provide better feedback to your users and implement failure recovery mechanisms in your application.

For details on the main error codes, response format, tips and troubleshooting, see our Handling API errors guide

Errors 401

If you get a status code 401 with the error code 42 (such as below), then you have to request a new access token.

HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
  "code": 42,
  "message": "Expired credentials",
  "description": "The requested service needs credentials, and the ones provided
  were out-of-date."
}

Token lifetime

  • Each access_token has a lifetime validity period. This validity period may change overtime to comply with security rules.
  • The token server has a maximum hourly quota per client application to prevent from misuse. Therefore, DON'T request an access_token each time you invoke the service API. DON'T hard-code a validity duration in your application. Instead, your application must parse the returned status code and error code to check if it needs to request a new access token.

For other 401 errors: check that you provide the right Authorization header with the right Bearer

Errors 400

In case of invalid request, you will receive a 400 error code with detailed information in the body message, such as:

HTTP/1.1 400 Bad Request
{
  "code": 25,
  "description": "Missing header",
  "message": "...."
}

Errors 404

If you try to access to a non-existent productOrder using the following endpoint : GET productorder/{id}:

HTTP/1.1 404 Not Found
{
    "code": "60",
    "message": "No entity found with ID 'sdfsd'!",
    "reason": "Resource not found",
    "@type": "Error"
}

Others

Below you can find a table with the http codes and their respective functional codes and messages :

HTTP error codeQuotify code errorerror message
40020Invalid URL parameter value
40021Missing body
40022Invalid body
40023Missing body field
40024Invalid body field
40025Missing header
40026Invalid header value
40027Missing query-string parameter
40028Invalid query-string parameter value
40140Missing credentials
40141Invalid credentials
40142Expired credentials
40350Access denied
40351Forbidden requester
40352Forbidden user
40353Too many requests
40460Resource not found
40561Method not allowed
40662Not acceptable
40863Request time-out
40969Conflict
41164Length required
41265Precondition failed
41366Request entity too large
41467Request-URI too long
41568Unsupported Media Type
42953Too many requests
5001Internal Server Error
5021Internal error
5023Bad gateway
5035The service is temporarily unavailable
5036Orange API is over capacity, retry later !

Use cases

1. I want to make an order with the productOrder API

I am in a sales administration team, I want to fill the needed information to send a new productorder for a product offering from sccatch. The following 3 steps are recommanded.

Understand a catalog offer

Catalog Offer Description

A catalog offer is composed of several bundles and Product Offering with relationships. A catalog offer is built in 4 levels of product offering:

  • level 1: Contract
  • level 2: Play
  • level 3: Set
  • level 4: AtomicOffer

See below an example of a possible catalog offer structuration

ContractPlaySetAtomic OfferRelationships
ProductOffering Contract 1bundles "productOffering Play
productOffering Play 1bundles "productOffering Set 1"
productOffering Set 1bundles "productOffering AtomicOffer 1", "productOffering AtomicOffer 2" and "productOffering AtomicOffer 3"
productOffering AtomicOffer 1
productOffering AtomicOffer 2
productOffering AtomicOffer 3
productOffering Set 2bundles "productOffering AtomicOffer 4"
productOffering AtomicOffer 4
Visual representation of a catalog offer

Catalog's Offer representation

As we can see the Catalog Offer is built like a tree and some of his items are mandatory to create a productOrder, the other one are optionals.

Find a catalog offer

To generate the productOrder you must first target an offer in the catalog, this action can be done by requesting the contract level productOffering in the catalog:

GET api/catalog/productOffering/<productOfferingId>/catalog

This request return catagories, productofferings, productSpecifications and productOfferingPrice. These elements will help you to generate the content of the productOrder.

{
  "categories":[...],
  "productOfferings":[...],
  "productSpecifications":[...],
  "productOfferingPrices":[...]
}

Building a productOrder

add mandatory attribute to the productOrder

set to the productOrder:

  • "productOrderSpecification": "Acquisition"
{
  "productOrderSpecification": "Acquisition",
  ...
}

set your organization information into the RelatedParty (see chapter on resource relatedParty to know how to get it)

{
    "externalIdentifier": [
        {
            "id": "myExternalId",
            "externalIdentifierType": "customerIdentifier",
            "owner": "myOrganization",
            "@type": "ExternalIdentifier"
        }
    ],
    "instantSyncProductOrder": false,
    "productorderSpecification": "Acquisition"
    "relatedParty": [
        {
            "@referredType": "organization",
            "id": "ea69228c-600a-4058-8e4e-e13fcc8bf89f",
            "name": "ABSOLIGHT",
            "role": "buyer"
        }
    ],
    ...
}
create a productOrderItem with a productOffering

Add into the productOrderItem list a productOrderItem with:

  • id: a unique id of your choice
  • action: add
  • a product with a productOffering from the catalog response

Example

{
  "externalIdentifier": [
    {
      "id": "myExternalId",
      "externalIdentifierType": "customerIdentifier",
      "owner": "myOrganization",
      "@type": "ExternalIdentifier"
    }
  ],
  "instantSyncProductOrder": false,
  "productOrderSpecification": "Acquisition",
  "relatedParty": [
    {
      "@referredType": "organization",
      "id": "ea69228c-600a-4058-8e4e-e13fcc8bf89f",
      "name": "ABSOLIGHT",
      "role": "buyer"
    }
  ],
  "productOrderItem": [
    {
      "action": "add",
      "id": "GOC40140084001",
      "product": {
        "productOffering": {
          "id": "GOC40140084001",
          "name": "Just Fibre TEST"
        }
      }
    }
  ]
}

To find the productOffering id search it into the list of productOfferings from catalog response:

...
"productOfferings":[
{
  "id":"GOC40140084001",
  "href":"http://cae-owf-ventes.caas-cnp-apps.com.intraorange/catalog/api/catalog/productOffering/GOC40140084001",
  "name":"Just Fibre TEST",
  "shortName":"Just Fibre TEST",
  "category":[],
  "bundledProductOffering":[],
  "visible":"true",
  "isTopLevel":true,
  "isBundle":true,
  "isFulfillable":true,
  "isInstallable":true,
  "productOfferingType":"contract",
  "externalIdentifier":[],
  "viewProperty":{},
  "otherProperty":[]
},
...
create a productOrderItem with a place

To check the geographical eligibility of your productOrder, you must submit a place of type GeographicSiteBuilding with a buildingCode and a role deliveryAddress into the product of the productOrderItem which contains the productOffering of type contract.

This rule is defined by the catalog into the productOffering of type contract in the otherProperties list by an element with id operationSpecification.Acquisition which contains a value expectedPlace.deliveryAddress:geographicSiteBuilding (see below).

{
  "id":"GOC40140084001",
  "href":"http://cae-owf-ventes.caas-cnp-apps.com.intraorange/catalog/api/catalog/productOffering/GOC40140084001",
  "name":"Just Fibre TEST",
  "shortName":"Just Fibre TEST",
  "productOfferingType":"contract",
  ...
  "otherProperty":[
    {
      "id":"operationSpecification.Acquisition",
      "multiplesValues":[
        "expectedPlace.deliveryAddress:geographicSiteBuilding",
        "expectedSubAddress:true"
        ...
        },
        ...
      ]
      ...
}

The expectedSubAddress:true value explains that sub address informations (building, staircase, floor) are mandatory (see chapter on resource GeographicSubAddress to know how to get it)

Example

{
  "externalIdentifier": [
    {
      "id": "myExternalId",
      "externalIdentifierType": "customerIdentifier",
      "owner": "myOrganization",
      "@type": "ExternalIdentifier"
    }
  ],
  "instantSyncProductOrder": false,
  "productorderSpecification": "Acquisition",
  "relatedParty": [
    {
      "@referredType": "organization",
      "id": "ea69228c-600a-4058-8e4e-e13fcc8bf89f",
      "name": "ABSOLIGHT",
      "role": "buyer"
    }
  ],
  "productOrderItem": [
    {
      "action": "add",
      "id": "GOC40140084001",
      "product": {
        "place": [
          {
            "@type": "GeographicSiteBuilding",
            "role": "deliveryAddress",
            "geographicAddress": [
              {
                "@type": "GeographicAddress",
                "geographicSubAddress": [
                  {
                    "buildingName": "OULLINS C",
                    "@type": "GeographicSubAddress"
                  },
                  {
                    "levelNumber": "_NA_",
                    "levelType": "staircase",
                    "@type": "GeographicSubAddress"
                  },
                  {
                    "levelNumber": "0",
                    "levelType": "floor",
                    "@type": "GeographicSubAddress"
                  }
                ]
              }
            ],
            "buildingCode": "IMB/69149/C/ZJU1"
          }
        ],
        "productOffering": {
          "id": "GOC40140084001",
          "name": "Just Fibre TEST"
        }
      }
    }
  ]
}
create a productOrderItem with a productOrderItemRelationship

The relation between every productOffering with productOfferingType: contract, play, set and atomicOffer is done by productOrderItemRelationship into the productOrderItem.

If the catalog productOffering contains bundledProductOffering like this:

{
  "id":"GOC40140084001",
  "href":"http://cae-owf-ventes.caas-cnp-apps.com.intraorange/catalog/api/catalog/productOffering/GOC40140084001",
  "name":"Just Fibre TEST",
  "shortName":"Just Fibre TEST",
  "productOfferingType":"contract",
  ...
  "bundledProductOffering":[
    {
      "id":"OC40140084001",
      "href":"http://cae-owf-ventes.caas-cnp-apps.com.intraorange/catalog/api/catalog/productOffering/OC40140084001",
      "name":"Just Fibre TEST"
    }
  ],
  ...

add into the productOrderItem a productOrderItemRelationship like this:

Example

{
  "productorderSpecification": "Acquisition",
  "relatedParty": [
    {
      "@referredType": "organization",
      "id": "ea69228c-600a-4058-8e4e-e13fcc8bf89f",
      "name": "ABSOLIGHT",
      "role": "buyer"
    }
  ],
  "productOrderItem": [
    {
      "action": "add",
      "id": "GOC40140084001",
      "product": {
        "place": [
          {
            "@type": "GeographicSiteBuilding",
            "role": "deliveryAddress",
            ...
          }
        ],
        "productOffering": {
          "id": "GOC40140084001",
          "name": "Just Fibre TEST"
        }
      },
      "productOrderItemRelationship": [
        {
          "id": "OC40140084001",
          "relationshipType": "bundles"
        }
      ]
    },
    {
      "action": "add",
      "id": "OC40140084001",
      "product": {
        "productOffering": {
          "id": "OC40140084001",
          "name": "Just Fibre TEST"
        }
      }
    }
  ]
}

Warning: if you add a productOrderItemRelationship into a productOrderItem you shoud add a dedicated productOrderItem for the declaration (see previous example).

create a productOrderItem with productCharacteristic

If the catalog productOffering is a "productOfferingType":"atomicOffer" with "isBundle":false you should set productCharacteristic into the product of the productOrderItem.

To find available characteristics for this productOffering get the productSpecification.id and search it into the productSpecifications list of the catalog response (see below)

"productSpecifications":[
   {
      "id":"PS40140084001",
      "href":"http://cae-owf-ventes.caas-cnp-apps.com.intraorange/catalog/api/catalog/productSpecification/PS40140084001",
      "version":"1",
      "name":"Activation des ressources",
      "productSpecCharacteristic":[
         {
            "id":"FONC40140084004",
            "href":"http://cae-owf-ventes.caas-cnp-apps.com.intraorange/catalog/api/catalog/productSpecCharacteristic/FONC40140084004",
            "name":"Débit d'accès Montant/Descendant",
            "visible":"true",
            "configurable":"false",
            "productSpecCharacteristicValue":[
               {
                  "systemValueCode":"VF0000140140084004",
                  "value":"300M/300M",
                  "externalIdentifier":[
                     {
                        "referentialId":"SI_OWF",
                        "id":"300.0"
                     }
                  ],
                  "property":{
                     "id":"VALEUR_DEBIT",
                     "simpleValue":"300.0"
                  }
               },
               {
                  "systemValueCode":"VF0000240140084004",
                  "value":"400M/1000M",
                  "externalIdentifier":[
                     {
                        "referentialId":"SI_OWF",
                        "id":"1000.0"
                     }
                  ],
                  "property":{
                     "id":"VALEUR_DEBIT",
                     "simpleValue":"1000.0"
                  }
               }
            ]
         }
      ]
   }
]

Example of productOrderItem with characteristics

{
   "productorderSpecification":"Acquisition",
   "relatedParty":[
      {
         "@referredType":"organization",
         "id":"ea69228c-600a-4058-8e4e-e13fcc8bf89f",
         "name":"ABSOLIGHT",
         "role":"buyer"
      }
   ],
   "productOrderItem":[
      {
         "action":"add",
         "id":"O40140084001",
         "product":{
            "productOffering":{
               "id":"O40140084001",
               "name":"Accès"
            },
            "productCharacteristic":[
               {
                  "id":"FONC40140084004",
                  "valueType":"object",
                  "name":"Débit d'accès Montant/Descendant",
                  "value":{
                     "@type":"CharacteristicChoiceValue",
                     "id":"VF0000140140084004",
                     "name":"300M/300M"
                  }
               },
               {
                  "id":"FONC40140084005",
                  "valueType":"object",
                  "name":"VLAN",
                  "value":{
                     "@type":"CharacteristicChoiceValue",
                     "id":"VF0000240140084005",
                     "name":"Sans TAG"
                  }
               }
            ]
         }
      }
   ]
}

Warning: If the catalog productSpecCharacteristic have the "valueType": "string" the productCharacteristic format in the productOrderItem is:

{
   "id": "FONC40140084011",
   "valueType": "string",
   "name": "Référence PTO",
   "value": "XXXXXXXXX"
}

If the catalog productSpecCharacteristic have a productSpecCharacteristicValue list, the productCharacteristic format in the productOrderItem is:

{
   "id": "FONC40140084004",
   "valueType": "object",
   "name": "Débit d'accès Montant/Descendant",
   "value": {
       "@type": "CharacteristicChoiceValue",
       "id": "VF0000140140084004",
       "name": "300M/300M"
   }
}
create a productOrderItem with productRelationship

In special case a productOffering need a relationship to a product from the inventory (this is the case for offers where you must have already subscribed to a product to make a quotation).

If the catalog productOffering contains a productOfferingRelationship you must specify a productRelationship in the product of the productOrderItem.

Example of productOfferingRelationship on productOffering catalog

{
  "id": "O40140084001",
  "href": "http://cae-owf-ventes.caas-cnp-apps.com.intraorange/catalog/api/catalog/productOffering/O40140084001",
  "name": "Accès",
  "shortName": "Accès",
  "visible": "true",
  "productOfferingType": "atomicOffer",
  "productOfferingRelationship": [
    {
      "id": "O40160084003",
      "name": "Collecte régionale",
      "relationshipType": "reliesOn",
      "validFor": {
        "startDate": "2000-12-31T23:00:00.000+0000"
      }
    },
    {
      "id": "O40160085001",
      "name": "Collecte nationale",
      "relationshipType": "reliesOn",
      "validFor": {
        "startDate": "2000-12-31T23:00:00.000+0000"
      }
    },
    {
      "id": "O40160086001",
      "name": "Collecte DROM - métropole",
      "relationshipType": "reliesOn",
      "validFor": {
        "startDate": "2000-12-31T23:00:00.000+0000"
      }
    },
    ...
  ],
  ...
}

To retrieve a product.id to set in the productRelationship of the productOrderItem, you should call the Product Inventory Management API with this sample request based on previous sample:

GET /api/v1/product?productOffering.id=O40160084003,O40160085001,O40160086001&fields=id
[
  {
    "id": "2c9797447e05ac18017e252187b50025",
    "href": "/api/v1/product/2c9797447e05ac18017e252187b50025"
  },
  {
    "id": "2c9004647f69a6da017f6a1c577c0001",
    "href": "/api/v1/product/2c9004647f69a6da017f6a1c577c0001"
  },
  ...
]

After Get the reponse from inventory, choose your product.id to set into the productRelationship and don't forget to set the relationshipType according the catalog relationshipType.

Example of productOrderItem with productRelationship

{
  "productorderSpecification": "Acquisition",
  "relatedParty": [
    {
      "@referredType": "organization",
      "id": "ea69228c-600a-4058-8e4e-e13fcc8bf89f",
      "name": "ABSOLIGHT",
      "role": "buyer"
    }
  ],
  "productOrderItem": [
    {
      "action": "add",
      "id": "O40140084001",
      "product": {
        "productOffering": {
          "id": "O40140084001",
          "name": "Accès"
        },
        "productCharacteristic": [
          {
            "id": "FONC40140084004",
            "valueType": "object",
            "name": "Débit d'accès Montant/Descendant",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000140140084004",
              "name": "300M/300M"
            }
          },
          {
            "id": "FONC40140084005",
            "valueType": "object",
            "name": "VLAN",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000240140084005",
              "name": "Sans TAG"
            }
          }
        ],
        "productRelationship": [
          {
            "relationshipType": "reliesOn",
            "product": {
              "id": "2c9797447e05ac18017e252187b50025"
            }
          }
        ]
      }
    },
    ...
  ]
}

Create productOrder

When the content of your productOrder is completed, you can do a POST. Don't forget to use an access_token with owf:united-way:product-order:v1:write scope.

POST /productorder
Content-Type: application/json
{
  "externalIdentifier": [
    {
      "id": "myExternalId",
      "externalIdentifierType": "customerIdentifier",
      "owner": "myOrganization",
      "@type": "ExternalIdentifier"
    }
  ],
  "productOrderItem": [
    {
      "action": "add",
      "id": "GOC40140084001",
      "product": {
        "place": [
          {
            "@type": "GeographicSiteBuilding",
            "role": "deliveryAddress",
            "geographicAddress": [
              {
                "@type": "GeographicAddress",
                "geographicSubAddress": [
                  {
                    "buildingName": "OULLINS C",
                    "@type": "GeographicSubAddress"
                  },
                  {
                    "levelNumber": "_NA_",
                    "levelType": "staircase",
                    "@type": "GeographicSubAddress"
                  },
                  {
                    "levelNumber": "0",
                    "levelType": "floor",
                    "@type": "GeographicSubAddress"
                  }
                ]
              }
            ],
            "buildingCode": "IMB/69149/C/ZJU1"
          }
        ],
        "productOffering": {
          "id": "GOC40140084001",
          "name": "Just Fibre TEST"
        }
      },
      "productOrderItemRelationship": [
        {
          "id": "OC40140084001",
          "relationshipType": "bundles"
        }
      ]
    },
    {
      "action": "add",
      "id": "OC40140084001",
      "product": {
        "productOffering": {
          "id": "OC40140084001",
          "name": "Just Fibre TEST"
        }
      },
      "productOrderItemRelationship": [
        {
          "id": "GO40140084001",
          "relationshipType": "bundles"
        },
        {
          "id": "GO40140084002",
          "relationshipType": "bundles"
        },
        {
          "id": "GO40140084003",
          "relationshipType": "bundles"
        },
        {
          "id": "GO40140084004",
          "relationshipType": "bundles"
        }
      ]
    },
    {
      "action": "add",
      "id": "GO40140084001",
      "product": {
        "productOffering": {
          "id": "GO40140084001",
          "name": "Caractéristiques principales"
        }
      },
      "productOrderItemRelationship": [
        {
          "id": "O40140084001",
          "relationshipType": "bundles"
        }
      ]
    },
    {
      "action": "add",
      "id": "O40140084001",
      "product": {
        "productOffering": {
          "id": "O40140084001",
          "name": "Accès"
        },
        "productCharacteristic": [
          {
            "id": "FONC40140084004",
            "valueType": "object",
            "name": "Débit d'accès Montant/Descendant",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000140140084004",
              "name": "300M/300M"
            }
          },
          {
            "id": "FONC40140084005",
            "valueType": "object",
            "name": "VLAN",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000240140084005",
              "name": "Sans TAG"
            }
          }
        ],
        "productRelationship": [
          {
            "relationshipType": "reliesOn",
            "product": {
              "id": "2c9797447e05ac18017e252187b50025"
            }
          }
        ]
      }
    },
    {
      "action": "add",
      "id": "GO40140084002",
      "product": {
        "productOffering": {
          "id": "GO40140084002",
          "name": "Point de livraison sur site client final"
        }
      },
      "productOrderItemRelationship": [
        {
          "id": "O40140084008",
          "relationshipType": "bundles"
        }
      ]
    },
    {
      "action": "add",
      "id": "O40140084008",
      "product": {
        "productOffering": {
          "id": "O40140084008",
          "name": "Raccordement"
        },
        "productCharacteristic": [
          {
            "id": "FONC40140084010",
            "valueType": "object",
            "name": "Type de point de livraison",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000140140084010",
              "name": "DTIO/PTO"
            }
          },
          {
            "id": "FONC40140084008",
            "valueType": "object",
            "name": "Multi-accès",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000240140084008",
              "name": "Non"
            }
          },
          {
            "id": "FONC40140084003",
            "valueType": "object",
            "name": "Type de raccordement",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000140140084003",
              "name": "Raccordement sur prise existante"
            }
          },
          {
            "id": "FONC40140084011",
            "valueType": "string",
            "name": "Référence PTO",
            "value": "FI-9786-6362"
          }
        ]
      }
    },
    {
      "action": "add",
      "id": "GO40140084003",
      "product": {
        "productOffering": {
          "id": "GO40140084003",
          "name": "Interface de livraison sur site client final"
        }
      },
      "productOrderItemRelationship": [
        {
          "id": "O40140084004",
          "relationshipType": "bundles"
        }
      ]
    },
    {
      "action": "add",
      "id": "O40140084004",
      "product": {
        "productOffering": {
          "id": "O40140084004",
          "name": "ONT éxpédié par Orange"
        },
        "productCharacteristic": [
          {
            "id": "FONC40140084015",
            "valueType": "object",
            "name": "Modèle ONT",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000140140084015",
              "name": "Modèle 1 Gbps"
            }
          },
          {
            "id": "FONC40140084014",
            "valueType": "object",
            "name": "ONT installé par Orange",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000140140084014",
              "name": "Oui"
            }
          }
        ]
      }
    },
    {
      "action": "add",
      "id": "GO40140084004",
      "product": {
        "productOffering": {
          "id": "GO40140084004",
          "name": "Intervention"
        }
      },
      "productOrderItemRelationship": [
        {
          "id": "O40140084005",
          "relationshipType": "bundles"
        }
      ]
    },
    {
      "action": "add",
      "id": "O40140084005",
      "product": {
        "productOffering": {
          "id": "O40140084005",
          "name": "Intervention"
        },
        "productCharacteristic": [
          {
            "id": "FONC40140084007",
            "valueType": "object",
            "name": "Type d'intervention",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000140140084007",
              "name": "Standard"
            }
          },
          {
            "id": "FONC40990080002",
            "valueType": "object",
            "name": "Intervention",
            "value": {
              "@type": "CharacteristicChoiceValue",
              "id": "VF0000840990080002",
              "name": "Intervention avec pose ONT : Prise Optique présente"
            }
          }
        ]
      }
    }
  ],
  "relatedParty": [
    {
      "@referredType": "organization",
      "id": "ea69228c-600a-4058-8e4e-e13fcc8bf89f",
      "name": "Jean Pontus",
      "role": "buyer"
    }
  ],
  "productorderSpecification": "Acquisition"
}
HTTP/1.1 201 Created
Location: /productOrder/de76cfa1-9a55-412f-a9ee-61ca2f662a63

In the response body some attributes will automatically be added, including:

  • id
  • href
  • state (The state follows the lifecycle presented above)
  • expectedFulfillmentStartDate
  • expectedCompletionDate
  • requestedCompletionDate
  • orderDate

If the payload is not valid, server will return a 400.

HTTP/1.1 400 Bad Request
{
  "code": "1",
  "message": "error message",
  "reason": "reason message",
  "@type": "Error"
}

2. I want to follow up my productOrder

To follow the productOrder state, you can do a GET on the resource /productOrder/{id}. Don't forget to use an access_token with owf:united-way:product-order:v1:write scope.

GET /productOrder/de76cfa1-9a55-412f-a9ee-61ca2f662a63
HTTP/1.1 200 OK
{
  "id": "de76cfa1-9a55-412f-a9ee-61ca2f662a63",
  ...
  "state": "INPROGRESS",
  ...
}

ProductOrder and ProductOrderItem states

My productOrder has a state that follows the productOrder's lifecycle.

StateTypeDescription
acknowledgedinitialisationproductOrder being validated
inProgress.acceptedinitialisationproductOrder delivery initialisation
inProgressdeliveryproductOrder ongoing delivery
completedfinalproductOrder delivered
assessingCancellationcancellationproductOrder cancellation request under validation
pendingCancellationcancellationproductOrder cancellation in progress
cancelledfinal koproductOrder cancelled
rejectedfinal koproductOrder rejected
failedfinal koproductOrder delivery failed

Each productOrderItem composing my productOrder also has its own state that follows the productOrderItems's lifecycle.

StateTypeDescription
acknowledgedinitialisationproductOrderItem being validated
inProgress.acceptedinitialisationproductOrderItem delivery initialisation
inProgressdeliveryproductOrderItem ongoing delivery
pendingdeliveryproductOrderItem has encountered a delivery issue, and require an action from your side
helddeliveryproductOrderItem has encountered a delivery issue, managed by Orange
completedfinalproductOrderItem delivered
assessingCancellationcancellationproductOrderItem cancellation request under validation
pendingCancellationcancellationproductOrderItem cancellation in progress
cancelledfinal koproductOrderItem cancelled
rejectedfinal koproductOrderItem rejected
failedfinal koproductOrderItem delivery failed

ProductOrder and ProductOrderItem milestones / errorMessages

During the delivery process, additional follow-up information will be provided, using milestones, errorMessages and jeopardyAlert arrays, attached to the productOrder or to the relevant productOderItem.

For example, on a productOrderItem, you mais have the following information :

 {
  ...
  "state": "inProgress",
  "jeopardyAlert": [],
  "milestone": [
    {
      "description": "Orange a bien reçu votre commande. Celle-ci est en cours de validation",
      "message": "Validation de la commande en cours",
      "milestoneDate": "2022-09-30T14:26:23+02:00",
      "name": "FTTH",
      "status": "completed",
      "@type": "Milestone"
    },
    {
      "description": "Votre commande a été validée, elle est désormais en cours de production",
      "message": "En cours de production",
      "milestoneDate": "2022-10-01T10:06:17+02:00",
      "name": "FTTH",
      "status": "completed",
      "@type": "Milestone"
    },
    {
      "message": "ICC : DSART162!10!FTT!04/05/33/0/1:835#xxx, SLID : xxxx",
      "milestoneDate": "2022-10-01T10:06:17+02:00",
      "name": "FTTH",
      "status": "completed",
      "@type": "Milestone"
    }
  ],
  "errorMessage": [
    {
      "message": "Suite à l'échec de l'intervention, une nouvelle étude technique est nécessaire. A l'issue de la réparation, vous pourrez reprendre un rendez-vous.",
      "reason": "OWF",
      "status": "closed",
      "timestamp": "2022-10-14T19:06:19+02:00",
      "@type": "ErrorMessage"
    },
    {
      "message": "Suite à l'échec de l'intervention, une nouvelle étude technique est nécessaire. A l'issue de la réparation, vous pourrez reprendre un rendez-vous.",
      "reason": "OWF",
      "status": "opened",
      "timestamp": "2022-10-14T19:06:25+02:00",
      "@type": "ErrorMessage"
    },
    {
      "message": "Rendez-vous à reprendre",
      "reason": "ORT",
      "status": "opened",
      "timestamp": "2022-10-19T10:06:19+02:00",
      "@type": "ErrorMessage"
    }
  ],
  "itemTotalPrice": [],
  "@type": "ProductOrderItem"
}
  • Milestones are only informational, and will always have a "completed" status
  • ErrorMessages describe an issue encountered during the delivery process. An active errorMessage will have an "opened" status, which will be "closed" when the issue is solved.
  • jeopardyAlerts are currently not used.

3. I want to cancel an ongoing productOrder

POST /cancelProductOrder
{
  "cancellationReason": "Rétractation client",
  "effectiveCancellationDate": "2021-08-25T23:03:25.098Z",
  "productOrder": {
    "id": "de76cfa1-9a55-412f-a9ee-61ca2f662a63",
    "href": "...",
    "name": "Product Order to be cancelled 5",
    "@type": "ProductOrder"
  },
  "@type": "cancelProductOrder"
}
HTTP/1.1 201 Created
{
  "id": "1",
  "cancellationReason": "Rétractation client",
  "effectiveCancellationDate": "2021-08-25T23:03:25.098Z",
  "productOrder": {
    "id": "de76cfa1-9a55-412f-a9ee-61ca2f662a63",
    "href": "...",
    "name": "Product Order to be cancelled 5",
    "@type": "ProductOrder"
  },
  "@type": "cancelProductOrder"
}

4. I want to get a productOrderItem

GET /productOrder/de76cfa1-9a55-412f-a9ee-61ca2f662a63/productOrderItem/O40140084001
HTTP/1.1 200 OK
{
  "id": "O40140084001",
  "action": "add",
  "state": "inProgress.accepted",
  "product": {
    "productOffering": {
      "id": "O40140084001",
      "name": "Accès"
    },
    "productCharacteristic": [
      {
        "id": "FONC40140084004",
        "valueType": "object",
        "name": "Débit d'accès Montant/Descendant",
        "value": {
          "@type": "CharacteristicChoiceValue",
          "id": "VF0000140140084004",
          "name": "300M/300M"
        }
      },
      {
        "id": "FONC40140084005",
        "valueType": "object",
        "name": "VLAN",
        "value": {
          "@type": "CharacteristicChoiceValue",
          "id": "VF0000240140084005",
          "name": "Sans TAG"
        }
      }
    ],
    "productRelationship": [
      {
        "relationshipType": "reliesOn",
        "product": {
          "id": "2c9797447e05ac18017e252187b50025"
        }
      }
    ]
  }
}

5. I want to terminate an active access

To terminate an active access, a dedicated termination productOrder must be sent.

Don't forget to use an access_token with owf:united-way:product-order:v1:write scope.

POST /productorder
Content-Type: application/json

This termination productOrder must include :

  • characteristic : "productOrderSpecification" set to Termination
  • section : "externalIdentifier" relative to your company order
  • section : "productOrderItem" of contract-level
    • characteristic action set to delete
  • section "relatedParty" relative to the buyer

Note : you should call the Product Inventory Management API to retrieve the structure of the existing product

{
    "description": "ProductOrder Résil from API - ABA",
    "productOrderSpecification": "Termination",
    "externalIdentifier": [
        {
            "id": "MYCOMPANY-ORDER-ID",
            "externalIdentifierType": "customerIdentifier",
            "owner": "MYCOMPANY"
        }
    ],
    "productOrderItem": [
        {
            "id": "2c9280828682d8590186c0abe12b06xx",
            "isBundle": true,
            "action": "delete",
            "product": {
                "id": "2c9280828682d8590186c0abe12b06xx",
                "productOffering": {
                    "id": "GOC40140084001",
                    "name": "FTTH Access",
                    "productOfferingType": "contract"
                },
                "agreement": [
                    {
                        "id": "TESTFTTHAcess1"
                    }
                ],
                "relatedParty": [
                    {
                        "id": "1563c17f-3c37-4c31-9642-xxxxxxxxx",
                        "role": "operatorInterlocutor",
                        "@baseType": "RelatedParty",
                        "@referredType": "Individual"
                    }
                ]
            }
        }
    ],
    "relatedParty": [
        {
            "id": "8f4ac814-5072-4519-9e8c-xxxxx",
            "role": "buyer",
            "@referredType": "organization",
            "name": "MYCOMPANY"
        }
    ]
}

6. I want to modify a characteristic on an active access

To modify an active access SpeedCos characteristic, a dedicated modification productOrder must be sent.

Don't forget to use an access_token with owf:united-way:product-order:v1:write scope.

POST /productorder
Content-Type: application/json

This modification productOrder must include :

  • characteristic : "productOrderSpecification" set to speedCosModification
  • section : "externalIdentifier" relative to your company order
  • section : "productOrderItem" of contract-level with action set to noChange
  • section : "productOrderItem" of play-level with action set to noChange
  • section : "productOrderItem" of set-level with action set to noChange
  • section : "productOrderItem" relative to the modified product
    • characteristic action set to modify
    • the product.id to be modified
    • the new productCharacteristic description
  • section "relatedParty" relative to the buyer

Note : you should call the Product Inventory Management API to retrieve the structure of the existing product

{
    "description": "ProductOrder Modif speedcos from API - ABA",
    "productOrderSpecification": "speedCosModification",
    "externalIdentifier": [
        {
            "id": "MYCOMPANY_ORDER_ID",
            "externalIdentifierType": "customerIdentifier",
            "owner": "MYCOMPANY"
        }
    ],
    "productOrderItem": [
        {
            "id": "2c9280828682d8590186c084c83501cf",
            "quantity": 1,
            "action": "noChange",
            "product": {
                "id": "2c9280828682d8590186c084c83501cf",
                "productOffering": {
                    "id": "GOC40140084001"
                },
                "relatedParty": [
                    {
                        "id": "1563c17f-3c37-4c31-9642-xxx",
                        "role": "operatorInterlocutor",
                        "@baseType": "RelatedParty",
                        "@referredType": "Individual"
                    }
                ],
                "agreement": [
                    {
                        "id": "TESTFTTHAcess1"
                    }
                ]
            },
            "productOrderItemRelationship": [
                {
                    "id": "2c9280828682d8590186c084c7ac01ca",
                    "relationshipType": "bundles"
                }
            ]
        },
        {
            "id": "2c9280828682d8590186c084c7ac01ca",
            "quantity": 1,
            "action": "noChange",
            "product": {
                "id": "2c9280828682d8590186c084c7ac01ca",
                "productOffering": {
                    "id": "OC40140084001"
                }
            },
            "productOrderItemRelationship": [
                {
                    "id": "2c9280828682d8590186c084c41d01c1",
                    "relationshipType": "bundles"
                }
            ]
        },
        {
            "id": "2c9280828682d8590186c084c41d01c1",
            "quantity": 1,
            "action": "noChange",
            "product": {
                "id": "2c9280828682d8590186c084c41d01c1",
                "productOffering": {
                    "id": "GO40140084001"
                }
            },
            "productOrderItemRelationship": [
                {
                    "id": "2c9280828682d8590186c084c1a101bb",
                    "relationshipType": "bundles"
                }
            ]
        },
        {
            "id": "2c9280828682d8590186c084c1a101bb",
            "quantity": 1,
            "action": "modify",
            "product": {
                "id": "2c9280828682d8590186c084c1a101bb",
                "productCharacteristic": [
                    {
                        "id": "FONC40140084004",
                        "name": "Débit d'accès Montant/Descendant",
                        "value": {
                            "id": "VF0000440140084004",
                            "name": "800M/1000M"
                        },
                        "valueType": "object"
                    }
                ],
                "productOffering": {
                    "id": "O40140084001"
                }
            }
        }
    ],
    "relatedParty": [
        {
            "id": "8f4ac814-5072-4519-9e8c-xxx",
            "role": "buyer",
            "@referredType": "organization"
        }
    ]
}

7. I want to add an optional product on an active access

To add an optional product, like a GTR, to an active access, a dedicated modification productOrder must be sent.

Don't forget to use an access_token with owf:united-way:product-order:v1:write scope.

POST /productorder
Content-Type: application/json

This modification productOrder must include :

  • characteristic : "productOrderSpecification" set to gtrModification
  • section : "externalIdentifier" relative to your company order
  • section : "productOrderItem" of contract-level with action set to noChange
  • section : "productOrderItem" of play-level with action set to noChange
  • section : "productOrderItem" of set-level with action set to noChange
  • section : "productOrderItem" relative to the new product
    • characteristic action set to add
    • the productCharacteristic description
    • the productOffering
  • section "relatedParty" relative to the buyer

Note : you should call the Product Inventory Management API to retrieve the structure of the existing product

{
    "description": "ProductOrder ajout GTR from API - ABA",
    "productOrderSpecification": "gtrModification",
    "externalIdentifier": [
        {
          "id": "MYCOMPANY_ORDER_ID",
          "externalIdentifierType": "customerIdentifier",
          "owner": "MYCOMPANY"
        }
    ],
    "productOrderItem": [
        {
            "id": "2c9280828682d8590186c0bf9b3f0231",
            "quantity": 1,
            "action": "noChange",
            "product": {
                "id": "2c9280828682d8590186c0bf9b3f0231",
                "productOffering": {
                    "id": "GOC40140084001"
                },
                "relatedParty": [
                    {
                        "id": "1563c17f-3c37-4c31-9642-7b6f2533f969",
                        "role": "operatorInterlocutor",
                        "@baseType": "RelatedParty",
                        "@referredType": "Individual"
                    }
                ],
                "agreement": [
                    {
                        "id": "TESTFTTHAcess1"
                    }
                ]
            },
            "productOrderItemRelationship": [
                {
                    "id": "2c9280828682d8590186c0bf9aa9022c",
                    "relationshipType": "bundles"
                }
            ]
        },
        {
            "id": "2c9280828682d8590186c0bf9aa9022c",
            "quantity": 1,
            "action": "noChange",
            "product": {
                "id": "2c9280828682d8590186c0bf9aa9022c",
                "productOffering": {
                    "id": "OC40140084001"
                }
            },
            "productOrderItemRelationship": [
                {
                    "id": "2c9280828682d8590186c0bf98100224",
                    "relationshipType": "bundles"
                }
            ]
        },
        {
            "id": "2c9280828682d8590186c0bf98100224",
            "quantity": 1,
            "action": "noChange",
            "product": {
                "id": "2c9280828682d8590186c0bf98100224",
                "productOffering": {
                    "id": "GO40140084001"
                }
            },
            "productOrderItemRelationship": [
                {
                    "id": "GTR",
                    "relationshipType": "bundles"
                }
            ]
        },
        {
            "id": "GTR",
            "quantity": 1,
            "action": "add",
            "product": {
                "isBundle": false,
                "productCharacteristic": [
                    {
                        "id": "FONC40140084009",
                        "name": "Type de GTR",
                        "value": {
                            "id": "VF0000240140084009",
                            "name": "10 heures HO (heures ouvrables)"
                        },
                        "valueType": "object"
                    }
                ],
                "productOffering": {
                    "id": "O40140084002"
                }
            }
        }
    ],
    "relatedParty": [
        {
            "id": "8f4ac814-5072-4519-9e8c-xxx",
            "role": "buyer",
            "@referredType": "organization"
        }
    ]
}

8. I want to terminate an optional product on an active access

To terminate an optional product, like a GTR, on an active access, a dedicated modification productOrder must be sent.

Don't forget to use an access_token with owf:united-way:product-order:v1:write scope.

POST /productorder
Content-Type: application/json

This modification productOrder must include :

  • characteristic : "productOrderSpecification" set to gtrModification
  • section : "externalIdentifier" relative to your company order
  • section : "productOrderItem" of contract-level with action set to noChange
  • section : "productOrderItem" of play-level with action set to noChange
  • section : "productOrderItem" of set-level with action set to noChange
  • section : "productOrderItem" relative to the product to be terminated
    • characteristic action set to delete
    • the product.id to be deleted
  • section "relatedParty" relative to the buyer

Note : you should call the Product Inventory Management API to retrieve the structure of the existing product

{
  "description": "ProductOrder suppression GTR from API -ABA",
  "productOrderSpecification": "gtrModification",
  "externalIdentifier": [
    {
      "id": "MYCOMPANY_ORDER_ID",
      "externalIdentifierType": "customerIdentifier",
      "owner": "MYCOMPANY"
    }
  ],
  "productOrderItem": [
    {
      "id": "2c9280828682d8590186c09e1ff401f1",
      "quantity": 1,
      "action": "noChange",
      "product": {
        "id": "2c9280828682d8590186c09e1ff401f1",
        "productOffering": {
          "id": "GOC40140084001"
        },
        "relatedParty": [
          {
            "id": "1563c17f-3c37-4c31-9642-xxx",
            "role": "operatorInterlocutor",
            "@baseType": "RelatedParty",
            "@referredType": "Individual"
          }
        ],
        "agreement": [
          {
            "id": "TESTFTTHAcess1"
          }
        ]
      },
      "productOrderItemRelationship": [
        {
          "id": "2c9280828682d8590186c09e1f4401ec",
          "relationshipType": "bundles"
        }
      ]
    },
    {
      "id": "2c9280828682d8590186c09e1f4401ec",
      "quantity": 1,
      "action": "noChange",
      "product": {
        "id": "2c9280828682d8590186c09e1f4401ec",
        "productOffering": {
          "id": "OC40140084001"
        }
      },
      "productOrderItemRelationship": [
        {
          "id": "2c9280828682d8590186c09e1be201e3",
          "relationshipType": "bundles"
        }
      ]
    },
    {
      "id": "2c9280828682d8590186c09e1be201e3",
      "quantity": 1,
      "action": "noChange",
      "product": {
        "id": "2c9280828682d8590186c09e1be201e3",
        "productOffering": {
          "id": "GO40140084001"
        }
      },
      "productOrderItemRelationship": [
        {
          "id": "2c9280828682d8590186c09e184301df",
          "relationshipType": "bundles"
        }
      ]
    },
    {
      "id": "2c9280828682d8590186c09e184301df",
      "quantity": 1,
      "action": "delete",
      "product": {
        "id": "2c9280828682d8590186c09e184301df",
        "productOffering": {
          "id": "O40140084002"
        }
      }
    }
  ],
  "relatedParty": [
    {
      "id": "8f4ac814-5072-4519-9e8c-xxx",
      "role": "buyer",
      "@referredType": "organization"
    }
  ]
}