How to Import Meta and TikTok Ad Costs Into GA4 for a Shopify Store

|Dan Giura
How to Import Meta and TikTok Ad Costs Into GA4 for a Shopify Store

TL;DR

Getting Meta and TikTok spend into GA4 is now mostly a tagging job. Google's connectors pull cost daily, with 24 months of history, and join it to your sessions on source, medium and date [1]. They only work if all paid traffic from one platform carries one source and one medium, set before you connect. On a Shopify store running WeltPixel Conversion Tracking, the purchase side of the join is already there: the app sends the GA4 purchase inside the shopper's session, with that session's campaign values, whenever the shopper's browser reached the app. The app never touches cost.

Key Takeaways

  • Required join keys are utm_source, utm_medium and the date. Without utm_id or utm_campaign, cost is reported in aggregate instead of per campaign [1][4].
  • Pick one source and one medium for paid Meta traffic, and one pair for TikTok, before you connect. They're locked once the connector exists [2].
  • Fill utm_id with {{campaign.id}} on Meta and __CAMPAIGN_ID__ on TikTok [10][11].
  • Delete any cost dataset you uploaded by hand for the same platform first. GA4 doesn't de-duplicate the two [3].
  • Check Reports > Data import > Campaign data import validation for "No Analytics data" rows before you read any ROAS [8].
  • Imported cost isn't available in audiences or Exploration segments [6].

What does GA4 data import join your ad costs on?

Source, medium and date. Campaign name and campaign ID stopped being required key fields on February 3, 2025 [4]. Google's help page: "Campaign data is joined to Analytics data using the required keys (utm_source, utm_medium, and date)" [1]. The menus say Campaign data now, since Google renamed Cost data import on November 19, 2025 [4].

Key Google's status [1] What it does in your reports
utm_source Required Must match the value in your ad URLs exactly
utm_medium Required Same exact match
Date Required Cost is aggregated by day
utm_id (Campaign ID) Optional, but highly recommended Puts cost on the campaign row
utm_campaign Optional, but highly recommended Same, by name
Currency Required if cost is included Connectors convert it for you [2]

The optional rows decide how useful the result is. Without campaign name or ID, Google says cost "will be reported in aggregate when these dimensions are requested" [4]: what Meta cost in total for that medium and date, nothing per campaign.

Google's own example is that "Facebook" and "facebook" "aren't exact matches" [1]. Case, the paid-medium pattern and naming in general are covered in the UTM tagging rules; the cost join adds only what follows.

Tag every Meta and TikTok ad URL with one fixed pair

The connector is stricter than a file upload: "All of your paid traffic from the selected 3P source should be tagged with a single unique value for utm_source and a single unique value for utm_medium" [1]. GA4's Meta connector allows one source for all paid Meta traffic or one per Meta platform, with separate fields for Facebook, Instagram, Audience Network, Messenger and Threads [2]. TikTok has one source field and one medium field [3].

Source and medium go in as literal text. The ID and the campaign name can be ad-platform macros: Google's import screens don't accept {{...}} placeholders, and its page says "you must resolve these parameters at the ad platform level" [1]. For example, in each ad's URL parameters:

Meta:   utm_source=facebook&utm_medium=paid_social&utm_campaign={{campaign.name}}&utm_id={{campaign.id}}
TikTok: utm_source=tiktok&utm_medium=paid_social&utm_campaign=__CAMPAIGN_NAME__&utm_id=__CAMPAIGN_ID__

Those values are examples. Pick your own with the naming rules, then use the same strings in every ad on that platform.

Meta says name-based macros come from "a snapshot" of the names stored when the ad is first published, and it "pulls from the snapshot rather than the live value" [10]. Rename a campaign in November and the URL keeps the old name, while the ID stays put. That's the practical reason to send utm_id. TikTok "offers an option to automatically add UTM parameters" [11], but its page doesn't say which values it writes, so set them yourself.

Decide the pair before you create the connector. GA4 won't let you fix it afterwards: "you won't be able to modify configuration settings relevant to data pulling such as Ad Account, Source, and Medium", and the only way out is deleting the connector and building a new one [2].

Connect Meta and TikTok in Data import

