Pricing Engine Overview & Pricing Models
How tier, volume, and block pricing is calculated in Good Sign, including discounts, pricing breakdowns, and repricing behavior.
1. Purpose of this guide
This guide explains how pricing is calculated in Good Sign when using tier‑based, volume‑based, and block‑based pricing models, and how discounts and repricing behave after the enhancements introduced in Release 2026_2.
The guide focuses on pricing behavior and outcomes, not technical implementation details.
This guide covers
- How prices are calculated and combined
- How tiers, steps, discounts, and repricing behave
This guide does not cover
- How to create pricing rows in the UI
- API or database implementation details
- User rights or automation scheduling
2. Supported pricing models
2.1. Unit pricing
Unit pricing calculates the total price by multiplying the quantity by a fixed unit price. Quantity can be an integer count of items (e.g., 100 software licenses) or a decimal amount/measurement (e.g. 37.5 hours).
Typical use cases:
- Work invoicing
- Simple recurring fees
- One‑time fees
2.2. Tier pricing
Tier pricing splits the total amount into predefined tiers and prices each tier separately.
Characteristics:
- Each tier has its own unit price
- Different portions of the amount may be priced at different rates
- Total price is the sum of all priced tiers
Typical use cases:
- Usage‑based overage pricing
- Graduated SaaS pricing
- Consumption models where marginal price decreases or increases with volume
2.3. Volume pricing
Volume pricing selects a single price step based on the total amount and applies that unit price to the entire amount.
Characteristics:
- Only one pricing step is selected
- The selected unit price is applied to the full amount
- Step boundaries determine which price applies
Typical use cases:
- Subscription tiers
- Contract pricing based on total customer size or volume
- Simplified enterprise pricing levels
2.4. Block pricing
Block pricing charges a fixed total price for a defined amount range.
Characteristics:
- One pricing step is selected based on amount
- The step price is charged as‑is (not multiplied by amount)
- Amount is still recorded for reporting and unit‑price calculation
Typical use cases:
- Bundles
- Flat‑rate service packages
- Included‑usage blocks
2.5. Visual comparison table (Unit vs Tier vs Volume vs Block)
|
Model |
How price is selected |
Typical outcome |
|
Unit |
Quantity × unit price |
Linear pricing |
|
Tier |
Quantity split across steps |
Blended unit price |
|
Volume |
One step applies to all |
Step‑based unit price |
|
Block |
One step gives total |
Fixed total per range |
3. Configuring pricing steps (min / max)
Tier, volume, and block pricing all use pricing steps defined as an ordered “staircase” of amount ranges. Each step is configured using min (step start) and max (step end).

Figure 1: Pricing Step Staircase (Min / Max Ranges)
3.1. Make the staircase continuous (no gaps, no overlaps)
- The previous step’s max must equal the next step’s min.
- This works the same way for decimal amounts (e.g., 37.5 hours), not just whole numbers.
If there are gaps in the staircase, part of the amount may not match any step, which can lead to unexpected results. In tier pricing, gaps can cause pricing to stop early, meaning lower steps below the gap may not be priced at all. This behavior does not affect volume or block pricing in the same way, because those models only select the single matching step for the full amount.
⚠️ Important
In tier pricing, gaps in the staircase can cause pricing to stop early. Any amount below the gap may not be priced at all.
Always verify that tier steps form a continuous chain from the lowest minimum to the highest maximum.
3.2. Boundary rule (lower step wins)
Step boundaries are included. This means an amount exactly on the boundary (e.g., 100) can match more than one step. In that case, the engine applies a deterministic tie-breaker: the lower step wins (e.g., 100 is priced using the 0–100 step, not the 100–200 step).
An amount of 0 belongs to the lowest step.
3.3. Example staircase (with unit prices)
Boundaries are defined the same way for tier, volume, and block pricing. The unit prices below illustrate a typical pattern where the price per unit decreases in higher steps.

