Price injections
Overview
Price injections let your backend override the prices Centra's pricing engine would normally apply — on individual cart lines or on the current shipping method. Centra still owns the catalog, tax logic, and voucher handling; you are only replacing the monetary value for selected units.
Common use cases:
- CO₂ fees — add a line item priced dynamically based on the cart's weight or carbon footprint
- Donations — add a "donate X% to charity" line at a calculated amount
- Made-to-measure / custom pricing — price calculated by an external configurator
- Customer-segment pricing — apply loyalty or B2B pricing computed in your own system
Prerequisites
Enable the feature
Price injections must be enabled in the Storefront API plugin by Centra staff before they can be used. The priceInjections permission controls access; without it, calls to the price injection mutations return a permission error regardless of the operating mode.
Operating mode: SHARED_SECRET
All price injection mutations require the SHARED_SECRET operating mode. This means:
- The mutation must be called from your backend, never from client-side code running in the browser.
- The shared secret must be sent in every request that includes a price injection.
Under no circumstances may the injected price be set based on unvalidated end-user input. Do not build a reverse proxy that forwards user-supplied values directly into these mutations. If you need to accept a price from a user, validate and authorise it in your own system first, then inject it server-side.
The product must exist in Centra
Line price injections override the price of an existing product variant — they do not create free-text or ad-hoc lines. The item passed to addItem, or the line targeted by setLinePrice, must correspond to a real product variant configured in Centra. This requirement ensures that Centra can apply the correct tax rules, product attributes, and reporting for every line.
For use cases like CO₂ fees or donations, set up a dedicated product variant in Centra (e.g. a "CO₂ fee" or "Donation" product), then add it to the cart with the dynamically calculated price injected at the time of the call.
How to inject custom prices on cart lines
How it works
All line-price mutations accept a CustomPriceInput that carries the overriding price and a required comment for traceability. Centra still owns catalog, voucher, and tax handling — you are only replacing the monetary value for the selected units.
input CustomPriceInput {
unitPrice: PriceInput! # The overriding unit price
originalPrice: PriceInput # Optional: override the "pricelist" original price
quantity: Int! # How many units this price covers
comment: String! # Required — explain why the price was injected
}
input PriceInput {
price: Float!
currencyCode: String! # Must match the session currency
}
unitPrice — the price per unit that Centra will use instead of its catalog price. Must not exceed the pricelist's original price for the variant. If it does, a userError is returned.
originalPrice — optionally override the "was" price shown to the buyer. If omitted, Centra uses the pricelist original price. Use this when you want to control whether the line is rendered as a discount (red price) or a straight price.
quantity — the number of units the custom price covers. If the line holds more units than this, the remaining units are priced by Centra's standard logic (see line splitting under Step 2 below).
comment — a free-text string recorded for traceability. Required. Describe the source of the price — for example "CO2 fee calculated by emissions-api v2" or "Loyalty tier price from CRM".
Step 1. Inject a price when adding an item
Pass customPrice directly on addItem:
mutation AddItemWithCustomPrice {
addItem(
item: "123-456"
quantity: 2
customPrice: {
unitPrice: { price: 299.00, currencyCode: "SEK" }
quantity: 2
comment: "Made-to-measure price from configurator"
}
) {
line {
id
unitPrice { value }
}
userErrors { message }
}
}
If customPrice.quantity equals the requested quantity, the entire line is priced at the injected value. If it is less, the line is split on creation: the first segment uses the injected price, the remainder uses catalog pricing.
Two addItem calls for the same variant with identical custom prices are merged into a single line. Two calls with different custom prices produce two separate lines.
Mutation: addItem
Step 2. Apply or update a custom price on an existing line
Use setLinePrice to inject (or re-inject) a price on a line that is already in the selection:
mutation SetLinePrice {
setLinePrice(
lineId: "abc123"
customPrice: {
unitPrice: { price: 149.00, currencyCode: "SEK" }
quantity: 1
comment: "Segment-A promotional price"
}
) {
selection { ... }
userErrors { message }
}
}
Line splitting
If the line currently holds more units than customPrice.quantity, the line is split:
| Result | Price | Qty |
|---|---|---|
| New line | Injected price | customPrice.quantity |
| Original line (remainder) | Previous price | remaining units |
If customPrice.quantity is greater than or equal to the line quantity, the entire line is updated in place.
Mutation: setLinePrice
Step 3. Clear a custom price
To restore a line to Centra's catalog price:
mutation ClearCustomPrice {
clearCustomPrice(lineId: "abc123") {
selection { ... }
userErrors { message }
}
}
Mutation: clearCustomPrice
Step 4. Re-inject after market or pricelist resets
Custom line prices are tied to the market and pricelist active when they were set. If the buyer's market or pricelist changes (e.g. they switch country and land on a different pricelist), Centra resets all injected line prices back to catalog values — and a CustomLinePriceChange user warning is returned on the next mutation for each affected line.
# Example: country changed — CustomLinePriceChange appears in userWarnings
mutation ChangeCountry {
setCountryState(country: "US") {
selection { ... }
userWarnings {
... on CustomLinePriceChange {
message
lineId
}
}
}
}
Use the lineId field to identify which lines were reset. If the custom price should still apply under the new market/pricelist, call setLinePrice again for each affected line.
Behavior with vouchers and campaigns
- Vouchers can still be applied to lines that have a custom price.
- Campaigns do not affect custom-priced lines; Centra's campaign engine skips those units.
- Fixed-price campaigns are not compatible with price injection on the same line.
- Lowest price is not affected by price injections. The lowest-price field (used for EU price transparency regulations) reflects the pricelist price, not the injected price.
Tax calculation
Centra calculates VAT/sales tax on the injected price using the tax rate configured for the product. No special handling is needed — taxes are recalculated automatically on every save.