Appearance
Customize pricing
Use price:resolve to transform already loaded pricing. The callback receives base values, the current resolved price, product context, and customer-facing labels.
Apply a synchronous price table
Load remote pricing before registering the hook, or maintain it in a plugin-owned cache. Price resolution itself must return synchronously.
ts
import { PLUGIN_API_VERSION, definePlugin } from '@iconfigurators/plugin-sdk'
type Options = {
prices: Record<string, number>
}
export default definePlugin<Options>({
id: 'customer.pricing',
version: '1.0.0',
apiVersion: PLUGIN_API_VERSION,
setup(api, options) {
const prices = new Map(Object.entries(options?.prices ?? {}))
api.hooks.filter('price:resolve', (pricing) => {
const partNumber = pricing.spec?.partNumber
if (partNumber == null) return pricing
const customerPrice = prices.get(String(partNumber))
if (!Number.isFinite(customerPrice)) return pricing
return {
...pricing,
price: customerPrice,
compareAtPrice: pricing.price,
labels: {
...pricing.labels,
current: 'Your price',
original: 'Regular price',
},
}
})
},
})Refresh after cached data changes
If plugin-owned pricing changes after setup, update the cache and request a new pricing pass:
ts
function updatePrice(partNumber: string, price: number) {
prices.set(partNumber, price)
api.commands.refreshPricing()
}Do not start a network request inside price:resolve. Until the required data is available, return the received value unchanged.
Preserve public context
Return a new pricing record and retain fields such as source, productType, wheel, spec, vehicle, and base. Change only the resolved price, comparison price, or labels needed by the integration.