What the Shopify Admin API actually returns
Before designing anything that reads from Shopify, it helps to know precisely what is available, what requires permission, and what is simply absent. The third category is the one that reshapes projects.
The order, which is generous
The order object is rich and mostly does what you would hope.
You get the order name and identifier, timestamps for creation and payment, the financial and fulfilment status, and the full line items with quantity, price, product and variant references. Discounts are broken out at both order and line level, which matters — a discount applied to the order behaves differently in margin terms from one applied to a line.
Taxes are itemised. Shipping charged to the customer is separate from the goods. Refunds link back to the original order with their own line detail, and cancellations are distinguishable from refunds, which is a distinction most reporting gets wrong.
For working out what was sold and for how much, the API is comprehensive.
The transaction, which is where it stops
Each order carries transactions — the payment attempts and their outcomes. Here you find the gateway name, the kind of transaction, its status, and the amount in both shop and presentment currency.
Then you reach the fees field, and Shopify's documentation says:
Only present for Shopify Payments transactions.
The settlement currency and settlement rate fields carry the same restriction, and a few fields are limited to Shopify Plus stores.
For a Malaysian store this is the end of the money trail. Shopify Payments is not available in Malaysia, so the fee is empty, there is no net amount, and there is no payout object to query. The API will tell you a customer was charged and which gateway did it. What it cost, when you were paid, and which orders were in that payment are not there — see Shopify in Malaysia.
This is not a permissions problem. Requesting more scopes will not produce it, because Shopify never received the data.
Products, inventory and customers
Products and variants come with prices, SKUs, barcodes and options. Cost per item is available where the merchant has entered it, which many have not — worth checking before building margin reporting on it.
Inventory is exposed per location, which is what makes multi-location and marketplace stock sync possible at all.
Customers are gated. Personal data requires Shopify's protected customer data approval, granted on a minimum-necessary basis. Design so the connector still works with reduced customer access, because approval is not instant and may be narrower than requested.
The 60-day wall
The constraint that most often derails a migration plan.
By default an app can read the last 60 days of orders. Anything older requires an additional scope that Shopify must approve, requested through the Partner Dashboard with a written justification.
For an ERP this is not optional — historical migration, prior-year comparatives and any backfill all depend on it. Treat it as lead time at the start of the project, not a switch to flip when someone notices the backfill returning nothing.
How to ask for it efficiently
The API is GraphQL. REST has been legacy since October 2024 and new public apps have been GraphQL-only since April 2025.
Rate limiting is cost-based: each query has a calculated cost drawn from a bucket that refills per second — around 100 points per second on standard plans, more on higher tiers — and no single query may exceed 1,000 points. Responses report requested cost, actual cost and remaining capacity, and those figures should drive your pacing rather than a fixed delay, since the limit depends on the merchant's plan.
Two consequences worth designing around:
Ask for fewer fields. Cost scales with what you request. A query fetching everything because it might be needed will throttle you sooner than one that fetches what you use.
Use bulk operations for volume. They run asynchronously, return JSONL, and sit outside normal rate limits. For a nightly reconciliation pull this is the correct mechanism; paginated live queries are not.
What to do about the gap
Since the money data is not in Shopify, it comes from the gateway, and the connector needs both.
The workable design keeps them separate and joins deliberately:
From Shopify — orders, line items, discounts, taxes, refunds, cancellations, inventory. The commercial truth of what happened.
From the gateway — transaction references, fees, net amounts, payout batches, holds, chargebacks. The financial truth of what it cost and when you were paid.
The join — established on a proven field, verified against real data, and monitored, because it is the point where everything downstream either works or silently does not.
Then the bank confirms the third leg. How Shopify reconciliation actually works walks the whole sequence.
Common questions
Does the Shopify API include payment processing fees?
Only for stores using Shopify Payments. Shopify's documentation states that the transaction fees field is present only for Shopify Payments transactions, along with settlement currency and rate. Since Shopify Payments is unavailable in Malaysia, a Malaysian store's API returns the gateway name and the amount charged but no fee, net amount or payout data.
How far back can an app read Shopify orders?
Sixty days by default. Access to older orders requires an additional scope that Shopify must approve, requested through the Partner Dashboard with a written justification of why the app needs it. Historical migration and prior-year comparatives both depend on that approval, so it belongs at the start of a project plan.
How should a Shopify integration handle rate limits?
By reading the throttle information Shopify returns rather than using a fixed delay, since limits vary by the merchant's plan. Queries should request only the fields actually used, because cost scales with what is asked for, and large periodic pulls should use bulk operations, which run asynchronously and sit outside the normal rate limits.
What data does Shopify provide well?
Everything about the commercial transaction. Orders arrive with line items, quantities, prices, discounts separated at both order and line level, itemised taxes, shipping charged to the customer, and refunds linked back to the original order with cancellations distinguishable from refunds. For establishing what was sold and at what price, the API is comprehensive.
Related: what it takes to build a Shopify connector · how Shopify reconciliation actually works · Shopify in Malaysia
Read next
See what you could build
Start a free trial and describe what your business needs in plain language — SmartB Studio builds the module for you.
Start free trial