Product guide
Guide to creating and updating Products
Product Guide
This guide provides a foundation on how to work with the products API. To get a foundation for how products are structured and their different features the product structure user guide is a good place to start.
Product type and object structure
The product type defines how many charge plans and charges a product can have. Every product must contain at least one charge plan, and every charge plan must contain at least one charge.
There are four product types:
Simple – One charge plan with one charge.
MultipleCharges – One charge plan with multiple charges.
MultipleChargePlans – Multiple charge plans, each with one charge.
Full – Multiple charge plans with multiple charges.
Example: Simple product response
"product": {
"productNumber": "P-000001",
"chargePlans": [
{
"chargePlanNumber": "CP-000001",
"charges": [
{
"chargeNumber": "C-000001",
"priceDetails": [...]
}
]
}
]
}
Example: Full Product Response
"product": {
"productNumber": "P-000001",
"chargePlans": [
{
"chargePlanNumber": "CP-000001",
"charges": [
{
"chargeNumber": "C-000001",
"priceDetails": [...]
},
{
"chargeNumber": "C-000002",
"priceDetails": [...]
}
]
},
{
"chargePlanNumber": "CP-000002",
"charges": [
{
"chargeNumber": "C-000003",
"priceDetails": [...]
},
{
"chargeNumber": "C-000004",
"priceDetails": [...]
},
{
"chargeNumber": "C-000005",
"priceDetails": [...]
}
]
},
]
}
Charge Plans
A charge plan is primarily a container for charges. While it contains only general fields, it plays an important role by linking order products (products on an order) to their originating product and charges.
Charges
Charges are the most important part of the product and hold the most important information, which makes them more complex with a number of important fields. The fields on the charge object can be separated into different categories.
“General fields”, “charge configuration fields”, and “financial fields”
In the following JSON example, the fields are sorted by each category.
Charges
Charges are the core element of a product. They contain the most critical information and are therefore more complex, with fields that can be organized into three categories:
General fields
Charge configuration fields
Financial properties
Example: Charge Object
{
//"General fields"
"name": "string",
"customFields": {
"customFieldKey": "string"
},
"externalCRMId": "string",
"externalERPId": "string",
//charge configuration fields
"chargeType": "Recurring",
"model": "Quantity",
"unit": "units",
"pricePeriod": "Monthly,
"defaultQuantity": 0,
"usageRating": "Sum",
"measurementsRule": 0,
"PriceDetails": [
{
"tier": 0,
"currency": "EUR",
"price": 10,
"customFields": {},
"description": "string",
"isInfinite": false,
"priceBase": "Flat",
"toQuantity": 0
}
],
//Financial properties
"billingPeriod": "Monthly",
"periodAlignment": "None",
"billingDay": "None",
"billingTiming" "InAdvance"
"specificBillingDay": 0,
"taxIncluded": false,
"revenueRecognition": "Recognized monthly over time",
"taxTemplate": "Sweden standard",
"deferredRevenueAccount": "2970",
"recognizedRevenueAccount": "3000"
}
General fields
General identifiers for a charge and other detail fields. Read more about custom fields and external ids in the developer resources section
Charge configuration fields
These fields define the type and pricing model of a charge and the charge type determines which pricing models are valid. The relevance of the other fields are dictated by the Type and model combination. The matrices below show the relationship between the fields and the type and model a charge has.
chargeType
One-off
Usage
Measured
Recurring
model
Flat
Quantity
Volume
Tiered
Quantity
Volume
Tiered
Rated
Quantity
Volume
Tiered
Flat
Quantity
Volume
Tiered
PriceDetails
x
x
x
x
x
x
x
x
x
x
x
x
x
x
unit
x
x
x
x
x
x
x
x
x
x
x
x
x
defaultQuantity
x
x
x
x
x
x
pricePeriod
x
x
x
x
x
x
x
x
x
x
x
usageRating
x
x
x
measurementRules
x
x
x
Most values can be set even if they have no relevance for the type and model and will be ignored when the charge is used. If a value is required or invalid in a specific use case, this will be stated in the documentation or throw a validation error on the request.
Financial fields
These fields are connected to how the charge will be billed on an order and act as default values for the order product charge (the charge of an order) when it’s created.
Default charge values
Default values for charges can be set in the Younium UI under: Settings > Products > Product settings
.
If a field is not included or set to
null
in the request, it will fall back to the defined default (if available).Some fields (e.g.,
revenueRecognition
,taxTemplate
,deferredRevenueAccount
,recognizedRevenueAccount
) may remain null if no default exists.
In certain cases, this behavior is preferred, as these values can instead be set when a Subscription or Sales order is created.
Price details
Every charge (except rated usage charges) requires at least one price detail. Price details define the pricing rules and depend on the charge’s pricing model.
Key rules:
The tier index starts at 0 and increments by 1.
Each
toQuantity
must be greater than the previous tier’stoQuantity
.The last tier may omit
toQuantity
ifisInfinite = true
.If no currency is set, the legal entity’s base currency is applied.
For flat or quantity models, there is only one price detail per currency (tier = 0).
For volume or tiered models, multiple tiers per
currency
are supported.
Product category
The product category helps organize products (e.g., for reporting). Categories are defined under:
Settings > Products > Product categories
.
Creating a product
The POST /products
endpoint is used for creating products.
Example request for a simple subscription of a monthly recurring flat fee:
{
"name": "SaaS",
"productType": "Simple",
"category": "Core service",
"isFrameworkProduct": false,
"chargePlans": [
{
"name": "SaaS charge plan",
"charges": [
{
"name": "SaaS monthly fee",
"model": "Flat",
"chargeType": "Recurring",
"pricePeriod": "Monthly",
"billingDay": "FromOrder",
"specificBillingDay": 0,
"billingPeriod": "Annual",
"periodAlignment": "AlignToOrder",
"billingTiming": "InAdvance",
"taxTemplate": "Sweden Standard",
"taxIncluded": false,
"deferredRevenueAccount": "24xx",
"recognizedRevenueAccount": "30xx",
"customFields": {
"customChargeField": "string"
},
"priceDetails": [
{
"currency": "SEK",
"price": 1099.00
},
{
"currency": "EUR",
"price": 99.00
},
{
"currency": "DKK",
"price": 749.00
},
{
"currency": "USD",
"price": 99.00
},
{
"currency": "NOK",
"price": 1099.00
}
]
}
]
}
],
"customFields": {
"customProductField": "string"
}
}
Remarks about the request:
Note that the
tier
doesn’t have to be set on theprice details
in this case as there can be only one per currency. Tier will get the value 0 as default.
Creating a full product example
Say we are offering a SaaS in which there are 3 plans: starter, professional. In each plan, there is a recurring base fee for 99, 400 and including 5, 15, and 30 seats, respectively, and above those included seats, there’s a volume-based discounted price tier.
For example, for the starter plan
6-20
30 per seat
21-∞
20 per seat
{
"name": "SaaS",
"productType": "Full",
"category": "Core service",
"isFrameworkProduct": false,
"chargePlans": [
{
"name": "Starter",
"charges": [
{
"name": "Starter base fee",
"model": "Flat",
"chargeType": "Recurring",
"priceDetails": [
{
"currency": "EUR",
"price": 99
},
{
"currency": "USD",
"price": 99
}
]
},
{
"name": "Starter seats fee",
"model": "Tiered",
"chargeType": "Recurring",
"defaultQuantity": 5,
"unit": {
"key": "unit",
"value": "seats"
},
"priceDetails": [
{
"tier": 0,
"currency": "EUR",
"toQuantity": 5,
"priceBase": "perUnit",
"price": 0
},
{
"tier": 1,
"currency": "EUR",
"toQuantity": 20,
"priceBase": "perUnit",
"price": 30
},
{
"tier": 2,
"currency": "EUR",
"isInfinite": true,
"priceBase": "perUnit",
"price": 20
},
{
"tier": 0,
"currency": "USD",
"toQuantity": 5,
"priceBase": "perUnit",
"price": 0
},
{
"tier": 1,
"currency": "USD",
"toQuantity": 20,
"priceBase": "perUnit",
"price": 30
},
{
"tier": 2,
"currency": "USD",
"isInfinite": true,
"priceBase": "perUnit",
"price": 20
}
]
}
]
},
{
"name": "Professional",
"charges": [
{
"name": "Professional base fee",
"model": "Flat",
"chargeType": "Recurring",
"priceDetails": [
{
"currency": "EUR",
"price": 400
},
{
"currency": "USD",
"price": 400
}
]
},
{
"name": "Professional seats fee",
"model": "Tiered",
"chargeType": "Recurring",
"defaultQuantity": 15,
"unit": {
"key": "unit",
"value": "seats"
},
"priceDetails": [
{
"tier": 0,
"currency": "EUR",
"toQuantity": 5,
"priceBase": "perUnit",
"price": 0
},
{
"tier": 1,
"currency": "EUR",
"toQuantity": 20,
"priceBase": "perUnit",
"price": 30
},
{
"tier": 2,
"currency": "EUR",
"isInfinite": true,
"priceBase": "perUnit",
"price": 20
},
{
"tier": 0,
"currency": "USD",
"toQuantity": 5,
"priceBase": "perUnit",
"price": 0
},
{
"tier": 1,
"currency": "USD",
"toQuantity": 20,
"priceBase": "perUnit",
"price": 30
},
{
"tier": 2,
"currency": "USD",
"isInfinite": true,
"priceBase": "perUnit",
"price": 20
}
]
}
]
}
]
}
Patching a product
The PATCH /products/{id}
endpoint updates existing products and can add, modify, or remove charge plans, charges, and price details.
Operation Field
Entities can include an operation
field with values:
Create – Ignores lookup key; all child entities inherit
Create
.Remove – Requires lookup key; child entities inherit
Remove
.Change (default) – Requires lookup key; affects only that entity.
Price details do not use lookup keys. They are identified by the combination of tier
and currencyCode
.
Rules and Limitations
Removing entities may fail if they are already used in a subscription or sales order.
Changing product type may require explicit removal of charges/charge plans.
Changing the model may automatically alter or remove price details.
New entities receive default values unless otherwise specified.
Framework products currently support patching only at the product level (not charges or charge plans).
⚠️ Caution: Updates are irreversible. Deleted entities cannot be recovered.
Patching a full product endpoint
Taking the above example request of creating a full product and updating it with:
Adding an enterprise charge plan
Removing the middle tiers on the Starter tiered charge.
Updating the price on the flat recurring fee on the Professional charge plan
{
"name": "SaaS-updated",
"chargePlans": [
{
"chargePLan": "CP-000001",
"name": "Starter-updated",
"charges": [
{
"charge": "C-000002",
"defaultQuantity": 10,
"priceDetails": [
{
"tier": 0,
"currency": "EUR",
"toQuantity": 10,
"price": 5
},
{
"operation": "Remove",
"tier": 1,
"currency": "EUR"
},
{
"tier": 0,
"currency": "USD",
"toQuantity": 10,
"price": 5
},
{
"operation": "Remove",
"tier": 1,
"currency": "USD"
}
]
}
]
},
{
"chargePLan": "CP-000001",
"name": "Professional-updated",
"charges": [
{
"charge": "C-000003",
"priceDetails": [
{
"tier": 0,
"currency": "EUR",
"price": 500
},
{
"tier": 0,
"currency": "USD",
"price": 500
}
]
},
{
"charge": "C-000004",
"priceDetails": [
{
"tier": 1,
"currency": "EUR",
"price": 35
},
{
"tier": 2,
"currency": "EUR",
"price": 25
},
{
"tier": 1,
"currency": "USD",
"price": 35
},
{
"tier": 2,
"currency": "USD",
"price": 25
}
]
}
]
},
{
"operation": "create",
"name": "Enterprise",
"charges": [
{
"name": "Enterprise base fee",
"model": "Flat",
"chargeType": "Recurring",
"priceDetails": [
{
"currency": "EUR",
"price": 1000
},
{
"currency": "USD",
"price": 1000
}
]
},
{
"name": "Enterprise pcs fee",
"model": "Tiered",
"chargeType": "Recurring",
"defaultQuantity": 30,
"unit": {
"key": "name",
"value": "pcs"
},
"priceDetails": [
{
"tier": 0,
"currency": "EUR",
"toQuantity": 5,
"priceBase": "perUnit",
"price": 0
},
{
"tier": 1,
"currency": "EUR",
"toQuantity": 20,
"priceBase": "perUnit",
"price": 30
},
{
"tier": 2,
"currency": "EUR",
"isInfinite": true,
"priceBase": "perUnit",
"price": 20
},
{
"tier": 0,
"currency": "USD",
"toQuantity": 5,
"priceBase": "perUnit",
"price": 0
},
{
"tier": 1,
"currency": "USD",
"toQuantity": 20,
"priceBase": "perUnit",
"price": 30
},
{
"tier": 2,
"currency": "USD",
"isInfinite": true,
"priceBase": "perUnit",
"price": 20
}
]
}
]
}
]
}
Deleting a product
Products or their child entities can be deleted using the relevant API endpoints.
Entities in use on an order cannot be deleted.
Price details should be removed by updating the charge via
PATCH
.
Last updated
Was this helpful?