Acro Commerce

Integration architecture

Where should a B2B price be calculated: in the ERP, in the storefront, in middleware, or at request time?

In exactly one place, and for a distributor running Acumatica or Cin7 that place is normally the ERP, because the ERP holds the contract. The real choice is between pushing ERP-calculated prices into platform price lists on a schedule, which is what the native Acumatica connectors do, and asking the ERP at the moment the page renders, which buys correctness and spends page speed, cache complexity and a hard dependency on the ERP being awake.

What are the four places a B2B price can be calculated, and why can only one of them win?

There are four, and every pricing argument on an ERP-connected commerce project is really an argument about which one you have chosen, usually without saying so out loud. The ERP can calculate the price and keep it to itself until an order arrives. The ERP can calculate it in advance and something can copy the result into the storefront. The storefront can calculate it from its own rules. Or something can ask the ERP at the moment a buyer loads the page.

Only one can win, because each of the four holds a different set of inputs. Acumatica and Cin7 know the contract, the expiry date and the customer’s tier. Shopify B2B and BigCommerce know the cart, the quantity and the session. Middleware is a layer of software that sits between the ERP and the storefront, translating and enforcing rules that neither system holds on its own. It can be a hosted integration platform or a custom service. knows whatever you told it last. If two of them are allowed to produce a price, they will eventually produce two, and the customer will quote the one that suits them.

The thing that makes this harder than it sounds is that the number a buyer needs is not stored anywhere. A list price is a field. A price class rate is a field. The effective price for this customer, this item, this quantity, today is the output of a calculation that runs when someone asks for it. A connector that copies fields cannot copy a calculation, which is why Acumatica’s own community, answering a direct question about syncing the effective sales price to Shopify rather than the Default Price, replied "No. Only Default Price is supported."

The four places a B2B price can be calculated, and who each one suits
CriterionHow it worksWho it fitsWhat it breaks
1. In the ERP, at order entry onlyThe storefront shows list price, a price band or no price at all. Acumatica or Cin7 applies the real price when the order lands, and the buyer sees it on the confirmation.Quote-first sellers, and catalogues where the online range is deliberately sold at list while negotiated accounts stay on EDI or the phone.Self-service. Any number on the page is provisional and you have to say so in writing on the page, or you will spend the first year arguing about it.
2. In the ERP, pushed to the platform as price listsThis is the default path on Shopify B2B and BigCommerce, and for a large share of distributors it is genuinely the correct answer.The ERP calculates prices in advance and a connector or scheduled job writes them into Shopify catalogues or BigCommerce price lists. Acumatica’s BigCommerce path needs the Price List entity’s Prepare and Process run on a schedule, which most sites run overnight.Tier-driven pricing that changes a few times a year. This is what native connectors are built for and what every platform demo shows you.Freshness and effective dating. Prices are as current as the last run, and dated prices flattened into an undated list lose the mechanism that made last year’s price stop applying.
3. In the storefront, from its own rulesThe commerce platform holds the pricing logic: a percentage adjustment on a catalogue, a customer group rate, or a rules engine in an app.Discount structures that really are percentage off list, with no absolute negotiated prices and no expiry dates.Maintenance. Every new contract now has to be keyed in two systems, and the second one is the entry that gets skipped when the sales manager is busy.
4. At request time, against the ERPThe storefront asks, through middleware or a custom service, what this customer pays for this item right now. Drupal Commerce resolves a price through a chain of price resolvers whose Context carries the customer, the store and the time, so a custom resolver can go and ask the ERP.Deep contract structures, same-day effective dates, lot or batch pricing, and any catalogue where the number of customer-item price rows is too large to publish.Page speed and availability. You have put your ERP on the critical path of your most-visited pages, and you now own a cache.

Checked against: Acumatica community 17608: "Only Default Price is supported" for Shopify price sync, Acumatica community 11823: BigCommerce price lists move on Prepare and Process, usually scheduled overnight, Drupal Commerce developer guide: price resolvers and the pricing Context, read 20 August 2026

What does each option cost in latency, and where does the caching go?

Options one, two and three cost nothing measurable at page load, because the price is already sitting in the platform’s own database by the time a request arrives. That is the whole appeal of a pushed price list, and it is why it survives contact with a Black Friday-sized traffic spike without anyone doing arithmetic first.

