Customer-specific pricing: choose the source of truth before the cache

Define who owns a price and every dimension that changes it before adding caching or fallback behavior across Znode and an ERP.

Znode 10GuideAdvancedGCG engineering guide
In this guide
Authorized buying context Price authority Validated result Scoped cache Checkout validation
Cache a price only within the context and validity rules of its authoritative source.

The fast response with the wrong contract price

Two buyers request the same product. The first belongs to a service account with negotiated pricing; the second buys under a different agreement. A cache keyed only by SKU returns quickly for both. It has improved response time while violating the most important requirement of the pricing integration.

Before choosing a cache, identify the price authority. Does Znode own the account price list, does an ERP calculate the sell price, or does the commerce workflow combine several documented sources? A cache should preserve that decision. It must not become an accidental fourth pricing system with its own undocumented fallback rules.

Describe the complete pricing question

A price may depend on account, store, SKU, quantity, unit of measure, currency, effective date, contract, or delivery conditions. Not every implementation uses every dimension. Determine the actual dependencies from the source contract and commercial rules rather than copying a long generic key.

Resolve the account and store through trusted context. A browser-supplied account number cannot establish access to its prices. If a pricing request spans products or accounts, keep each result associated with the exact input that produced it. A response with a matching SKU but a different currency or account is not a valid cache candidate.

Build an unambiguous cache key

PriceCacheKey.cs length-prefixes every string dimension and serializes decimal quantity with invariant culture. The result distinguishes values even when their text contains a separator. It deliberately preserves case and identifier content; apply only the normalization rules established by your pricing contract.

Pass the authorized account and store together with SKU, unit, currency, contract revision, and policy revision. Add an effective-date bucket to the contract revision when pricing validity changes by date. Native Znode price-list associations remain configured through their supported administration or API paths; this helper owns only the key for an additional integration cache.

Pricing/PriceCacheKey.cs csharp

using System;
using System.Globalization;
using System.Linq;
using System.Text;
namespace Gcg.DeveloperExamples.Pricing
{
public static class PriceCacheKey
{
public static string Build(string policyRevision, string store, string account,
string sku, decimal quantity, string unit, string currency, string contract)
{
var fields = new[] { policyRevision, store, account, sku, unit, currency, contract };
if (fields.Any(string.IsNullOrWhiteSpace) || fields.Any(x => x.Length > 200))
throw new ArgumentException("Every pricing dimension must be present and bounded.");
if (quantity <= 0) throw new ArgumentOutOfRangeException(nameof(quantity));
// Length-prefix fields so separators inside an identifier cannot collide.
var key = new StringBuilder();
foreach (var field in fields)
key.Append(field.Length.ToString(CultureInfo.InvariantCulture))
.Append(':').Append(field);
var q = quantity.ToString("G29", CultureInfo.InvariantCulture);
key.Append(q.Length.ToString(CultureInfo.InvariantCulture)).Append(':').Append(q);
return key.ToString();
}
}
}
// Build from authorized context and the pricing contract's normalization rules.
// Use decimal amounts/quantities, not localized display text or floating-point totals.

Choose a failure policy explicitly

An expired entry is a business decision, not merely a cache miss. Decide whether a stale price may be displayed, whether it must be labeled provisional, and whether checkout requires revalidation. A browsing fallback can be acceptable while the same fallback at order acceptance would be incorrect.

Do not substitute a generic account when context is missing. Do not treat an unavailable provider as a zero price. Distinguish no applicable price, authorization failure, malformed response, and dependency failure. Batch requests where the verified API supports it, bound timeouts, and avoid launching an unbounded external call for every product tile.

Use distinctive prices to prove isolation

Create two fictional accounts with conspicuously different prices for the same SKU. Vary quantity, currency, and store where those dimensions apply. Request them in alternating order and concurrently, then switch accounts in the browser. This makes accidental reuse visible instead of hiding it behind nearly identical values.

Advance the effective date, expire an entry, change a contract revision, and simulate a provider outage. Verify the product page, cart, and final calculation independently. A correct cache lookup on a product listing does not establish the checkout price. Inspect persisted order values after a controlled test when the target environment permits it.

  • Check negative-result caching separately from successful prices.
  • Avoid logging complete account and product payloads.
  • Measure hit rate together with correctness and stale-result age.

Keep the cache subordinate

Document where cached values may be used and where fresh authority is required. Assign ownership for invalidation when account agreements change. Prefer a cache technology suited to the read and write frequency; a convenient custom metadata table is not automatically a suitable transactional price cache.

The best optimization retains an answer to a precise pricing question for a justified period. If the question, authority, or validity window is unclear, adding storage only makes the ambiguity last longer. Resolve those decisions first, then measure the resulting behavior under realistic catalog and account traffic.

References and further reading

Bring your next engineering question.

Discuss account pricing integration

Explore how GCG can help

Independent guidance from GCG. Znode is a trademark of its owner. Examples use fictional data and are not official platform documentation. Suggest a correction.