Last updated: March 2026
If you're running Google Shopping or Performance Max for a Shopify store, there are two data setups that most merchants skip โ and both directly impact how well Google can optimise your campaigns:
- COGS in your product feed โ tells Google the margin on each product via Google Merchant Center, enabling profit-based reporting
- Conversions with Basket Data โ passes item-level purchase data back to Google Ads, unlocking product-level ROAS and Gross Profit reporting
These are handled by two different tools that work together:
| What | Tool | How |
|---|---|---|
| COGS submission | Simprosys Google Shopping Feed | Feed attribute sent to Merchant Center |
| Basket data conversions | Google Tag Manager | Purchase event with item data sent to Google Ads |
You need both. Simprosys is a feed management tool โ it handles what data goes into your product feed. GTM is a tag management tool โ it handles what happens when a conversion fires. They solve different problems.
This guide walks through both setups.
What Is Conversions with Basket Data?
When a customer completes a purchase, a standard conversion tag fires and tells Google: a purchase happened, worth $X.
Conversions with basket data goes further. It sends Google the full order contents โ every product ID, quantity, unit price, and cost of goods โ so Google knows exactly which products were purchased.
This unlocks:
- Product-level ROAS in your Google Ads reports (which products are actually profitable after COGS)
- Smarter PMax optimisation โ Google learns which products convert at the best margin, not just the highest revenue
- Gross Profit ROAS as a reportable metric, broken down per product
- Accurate POAS (Profit on Ad Spend) when combined with COGS data
Without this data, Google sees every purchase as a single revenue number. With it, Google sees your business the way you do.
What You'll Need Before Starting
- A Shopify store
- Simprosys Google Shopping Feed installed (for COGS submission)
- Google Tag Manager installed on your store (for basket data conversion tracking)
- A connected Google Ads account
- A connected Google Merchant Center account
- Cost of goods entered in Shopify for each product variant (optional but recommended)
Part 1 โ Submit COGS via Simprosys (Feed Management)
Simprosys submits your cost of goods data to Google Merchant Center as the cost_of_goods_sold feed attribute. Google uses this to calculate Gross Profit in your reporting.
This has nothing to do with conversion tracking. It's purely a product feed attribute.
Method 1 โ Shopify's Built-In Cost Per Item (Recommended)
Shopify Admin โ Products โ [Product] โ Variants โ Cost per item
Enter the cost price (ex-tax) per variant. Simprosys reads this automatically and includes it in your feed.
Priority: Highest โ overrides other methods. Best for stores that already track inventory costs in Shopify.
Method 2 โ Simprosys Automated Rules
In Simprosys, go to Feed Rules โ Automated Rules and create a rule to set cost_of_goods_sold as a calculated value โ for example, price ร 0.45 for a product category with 55% margins. (Simprosys COGS docs)
Best for: Stores with consistent category-level margins but no per-product cost data.
Method 3 โ CSV Export/Import
Export your feed as CSV, add a cost_of_goods_sold column with values in 15.00 AUD format, then re-import.
Priority order: Shopify Cost per Item โ Automated Rules โ CSV Import.
Verify in Merchant Center
Go to Products โ All Products โ click a product. Look for cost_of_goods_sold under Product Data. If missing, check the priority order above.
Part 2 โ Enable Basket Data Conversions via Google Tag Manager
This is the conversion tracking side โ handled entirely in GTM, not Simprosys.
Step 1: Add the Purchase Data Layer to Shopify's Thank You Page
In your Shopify Admin, go to Settings โ Checkout โ Order status page โ Additional scripts.
Add this Liquid/JavaScript code. It pushes a purchase event with full basket data to GTM on every order confirmation:
The script pushes a standard GA4 ecommerce purchase event to the data layer, including transaction_id, value, currency, and an items array. Each item in the array includes item_id (mapped to Shopify's line_item.product_id), price, quantity, and cost_of_goods_sold (from line_item.variant.cost, defaulting to 0 if blank).
You can find the complete Liquid code snippet in Google's basket data implementation guide or in the Analyzify Shopify data layer guide.
Key variable mappings:
transaction_id: Shopify order numbervalue: Total order value (price in cents รท 100)item_id:line_item.product_idโ must match your Merchant Center feed IDcost_of_goods_sold:line_item.variant.costโ the "Cost per item" from Shopify
Shopify Plus note:
line_item.variant.costis supported on all Shopify plans that have Cost per Item set. Test in GTM Preview mode before going live.
Notes:
line_item.product_idmust match theidin your Merchant Center feed for basket data to work. If your feed uses SKUs as IDs, useline_item.variant.skuinstead.line_item.variant.costpulls the "Cost per item" from Shopify. If blank, defaults to0. Standard Shopify plans support this โ test to confirm.
Step 2: Configure GTM
In your GTM container, create the following:
Data Layer Variables:
| Variable Name | Data Layer Variable Name |
|---|---|
| DLV - Transaction ID | ecommerce.transaction_id |
| DLV - Value | ecommerce.value |
| DLV - Currency | ecommerce.currency |
| DLV - Items | ecommerce.items |
Custom Event Trigger:
- Type: Custom Event
- Event name:
purchase - Name: "CE - Purchase"
Google Ads Conversion Tag:
- Find your existing Google Ads purchase conversion tag
- Enable "Send transaction-specific data"
- Map: Transaction ID โ
DLV - Transaction ID, Revenue โDLV - Value, Currency โDLV - Currency - Enable "Provide item data" and map
DLV - Itemsas the items array
The cost_of_goods_sold field inside each item object is read automatically by Google Ads.
Step 3: Test With GTM Preview Mode
- In GTM, click Preview to open Tag Assistant
- Complete a test purchase on your store
- In Tag Assistant, check the Data Layer tab on the
purchaseevent - Confirm
ecommerce.itemscontainsitem_idandcost_of_goods_soldper item - Confirm your Google Ads conversion tag fires once on the thank you page
Once confirmed, Publish your GTM container.
Step 4: Verify in Google Ads
After 24โ48 hours, go to:
Google Ads โ Tools โ Conversions โ [Your Purchase Conversion]
Under the conversion action details, you should see "Basket data" listed as active.
Then go to: Reports โ Predefined Reports โ Shopping โ Shopping โ Item ID
Add columns: Gross Profit, Gross Profit ROAS. If basket data is working, these will be populated per product ID.
Part 3 โ Register COGS as a GA4 Custom Dimension (Optional)
If you're also sending purchase events to GA4 via GTM, register cost_of_goods_sold as an item-scoped custom dimension so it's reportable in GA4:
- In GA4, go to Admin โ Custom Definitions โ Custom dimensions
- Click Create custom dimension
- Dimension name:
cost_of_goods_sold - Scope:
Item - Item parameter:
cost_of_goods_sold
This makes Gross Profit visible in GA4's e-commerce reports.
Why This Matters for PMax and DukesMatrix
Once Google has both the feed COGS (from Simprosys) and basket data (from GTM), it can calculate Gross Profit ROAS (POAS) per product. This is exactly what DukesMatrix uses in POAS mode โ scoring products on gross profit rather than revenue ROAS, so your budget flows to the products that actually make money.
Without COGS data, Google optimises for revenue and will scale your highest-ticket products regardless of margin. With it, it learns to favour products with the best margin ร conversion rate combination.
Common Issues
Basket data not appearing after 48 hours: Usually a mismatch between the item_id in your purchase event and the product id in your Merchant Center feed.
COGS missing in Merchant Center: Check the priority order. If Shopify's Cost per Item is empty and no Automated Rule covers the product, COGS will be blank.
Duplicate conversions: If you previously set up conversion tracking another way, disable those tags before publishing your GTM basket data tag.
cost_of_goods_sold showing as 0: The Shopify "Cost per item" field for that variant is empty. Populate it in Shopify Admin or add an Automated Rule in Simprosys as a fallback.