Option four is where latency becomes a design problem. A request-time price call adds a round trip to the ERP on the product page, the category listing, the cart and the checkout. The category listing is the one that catches teams out: a page showing 48 products needs 48 prices, and if the integration asks for them one at a time you have built something that gets slower as your merchandising improves. Any request-time design needs a batch endpoint that takes a customer and a list of item IDs and returns a list of prices in one call.

We do not publish first-party latency measurements for this, and we would treat anyone else’s single number with suspicion, because it changes completely with the ERP, the hosting region, the size of the price call and whether the ERP instance is also running a month-end close. What we will say is what the design has to contain, because that part does not vary.

Cache the answer keyed on customer or price class plus item plus quantity band, never on item alone, because an item-keyed cache will serve one customer’s negotiated price to another. Give the cache a time to live short enough that a same-day price change is visible within the window your commercial team can live with, and add an explicit invalidation path so a price change in the ERP can push the old entry out rather than waiting for it to expire. Then decide what happens on a cache miss when the ERP does not answer, which is the next section and the part most projects skip.

  1. A batch price endpoint that answers for a whole page of items in one call, not one call per product tile.

  2. A cache key that includes the customer or the A price class is a label on a customer account that decides which set of prices they see. Acumatica and most ERPs use price classes so a seller can maintain one price list for a whole tier of customers instead of one per account., the item, and the quantity band, because all three change the answer.

  3. A time to live set from how fast your prices actually change, not from a default someone copied out of a tutorial.

  4. An invalidation hook so an ERP price change evicts the stale entry instead of waiting out the clock.

  5. A defined behaviour on cache miss plus ERP timeout, written down and tested, before go-live.

Checked against: Drupal Commerce developer guide: the default price resolver runs at priority -100 so custom resolvers outrank it, read 20 August 2026, Cin7 Core: API call limit errors are a documented integration FAQ item, read 20 August 2026

How stale is a pushed price, and when does staleness become a commercial problem?

A pushed price is exactly as fresh as the last run of the job that pushed it. On the Acumatica to BigCommerce path that means the Price List entity’s Prepare and Process schedule, which sites commonly run overnight because it is expensive to run often. Cin7 Core’s sync behaviour is documented as a four-hour cycle in SparkLayer’s Cin7 Core integration documentation, which is a different shape of the same constraint.

Staleness only becomes a commercial problem in three specific situations, and if none of them apply to you the overnight push is fine and you should stop worrying about it. The first is a price that has to take effect the same day it is entered, which is normal in commodity trading, metals, fuel-indexed freight and resin. The second is a contract with an expiry date, because a flattened price list has no way to know that yesterday’s price stopped being valid at midnight. The third is a price that depends on something the push cannot see, such as the lot the stock came from.

There is a second kind of staleness that is easier to miss and harder to explain to a customer. A push can fail silently and leave the previous run’s prices in place, which looks identical to a successful run that produced no changes. Acumatica’s community carries a thread on exactly this shape of failure, "Error on Shopify Price List Sync: Sync ID is not found for the record", and a separate one where BigCommerce sales prices synced against the wrong unit of measure, which is a wrong price rather than an old one. Any pushed-price architecture needs a monitor that alerts on the job not running, not only on the job erroring.

The practical test is to ask your commercial team a single question: if a price we agreed this morning does not appear on the website until tomorrow morning, who notices and what does it cost us? If the honest answer is nobody and nothing, you are a price-list business and you should buy the cheap architecture with both hands.

Checked against: Acumatica community 22606: "Error on Shopify Price List Sync: Sync ID is not found for the record", Acumatica community 6697: BigCommerce sales price sync with the wrong unit of measure, SparkLayer documentation: Cin7 Core sync cycle and overselling guidance, read 20 August 2026

What does the storefront show when the ERP is down?

Every ERP goes offline. Acumatica instances take upgrade windows, Cin7 has maintenance, and both have the ordinary bad afternoon that any hosted system has. The difference between the four architectures is not whether they survive that, it is how visible the failure is to a buyer and how much of it you get to choose.

Options one, two and three degrade invisibly. The prices are already in the platform database, so the storefront keeps trading. What stops is order transmission, and orders queue instead. That is a genuine architectural advantage of the pushed price list and it rarely gets stated in a platform comparison, because platform vendors are not the ones who get the phone call.