You need at least the Editor role in the GA4 property [2], and for TikTok at least the Analyst role in TikTok Ads [3]. If you've been pasting Ads Manager spend into a sheet every Monday and uploading it, delete that dataset first: GA4 "does not attempt to de-duplicate information between these 2 methods" [3].

  1. In Admin, under "Data collection and modification", click Data import [2].
  2. Click Create import source, name it, and select Campaign data as the data type.
  3. Under "Upload data for import", select Meta (or TikTok), click Connect and sign in.
  4. Meta: select the Business Center and Ad Account, then enter your source in the five platform source fields (the same value in all five if you use one) and your medium [2].
  5. TikTok: select the Business and Ad account, then enter the Campaign source and Campaign medium [3].
  6. Review the mapped fields and click Finish.

The connector runs daily and "will attempt to pull 24 months of historical data" [1]. Imports "can take up to 30 minutes to complete and up to 24 hours for the data to be available in reports" [2]. Cost currency is converted automatically [2][3]. Reddit (July 21, 2025), Snap (September 17, 2025) and Pinterest (September 26, 2025) got the same kind of connector earlier [4].

The file route (CSV, Google Sheets, SFTP, BigQuery and other storage sources) is for a platform whose paid traffic carries more than one source or medium, or a network without a connector [1]. Since July 28, 2026 a file with cost needs a currency field [5], and Google allows 120 uploads per property per day [6].

Where does the Shopify order meet the cost?

The order meets the cost in the session: the cost row is keyed on source, medium and date, so a sale sits next to its spend most directly when the purchase lands in the session those tags started.

On a store running WeltPixel Conversion Tracking, the app picks up the landing URL's campaign values in the browser, utm_id included, for the current GA4 session. When the order comes in, it sends GA4's purchase from the Shopify order, server-side, under that shopper's client ID and session ID, with the session's source, medium, campaign and campaign ID attached. The revenue lands in the row the imported cost joins to. Why a purchase starts a new session explains why the session ID matters more than the client ID.

There's one exception. When the shopper's browser never reached the app before the order, the purchase still reaches GA4, under a stand-in identity with no campaign values, so it can't land on a paid row. Google, meanwhile, "will report your cost, impressions and clicks on any combination of the imported required dimensions regardless of match rate" [1]. The spend shows and that sale doesn't. A visit that loses its tags between the ad and checkout lands outside the paid rows the same way.

Browser events respect Shopify's Customer Privacy API signals. The app also has an optional setting that skips the server-side GA4 purchase for visitors who declined analytics; if it's on, those visitors' orders aren't in GA4 to join.

The app doesn't import, read or send ad cost. GA4 gets cost from Meta and TikTok directly. All the join needs from the app is the GA4 purchase, which is on the free plan (GA4 only, up to 100 storefront orders a month) [12].

Check which rows joined in the validation report

Google added this report on August 10, 2026 [5], at Reports > Data import > Campaign data import validation [1]. It's session scoped and filtered by default "to only look at PAID manual campaigns, excluding all google sources and search mediums" [8].

  1. Open the report on a full week after the connector's first day.
  2. Read the status for each row [8]:
Status Google's description Where to look
Joined "Your campaign data was successfully joined to Google Analytics." Nothing to do
No campaign data "Your campaign data was NOT imported for this dimension or it was not joined correctly." Compare the row's source and medium with the connector's values
No Analytics data "Imported data was not joined and will be reported individually without Analytics data." Find the ads whose URLs don't carry the fixed pair
  1. For each "No Analytics data" row, open a live ad from that campaign and read its destination URL for a typo, a capital letter or a missing parameter.
  2. Then open Reports > Acquisition > Non Google campaign, and Advertising > Planning > All channels [1].

GA4 joins the cost when the report runs, and the connector tries to pull 24 months, so this report is also where you see which past days joined. Query-time data like cost is "not available when you're creating audiences" or Exploration segments [6]. Google says it "can be joined within BigQuery" [6]; if you work from the GA4 BigQuery export, that join is yours to write.

Why won't GA4's ROAS for Meta match Ads Manager?