Figure 2: Example Pricing Staircase with Decreasing Unit Prices
Open-ended last step: If max is empty, the step is open-ended and applies up to the maximum value supported by the amount data type.
Note: In tier pricing, unit prices are applied per step (each portion of the amount uses that step’s unit price). In volume pricing, one step is selected and its unit price applies to the full amount. In block pricing, the selected step defines a fixed total price for the range, so “unit price” is shown here only to illustrate how step selection works.
Concrete example (tier pricing): Assume the staircase above and an amount of 260.5. The amount is split across steps and each part is priced using that step’s unit price:
- Step 1 (0–100): 100.0 × 3.00 = 300.00
- Step 2 (100–200): 100.0 × 2.00 = 200.00
- Step 3 (200+): 60.5 × 1.50 = 90.75
Total = 300.00 + 200.00 + 90.75 = 590.75
This example also shows that the staircase works naturally with decimals (the last step quantity is 60.5).
4. Discounts and pricing order
The pricing engine applies discounts in a defined order to ensure predictable and transparent results.
4.1. Supported discount types
- Step‑specific discounts
- Applied to individual tier, volume, or block steps
- Applied per selected step. Tier: potentially multiple steps; volume/block: only the one selected step.
- Defined as multipliers (e.g. 0.90 = 10% discount)
- Can also represent price increases (e.g. 1.10)
- Whole‑ticket discounts
- Applied once to the total price after step calculations
- Defined as multipliers
- Used for campaign discounts, customer agreements, or contract‑level incentives
- Charge discounts
- Monetary discounts (absolute amount)
- Percentage discounts
- Applied after all pricing and multiplier discounts
4.2. Discount application order
The pricing engine applies discounts in the following order:
- Step‑specific discounts (if applicable)
- Whole‑ticket discounts
- Charge object monetary discounts
- Charge object percentage discounts
This order is fixed and ensures consistent results across invoicing, reporting, and repricing.
4.3. Pricing ID (ticket vs. breakdown)
This behavior explains why the pricing ID shown on the ticket may not match every pricing row shown in the breakdown.
Each ticket has a pricing ID that identifies the main pricing rule considered “selected” for that ticket. In addition, the internal pricing breakdown (used in creating reports and invoices) contains multiple lines, and each line can reference its own pricing ID to show which step price or discount produced that specific line.
What the ticket-level pricing ID means
- If no whole-ticket discount is applied, the ticket-level pricing ID refers to the base step pricing rule used for the ticket.
- For tier, volume, and block models, this base rule corresponds to the highest matching step for the ticket’s amount (i.e., the largest step whose min/max range matches the amount). In tier pricing, this is true even though the breakdown may include multiple step lines.
- If a whole-ticket discount is applied, the ticket-level pricing ID refers to the whole-ticket discount rule (not the base step rule).
What pricing IDs in the breakdown mean
- Step pricing lines reference the pricing ID of the step rule that produced that line.
- If step-specific discounts are used, the breakdown can include lines that reference both the step’s base price rule and the step-specific discount rule.
- Charge object discounts may appear as separate breakdown adjustments.
5. Unit price calculation
For tier, volume, and block pricing:
- The effective unit price is calculated as
final total price ÷ amount - This reflects what the customer actually pays per unit
- All discounts (step-specific, whole-ticket, and charge object discounts) are included in the calculation
This ensures that unit prices remain meaningful even when pricing is not purely unit‑based (especially in block pricing, where the total is not multiplied by the amount).
Example: Using the previous tier pricing example steps. We have tier pricing and we are using all three defined tiers for this product. Unit price is then calculated from final total price divided by amount. This can differ from the unit price stored in the selected pricing step (highest matching), because the effective unit price reflects the blended outcome across all tier steps (and possible discounts).

Figure 3: Effective Unit Price Calculation
Figure 4: Pricing Breakdown by Tier Step
Internal breakdown, where each tier step and their respective pricing IDs and unit prices can be seen.

Figure 5: Pricing Breakdown with Pricing IDs
6. Repricing behavior
6.1. What is repricing?
Repricing recalculates pricing for a ticket after pricing configurations change.
Examples:
- Tier limits or prices are updated
- Discounts are changed
- Pricing inheritance changes through the organization structure
6.2. What happens during repricing?
When repricing is run:
- The ticket price is recalculated using current pricing rules
- Pricing breakdown rows are regenerated
- Discount logic is re‑applied in the correct order
- Unit price is updated based on the new total
Repricing updates both the ticket header values (total price, selected pricing ID, unit price) and completely rebuilds the breakdown lines to match the current configuration.
The ticket’s pricing ID may change (for example, if a whole-ticket discount is now applicable, the selected pricing ID becomes the discount rule rather than the base step rule).
Example: Continuing the previous tier example, we now change the third tier price from 1.5 to 0.5. This triggers repricing, which regenerates the ticket and breakdown rows.
Figure 6: New Pricing Rows
Figure 7: New Charge Ticket Row

Figure 8: New Pricing Breakdown
6.3. Invoicing considerations
Normal invoicing restrictions apply.
If the ticket has already been invoiced, repricing is blocked or limited so that invoiced prices are not changed.