Option four fails in public unless you have designed for it, and the design has to be decided by the business rather than by whoever writes the integration at 6pm on a Thursday. There are four honest behaviours and each of them is wrong for somebody.

Pick one, write it into the requirements, and then test it by turning the ERP connection off in a sandbox and looking at the page. A surprising number of teams discover at that moment that their storefront shows a price of zero, which is the one option nobody chose.

Four honest behaviours when a request-time price call fails, and what each costs
CriterionWhat the buyer seesWhen it is the right callWhat it costs you
Serve the last cached price, even if expiredMost distributors should choose this row and then write the honour-it policy down.A price, marked as indicative if you are being straight about it.Catalogues where prices move slowly and an hour-old number is almost certainly still correct.You may take an order at a price you no longer offer, and you have to decide in advance whether you will honour it.
Fall back to list priceThe published price, higher than the customer’s contract price.Almost never on a B2B storefront.You show a contract customer a number above their agreement, which is the exact failure the whole architecture existed to prevent.
Hide the price and offer a quoteA request-a-price control instead of a number, and an explanation.Quote-heavy sellers who already run a Quote to order is the process where a buyer asks for a price, a person or a system prepares a quote, and the accepted quote becomes an order. In much of B2B it is the normal way to buy, not an exception. process, and any catalogue where a wrong price is worse than no price.Conversion on that visit, and a spike of quote requests your desk has to absorb during the outage.
Block the pageA maintenance notice.Regulated or contract-compliance selling where an unpriced or mispriced order creates a real liability.The whole storefront, for the length of the outage. Choose this deliberately or not at all.

Checked against: Acumatica community 11823: scheduled Prepare and Process runs mean the storefront trades on the last successful run

How do you tell which one your business needs, without a discovery project?

Six numbers decide this, all of them already in your ERP, and any competent person in finance or sales operations can pull them in an afternoon. Get them before your next platform demo, because they change which demo is even relevant.

The read on the answers is blunt. If question three is a few thousand rows or fewer and questions four and five are zero, you are a price-list business, and options one and two are correct: buy the native connector, spend the saved money on catalogue data, and stop reading architecture pages. If question three runs to tens or hundreds of thousands of rows, or question four is meaningfully non-zero, you are a request-time business and no connector configuration will rescue that. Question six is the one that quietly kills pushed price lists on Shopify, because Shopify documented on 20 August 2026 that Basic, Grow and Advanced plans allow "up to 3 active catalogs across all your B2B markets", with a maximum of 25 catalogues per company location and 10,000 per store on Plus.

One honest caveat about the arithmetic. Row counts are a proxy for cost, not a rule. A distributor with 200,000 customer-item price rows that never change is easier to push than one with 8,000 that change daily. Use the count to tell you how big the push is, and use question four and question five to tell you whether the push can be right at all.

  1. How many distinct price classes or tiers do you maintain today? Count them in the ERP rather than estimating.

  2. How many customers hold at least one price that is not derived from their tier?

  3. How many customer-and-item combinations carry a negotiated absolute price? This is the row count you would have to publish.

  4. How many of those prices carry a future effective date or an expiry date?

  5. How often does a price change have to take effect the same day it is entered? If the answer is never, an overnight push is fresh enough and you have your answer.

  6. How many separate price groups would you have to express as catalogues or price lists on the platform you are considering, and what is that platform’s cap?

Checked against: Shopify Help Centre: B2B catalogues, catalogue counts by plan, read 20 August 2026, Shopify Help Centre: customizing B2B pricing using catalogs, read 20 August 2026

When is the cheapest architecture the right one?

We build integrations for a living, so read this section with that in mind: an agency has an obvious incentive to talk you into option four, and option four is wrong for a lot of the companies that ask us about it.

The scheduled push wins outright in four situations. It is also the right first phase for a business that will eventually need request-time pricing, because a phase one on pushed prices gets a storefront trading and tells you which prices actually get looked at, which is information you cannot buy any other way.