The two tools credit different visits for the same money. All channels defines return on ad spend as "the revenue for selected key events divided by the total cost for your ads" [7]. On a store running the app, the revenue in that numerator is the order total, the same total_price the app sends Meta and TikTok on Plus, with tax and shipping in and discounts netted. What your purchase value includes covers that choice. If you want one number with no attribution in it at all, one blended ROAS across Shopify, Meta and Google Ads is the other instrument; GA4's version is per channel and attributed.

GA4 hands out credit by the property's reporting attribution model, and Google recommends Data-driven attribution for this report [7]. All of GA4's models "exclude direct visits from receiving attribution credit, unless the path to key event consists entirely of direct visits" [9]. GA4 can only credit Meta and TikTok with visits your tagged Meta and TikTok links produced. Meta and TikTok count by their own clicks and views, in their own attribution windows.

Refunds widen it over time. On Plus the app sends refunds to GA4, and Meta and TikTok never receive one.

When you filter the report to a subset of key events, Google says the cost shown "represents the full cost of that campaign and is not further subdivided" [7]. Filter to purchase only, and every dollar of the campaign's spend still sits against it.

FAQ

Do I still need a CSV to get Meta or TikTok ad costs into GA4?

No. Since October 7, 2025 both have a direct connector that runs daily [4]. A file only makes sense when one platform's paid traffic carries more than one source or medium pair, which the connector can't take [1].

Is utm_id required for GA4 campaign data import?

Source, medium and date are required [1]; utm_id isn't. Without utm_id or utm_campaign, GA4 reports the cost in aggregate for that source and medium [4], so you lose the per-campaign view.

Does WeltPixel Conversion Tracking send ad spend to GA4?

It sends the purchase from the Shopify order, inside the shopper's GA4 session with that session's campaign values. Cost comes into GA4 from Meta and TikTok through Google's own connectors.

Put the purchase in the session the cost joins to

WeltPixel Conversion Tracking sends the GA4 purchase from the Shopify order, server-side, in the shopper's session with its source, medium, campaign and utm_id, which is the half of the cost join that lives on your store. Plus, at $39/month with no order limit, adds Meta, TikTok and the other integrations, sends refunds to GA4 and also sends admin, POS and draft orders; the free plan covers GA4 only, up to 100 storefront orders a month [12].

Sources

  1. Google Analytics Help, "Import campaign data", support.google.com/analytics/answer/10071305, accessed October 20, 2026
  2. Google Analytics Help, "Connect Meta to Google Analytics", support.google.com/analytics/answer/16536051, accessed October 20, 2026
  3. Google Analytics Help, "Connect TikTok to Google Analytics", support.google.com/analytics/answer/16536156, accessed October 20, 2026
  4. Google Analytics Help, "What's new archive (2019-2025)" (entries February 3, 2025; July 21, September 17, September 26, October 7 and November 19, 2025), support.google.com/analytics/answer/13420269, accessed October 20, 2026
  5. Google Analytics Help, "What's new in Google Analytics" (entries July 28 and August 10, 2026), support.google.com/analytics/answer/9164320, accessed October 20, 2026
  6. Google Analytics Help, "About Data Import", support.google.com/analytics/answer/10071301, accessed October 20, 2026
  7. Google Analytics Help, "All channels performance report", support.google.com/analytics/answer/12198930, accessed October 20, 2026
  8. Google Analytics Help, "Campaign data import validation report", support.google.com/analytics/answer/17231531, accessed October 20, 2026
  9. Google Analytics Help, "Get started with attribution", support.google.com/analytics/answer/10596866, accessed October 20, 2026
  10. Meta for Developers, "Use URL Tags for Tracking", developers.facebook.com/documentation/ads-commerce/instagram/ads-api/guides/url-tags-for-tracking, accessed October 20, 2026
  11. TikTok Ads Manager Help Center, "About UTM Parameters", last updated February 2026, ads.tiktok.com/help/article/track-offsite-web-events-with-utm-parameters, accessed October 20, 2026
  12. WeltPixel Conversion Tracking, Shopify App Store listing (free plan GA4 up to 100 orders a month; Plus $39/month), apps.shopify.com/weltpixel-conversion-tracking, accessed October 20, 2026

Ready to upgrade your tracking?

Server-side tracking for Magento and Shopify — accurate data, better attribution, full privacy compliance.