Table of Contents
- Key Highlights
- Introduction
- Why Shopify removed pre_tax_price and pre_tax_price_set (and what that implies)
- What pre_tax_price represented and why apps relied on it
- How this change affects merchants, apps, and integrators
- The GraphQL Admin API: why it’s the recommended route
- How to retrieve equivalent data with GraphQL (patterns and examples)
- Calculating pre-tax amounts when fields are removed
- Migration checklist: audits, code, webhooks, and data storage
- Edge cases and special considerations
- Testing strategy: building a robust verification suite
- Data retention and compliance: preserving records required for audits
- When contacting Shopify or Avalara makes sense
- Real-world migration examples
- Practical recommendations and timeline for developers and merchants
- FAQ
Key Highlights
- Shopify has removed the pre_tax_price and pre_tax_price_set fields from order line items in the REST Admin API after deprecating the Avalara AvaTax 1.0 integration; developers should use the GraphQL Admin API to obtain order pricing and tax-related details.
- Merchants and app developers must audit code paths, migrate data retrieval to GraphQL (or calculate pre-tax values from available fields), update webhooks and integrations, and preserve historical records needed for tax compliance.
Introduction
Shopify has quietly closed a gap that some merchants and third-party apps relied on: two REST fields that surfaced pre-tax pricing on order line items are gone. Those fields—pre_tax_price and pre_tax_price_set—were tied to the legacy Avalara AvaTax 1.0 integration, itself deprecated in April 2025. The immediate, practical consequence is straightforward: any code, webhook consumer, or reporting workflow that depended on those REST fields will stop receiving them.
Removing fields from an established API has ripple effects across fulfillment partners, taxes and accounting integrations, returns processing, and internal analytics. The easiest path forward is to retrieve the same or equivalent data from the GraphQL Admin API. Where direct equivalents do not exist, teams must compute pre-tax amounts from the available price and tax line fields and update storage and audit practices to retain the values required for tax reporting.
This article explains what was removed and why, breaks down how the change affects merchants and apps, provides concrete migration and computation patterns, offers sample GraphQL queries and Node.js examples, and outlines a practical testing and compliance checklist to minimize disruption.
Why Shopify removed pre_tax_price and pre_tax_price_set (and what that implies)
The two fields in question were specific to environments where the Avalara AvaTax 1.0 integration had been active. As Shopify moved to deprecate and retire that legacy integration in April 2025, associated data surfaces in the REST Admin API were also phased out. That reduces surface area for legacy features and aligns Shopify’s APIs with the supported tax flows and data models.
What it means in practice:
- Any REST call that previously returned pre_tax_price on order line items will now omit it entirely.
- Apps that used those fields as the canonical source of pre-tax amounts will no longer be able to rely on the REST Admin API for that value.
- The recommended approach is to use the GraphQL Admin API to access current order pricing structures and tax detail fields, or to compute pre-tax values from price and tax line items where necessary.
This removal is not an indication that Shopify has stopped supporting tax calculations or integrations; rather, it’s a targeted cleanup tied to a deprecated third-party integration. Developers should treat the change as an opportunity to standardize on GraphQL for richer, more consistent order data and to harden their tax and accounting workflows by explicitly computing and storing pre-tax values at capture time.
What pre_tax_price represented and why apps relied on it
The pre_tax_price field provided the line-item price amount before taxes were applied. Developers used it in multiple places:
- Accounting and reporting exports where pre-tax revenue is required.
- Refund and return calculations when determining taxable amounts.
- Third-party tax services and internal systems that required a pre-tax base price to compute taxes, discounts, and allocations consistently.
- Display logic where stores needed to show a “price before tax” in invoices or packing slips.
When available as a dedicated field, it saved implementers from recomputing values from multiple elements (unit price, quantity, tax lines, discounts) and reduced the risk of subtle rounding differences. With the field removed, teams that relied on it must recover the same information either from GraphQL fields that contain money structures or by calculating pre-tax amounts deterministically from the canonical price and tax fields.
How this change affects merchants, apps, and integrators
Impact categories:
- Operational reporting and accounting: Systems that ingest REST order payloads for bookkeeping might lose pre-tax amounts and thus produce inaccurate reports unless updated.
- Tax and compliance: Audits and tax filings often require a clear separation of taxable base amounts and tax charges. Removing direct pre-tax fields requires merchants to document how pre-tax values are derived.
- Fulfillment and returns: Return authorizations and partial refunds that depended on pre_tax_price for proportional tax refunds will need recalibration.
- Third-party apps: Tax, ERP, and analytics apps that read the REST Admin API must migrate to GraphQL or perform in-app calculations to preserve expected behavior.
- Webhooks and middleware: Webhook handlers (for orders/create, orders/updated, etc.) that parsed REST payloads must be reviewed; GraphQL subscription-equivalent flows or storage of derived pre-tax values may be required.
Practical examples:
- An accounting integration that produced CSV exports for QuickBooks based on REST order fields will now generate CSVs with missing pre-tax values. The integration must either compute those values before export or switch ingestion to GraphQL to retrieve the necessary money objects.
- A returns management app that issued tax-adjusted refund requests based on the pre_tax_price field will start under-refunding taxes if not updated. The app needs to calculate the pre-tax base from line item price and taxLines in GraphQL or recompute using a deterministic formula.
The GraphQL Admin API: why it’s the recommended route
GraphQL provides:
- A single endpoint to request precisely the nested fields you need (order → line items → price money objects and tax lines).
- MoneySet objects (shopMoney and presentmentMoney) that explicitly separate monetary amounts and currencies.
- More stable, expressive, and compact payloads when compared with REST, which helps minimize bandwidth and parsing complexity.
Shopify’s GraphQL schema exposes money-related objects and tax lines that can be used to compute pre-tax prices. While field names differ from the old REST fields, GraphQL returns granular elements that let developers reconstruct the pre-tax base deterministically:
- line item price sets (which include shopMoney and presentmentMoney)
- taxLines for the order or each line item, where applicable
- discount allocations and adjustments at the line level
Because GraphQL lets you request these specific nested values, it reduces the need to fetch additional endpoints or perform multiple REST calls to assemble the same dataset.
How to retrieve equivalent data with GraphQL (patterns and examples)
The exact field names may vary with API versions. Use the GraphiQL explorer or Shopify’s GraphQL Admin API reference for the active schema. Below are practical patterns that illustrate how to retrieve pricing and tax details needed to compute pre-tax amounts.
General GraphQL query pattern to inspect order line items, prices, tax lines, and discounts:
query GetOrderLineItems($id: ID!, $lineItemsFirst: Int = 50) {
order(id: $id) {
id
name
currencyCode
totalPriceSet {
shopMoney { amount currencyCode }
presentmentMoney { amount currencyCode }
}
lineItems(first: $lineItemsFirst) {
edges {
node {
id
title
quantity
priceSet {
shopMoney { amount currencyCode }
presentmentMoney { amount currencyCode }
}
discountedPriceSet {
shopMoney { amount currencyCode }
presentmentMoney { amount currencyCode }
}
discountAllocations {
allocatedAmountSet {
shopMoney { amount currencyCode }
presentmentMoney { amount currencyCode }
}
discountApplication {
allocationMethod
targetSelection
__typename
}
}
taxLines {
title
rate
priceSet { shopMoney { amount } presentmentMoney { amount } }
}
discountedTotalSet {
shopMoney { amount currencyCode }
presentmentMoney { amount currencyCode }
}
}
}
}
}
}
Notes on this pattern:
- priceSet represents the line item’s price money object (unit price × quantity may be needed depending on shape).
- taxLines contains tax charge lines applied at the line level including rate and priceSet; the presence of taxLines depends on how taxes were calculated at checkout.
- discountAllocations and discountedPriceSet show per-line discount effects and can be necessary when reconstructing the pre-tax base for discounted items.
Practical Node.js example invoking the GraphQL Admin API:
const fetch = require('node-fetch');
async function fetchOrderGraphQL(shopDomain, accessToken, orderId) {
const endpoint = `https://${shopDomain}/admin/api/2025-10/graphql.json`; // replace API version if needed
const query = `query ($id: ID!) {
order(id: $id) {
id
name
currencyCode
lineItems(first: 100) {
edges {
node {
id
title
quantity
priceSet {
shopMoney { amount currencyCode }
presentmentMoney { amount currencyCode }
}
taxLines {
title
rate
priceSet {
shopMoney { amount }
}
}
discountAllocations {
allocatedAmountSet {
shopMoney { amount }
}
}
}
}
}
}
}`;
const res = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': accessToken
},
body: JSON.stringify({ query, variables: { id: orderId } })
});
return res.json();
}
Adjust the API version path to the active GraphQL Admin API version and verify that the GraphQL types exist. Use the GraphiQL explorer in your Shopify Partner or store admin to confirm available fields.
Calculating pre-tax amounts when fields are removed
When a direct pre_tax field is not provided, compute the pre-tax amount deterministically from available pieces: the line item price, quantity, discounts, and tax lines. The general formula is:
pre_tax_line_total = line_gross_total - tax_amount
Where:
- line_gross_total is the line item’s gross total after discounts (or before discounts, depending on what you intend to represent—record clearly which).
- tax_amount is the sum of taxLines for that line item.
A more explicit step-by-step approach:
- Retrieve the unit price and quantity:
- unit_price = priceSet.shopMoney.amount
- quantity = lineItem.quantity
- Compute gross_line_total = unit_price × quantity
- Subtract line-level discounts:
- If discountAllocations exist, compute total_discount = sum(allocatedAmountSet.shopMoney.amount) and net_line_total = gross_line_total - total_discount
- Otherwise, net_line_total = gross_line_total
- Compute tax_amount:
- If taxLines exist at the line level, tax_amount = sum(taxLine.priceSet.shopMoney.amount)
- If taxes are applied at the order level, tax allocation must be proportionally distributed to the line (see proportional allocation approach below)
- pre_tax_line_total = net_line_total - tax_amount
Proportional allocation for order-level taxes: When taxes are applied at the order level (not per-line), distribute order-level tax to line items based on their share of the net order subtotal:
- Compute each line's net_line_total (unit price × quantity minus discounts)
- Compute subtotal = sum(net_line_total for all lines)
- For each line, allocated_tax = (net_line_total / subtotal) × total_order_tax
- pre_tax_line_total = net_line_total - allocated_tax
Rounding considerations:
- Currency rounding can introduce cent-level discrepancies when taxes or discounts are allocated proportionally.
- Keep the same rounding rules Shopify uses (typically round per-line to the smallest currency unit) and store intermediate values (e.g., per-line allocated tax amounts) to replicate exact totals.
- For auditability, preserve raw numeric values returned by Shopify (shopMoney amounts), and log calculations with the rounding method used.
Example calculation in JavaScript:
function computePreTaxLine(netLineTotal, taxLines, allocatedTax = 0) {
// netLineTotal: number (e.g., 19.99)
// taxLines: array of objects with price.amount values (e.g., [{ price: 1.50 }])
const taxFromLines = taxLines.reduce((sum, t) => sum + Number(t.price), 0);
const totalTax = taxFromLines + allocatedTax;
const preTax = Number((netLineTotal - totalTax).toFixed(2));
return { preTax, totalTax };
}
Preserve the unrounded intermediate values for traceability.
Migration checklist: audits, code, webhooks, and data storage
Follow this checklist to minimize business interruption.
-
Inventory dependencies
- Search source code repositories, Lambda functions, middleware, analytics scripts, and server logs for occurrences of pre_tax_price and pre_tax_price_set.
- Identify third-party apps and partners that pull REST order data for tax, accounting, or returns.
-
Choose the retrieval strategy
- Preferred: switch to GraphQL Admin API to fetch line item priceSet/taxLines/discountAllocations.
- Alternative: continue using REST but compute pre-tax values from REST fields that remain (unit_price, tax_lines, discount_allocations); verify which REST endpoints still return consistent money objects.
-
Replace REST calls with GraphQL or implement local computation
- For each code path, implement a GraphQL query that returns the necessary money objects.
- Where pre_tax is reconstructed, implement deterministic code that matches Shopify’s rounding rules.
-
Update webhooks and middleware
- Webhook payloads for orders may be separate from GraphQL; ensure new handlers either compute pre-tax values at webhook reception or push incoming orders into a queue to fetch necessary GraphQL data.
- Consider a short-lived background job to enrich webhook data with tax allocation details.
-
Preserve historical pre-tax values
- If historical accuracy is required for accounting, export or recompute pre-tax values for older orders captured while pre_tax fields existed. Ideally, capture and persist the calculated pre-tax amount alongside each order record.
- Where recomputation may yield different cent-level results due to rounding, store both the computed pre-tax and the original tax lines for auditability.
-
End-to-end testing
- Create test orders in a developer store with a mix of tax rules: line-level taxes, order-level taxes, multiple jurisdictions, discounts, and different currencies.
- Validate computed pre-tax totals against expected values and ensure sum consistency with order totals after rounding.
-
Partner and merchant communication
- Notify merchants and integration partners about the change and provide migration documentation, example queries, and recommended timelines.
- Provide a rollback contingency: keep a compatibility layer for a short period that computes pre-tax values for older code while teams finish migration.
-
Logging and monitoring
- Add logs that flag when pre-tax cannot be reconstructed cleanly (e.g., missing tax lines and missing allocation metadata).
- Monitor for customer support cases tied to refunds, invoices, and tax calculations.
Edge cases and special considerations
Multi-currency orders and presentment vs shop money
- Shopify returns money objects both in shopCurrency (the store’s base currency) and presentmentCurrency (the customer's displayed currency during checkout). Determine which currency base your accounting workflows expect and compute pre-tax amounts in that currency consistently.
- Use shopMoney values for accounting records tied to the store’s ledger. Use presentmentMoney if you must display the amount in the customer’s currency as it appeared at purchase.
Discount mechanics
- Discounts can be applied at the line item or order-level and may affect the pre-tax base. Confirm whether discounts are tax-inclusive or tax-exclusive for your jurisdiction and store settings.
- If discounts change the taxable base (for example, percentage discounts typically reduce the taxable base), ensure your pre-tax calculation subtracts discounts before tax allocation.
Exempt items and tax overrides
- Some items may be tax-exempt. For such lines, taxLines may be empty or have rate 0; pre-tax equals net_line_total.
- Tax overrides or manual tax adjustments may appear in order attributes or as separate adjustments; record these in your audit trail.
Partial refunds and returns
- When processing partial refunds, compute the amount of tax to refund in proportion to the refunded quantity and its pre-tax base, using the same allocation and rounding rules as at purchase time.
- If refunds are processed after changes in tax rules, preserve original order tax data to ensure correct historical refunds.
Legacy Avalara behaviors
- If your business relied on the behavior of Avalara AvaTax 1.0 specifically (for instance, how it rounded or allocated taxes), validate that your recomputed values align with historical records. Differences in rounding strategy can create small mismatches.
Testing strategy: building a robust verification suite
Automated tests
- Unit tests for pre-tax calculation logic covering: single-line orders, multiple-line orders, discounts, order-level taxes, proportional tax allocation, presentment vs shop currency, and edge rounding cases.
- Integration tests that run the complete GraphQL query against a sandbox store with known sample orders and verify expected pre-tax results.
Manual scenarios to cover
- Orders with multiple tax jurisdictions (where shipping and billing addresses differ in tax implications).
- Orders with mixed taxable and non-taxable items.
- Orders with applied gift cards and their effect on taxable base depending on settings.
- High-volume scenarios to surface performance issues when switching from REST polling to GraphQL queries.
Data reconciliation
- Run parallel exports: keep the existing REST-based export (before removing) and the new GraphQL-based or computed export for a period. Reconcile totals and investigate discrepancies, focusing on rounding differences.
- For historical orders, compute a reconciliation report showing original REST pre_tax values (if any saved locally) against the recomputed pre-tax result and record any systematic offsets.
Monitoring and alerts
- Set alerts for when computed pre-tax totals do not sum to order total minus taxes and discounts within a cent-level tolerance.
- Track customer support tickets by tag (refunds, invoices) and watch for spikes after migration rollouts.
Data retention and compliance: preserving records required for audits
Tax authorities and auditors expect clear documentation for taxable bases and tax collected. Removing a convenience field forces teams to demonstrate how pre-tax values are derived.
Best practices:
- Always store priceSet, taxLines, discountAllocations, and the computed pre_tax value at the time of order capture. Do not rely on re-fetching past orders and recomputing on demand—recomputation risks differences due to API changes, rounding, or changed tax rules.
- Timestamp computed values and preserve the full set of raw money objects returned by Shopify for the order.
- If possible, store both shopMoney and presentmentMoney objects along with the currency code to ensure clarity in cross-currency audits.
- Add metadata indicating the calculation method and API version used when pre-tax was computed.
Regulatory deadlines and retention policies
- Consult local tax regulations for the period you must retain invoice-level documentation. Ensure your migration preserves required fields for that entire retention window.
- If the removal of pre_tax fields results in lost historical data and you need to recreate it, document the reconstruction method and the assumptions used.
When contacting Shopify or Avalara makes sense
Contact Shopify support if:
- You find missing order-level elements in GraphQL that you believe should be present.
- There is an inconsistency between what REST previously returned and what GraphQL returns for the same order.
- You uncover behavior suggesting an API bug causing tax or money fields to be returned incorrectly.
Contact Avalara (or your tax provider) if:
- You relied on AvaTax 1.0-specific behavior for tax calculation and need guidance on migration paths to a supported integration.
- You need to reconcile differences between historical Avalara outputs and Shopify’s recomputed amounts.
Document each support interaction and include example order IDs, timestamps, and payload dumps to expedite troubleshooting.
Real-world migration examples
Example 1: accounting integration for a mid-size apparel brand
- Situation: The brand exported REST orders nightly to populate pre-tax sales into their ERP. After field removal, exports were missing pre-tax columns.
- Action: Engineering replaced nightly REST exports with a GraphQL job. For each order, they fetched lineItems.priceSet, lineItems.discountAllocations, and order.totalTaxSet. Their script recomputed pre-tax per line using the proportional tax allocation method for orders with order-level tax. They preserved computed pre-tax amounts in the ERP with audit traces.
- Result: Reconciled exports matched historical records within one cent per order. The company avoided a disruption in monthly tax filing.
Example 2: returns platform for electronics retailer
- Situation: Refund scenarios used pre_tax_price to calculate tax refunds; missing field caused under-refunding.
- Action: Returns app added GraphQL calls at refund creation to compute the pre-tax base for refunded quantities using unit price and line tax allocations. They added unit tests for rounding behavior to match Shopify’s expected totals.
- Result: Refunds aligned with merchant expectations and avoided customer complaints.
Example 3: multi-currency marketplace with mixed tax jurisdictions
- Situation: Sellers on a marketplace displayed pre-tax prices in presentment currency for customer invoices.
- Action: The marketplace stored both shopMoney and presentmentMoney at order time, computed pre-tax in presentment currency for invoices, and separately computed shopMoney pre-tax values for VAT reporting in the seller’s country.
- Result: Sellers received consistent invoices matching checkout displays and could file taxes correctly in their local currency.
Practical recommendations and timeline for developers and merchants
Short-term (within 2–4 weeks):
- Audit your codebase and third-party integrations for dependencies on the removed fields.
- Implement GraphQL queries to fetch the necessary price and tax objects for new orders.
- Start logging computed pre-tax values for every incoming order and store raw money objects for auditability.
Medium-term (1–3 months):
- Migrate webhook consumers to enrich payloads with computed pre-tax data or persist GraphQL snapshots on order creation.
- Run reconciliation between legacy REST-based values (if stored) and new computed values; adjust rounding logic as needed.
- Update documentation, run training for customer support, and notify partners of the new data model.
Long-term (3–12 months):
- Standardize to GraphQL for order data retrieval to reduce fragility in integrations.
- Implement periodic audits to ensure computed tax and pre-tax values remain consistent as the store’s tax rules or Shopify’s APIs evolve.
- Maintain an immutable audit record of each order’s raw Shopify returns and the computed tax/pre-tax values.
FAQ
Q: Which fields were removed exactly? A: The REST Admin API fields pre_tax_price and pre_tax_price_set that used to appear on order line items have been removed. These fields were available specifically for stores using the legacy Avalara AvaTax 1.0 integration, which Shopify deprecated in April 2025.
Q: Does Shopify still provide tax detail for orders? A: Yes. Shopify continues to provide tax-related information via its APIs. Use the GraphQL Admin API to retrieve line-level price sets, taxLines, discountAllocations, and order-level tax sets. Those fields and money objects allow you to compute pre-tax amounts where necessary.
Q: Can I still get pre-tax values from the REST Admin API? A: Not via the removed pre_tax_price and pre_tax_price_set fields. You may compute pre-tax values from remaining REST fields if present, but the recommended path is to migrate to the GraphQL Admin API which provides richer, nested money objects.
Q: How do I calculate a pre-tax amount for a line item? A: Compute the net line total (unit price × quantity minus any discounts) and subtract the applicable tax for that line. If taxes are only available at the order level, allocate them proportionally to lines based on their share of the net subtotal. Preserve rounding consistency and store intermediate values for auditability.
Q: What about multi-currency orders? A: Store both shopMoney and presentmentMoney values and clearly pick which currency basis you use for accounting. For official bookkeeping, use the store’s shop currency amounts (shopMoney). For customer-facing displays or refunds in presentment currency, use presentmentMoney.
Q: Will Shopify provide a migration tool? A: Shopify’s official guidance is to use the GraphQL Admin API and compute pre-tax values as needed. There is no universal migration tool provided for every use case; you will need to update your apps and exports or reach out to Shopify support for assistance with specific cases.
Q: What should we do about historical orders? A: If you need historical pre-tax values for compliance, export stored raw money objects and tax lines now, and if you do not have them, reconstruct pre-tax amounts using the same calculation rules that Shopify used at the time of purchase. Document assumptions and methodology and keep the raw data for audit trails.
Q: Who should I contact if I find inconsistencies after migrating? A: Contact Shopify support with detailed examples (order IDs, timestamps, payloads) if you suspect a platform issue. If the inconsistency is tied to Avalara-like behavior or a unique tax calculation, contact your tax provider (e.g., Avalara) for reconciliation guidance.
Q: Are there any known rounding pitfalls? A: Yes. Rounding differences often cause cent-level mismatches. Ensure you replicate Shopify’s rounding approach—rounding at line-level in the smallest currency unit—and preserve intermediate values to avoid cumulative differences.
Q: How can I minimize disruption to customers? A: Implement a staged migration: run GraphQL-based enhancements in parallel with legacy flows, add monitoring, and keep a compatibility layer that computes pre-tax for older code until all paths migrate. Communicate with partners and provide a rollback plan if issues arise.
If you need step-by-step code tailored to your application stack (Python, Ruby, PHP, or Node.js) or a review of a specific GraphQL query for your store’s schema, share the details and I can produce a focused migration script and test cases.