The case we will not call for you is volume breaks. Several vendors, Acumatica included, advertise that customer-specific volume break rules synchronize to the storefront, and we have not verified that end to end against a live instance. Shopify’s own documentation is clear that you can add up to ten price breaks per product and that once volume pricing applies "the price becomes fixed. Any overall adjustment discount set on the catalog won’t apply", which is a real constraint rather than a rumour. If break quantities are how your pricing works, prove the whole chain in a sandbox with your own data before you believe any of us.

  • Your negotiated prices are percentage discounts off list held on the customer record, with no absolute prices and no expiry dates. A Shopify catalogue with an overall percentage adjustment expresses that directly and correctly.

  • Your online catalogue is a deliberate subset sold at list, with contract accounts staying on EDI or with their rep. That is scoping the problem out, and it is frequently the right first release rather than a failure of nerve.

  • You have a small number of tiers, they change a handful of times a year, and you are inside your platform’s catalogue or price list cap with room to grow.

  • Your ERP instance is already near its API ceiling for other reasons, in which case putting a per-page-view price call on top of it is a capacity decision disguised as an architecture decision.

Checked against: Shopify Help Centre: quantity rules and volume pricing, "up to 10 price breaks per product", read 20 August 2026, Acumatica marketing page for the Shopify connector, claiming customer-specific pricing synchronized to Shopify, read 20 August 2026

The wider picture

This page answers one narrow question. Acro Commerce covers the strategy around it.

Common questions

Can Acumatica calculate a customer-specific price for the storefront in real time?
Acumatica can calculate it internally, but the native Shopify connector does not publish it. Acumatica’s community, asked directly about syncing the current effective sales price rather than the stock item Default Price, answered "No. Only Default Price is supported." Reaching the effective price at request time means calling Acumatica’s API from middleware or a custom service, and the community also carries an unresolved thread about getting a customer-specific price from the API with correct fallback logic, so budget that as development rather than configuration.
Is it ever acceptable to keep pricing rules in the ecommerce platform instead of the ERP?
Yes, when the rules are genuinely simple and the ERP is a bookkeeping system rather than an order entry system. If your discounts are percentages off list with no absolute negotiated prices and no expiry dates, expressing them as a Shopify catalogue adjustment or a BigCommerce customer group is cheaper and easier to audit than an integration. It stops being acceptable the moment a salesperson can agree a price in the ERP, because from then on every deal has to be keyed twice and the website will drift.
How long should a storefront cache a price it fetched from the ERP?
Set the time to live from how quickly your prices actually change, then add an invalidation path so an ERP price change can evict the entry early. A distributor whose prices move quarterly can cache for hours; a business with same-day effective dates needs minutes plus invalidation. The part that matters more than the number is the cache key: include the customer or price class, the item and the quantity band, because a key that only includes the item will eventually serve one customer’s negotiated price to another.
What should a B2B storefront show when the ERP is unreachable?
Whatever you decided in advance and tested, which for most distributors should be the last cached price, labelled as indicative, with a written policy on whether you honour an order taken at it. Falling back to list price is the worst common choice, because it shows a contract customer a number above their agreement. If a wrong price creates real liability, hide the price and offer a quote instead. Test the behaviour by disabling the ERP connection in a sandbox, because a storefront that silently renders zero is a surprisingly common discovery.
Does middleware count as a fifth place to calculate a price?
Only if you let it hold pricing rules of its own, and that is usually a mistake. Middleware is a layer of software that sits between the ERP and the storefront, translating and enforcing rules that neither system holds on its own. It can be a hosted integration platform or a custom service. earns its place by transporting, translating, batching and caching a price the ERP calculated, and by giving you somewhere to put retry logic and monitoring that neither the ERP nor the platform will host. The moment middleware starts deciding what a customer pays, you have a third pricing system that nobody in finance can audit and that no ERP report will agree with.
How many customer-specific prices are too many to push into a commerce platform?
There is no universal number, and the constraint that bites first is usually the platform’s grouping model rather than the row count. Shopify documented on 20 August 2026 that Basic, Grow and Advanced plans allow up to three active catalogues across all B2B markets, with 25 catalogues per company location and 10,000 per store on Plus, so a business needing hundreds of distinct price groups hits a structural wall well before it hits a data volume wall. Count your distinct price groups first, and only then count rows.

Last updated 2026-08-20. Facts on this page last checked against source 2026-08-20.