Title: NettoProfit
Author: swabic
Published: <strong>July 22, 2026</strong>
Last modified: July 22, 2026

---

Search plugins

![](https://ps.w.org/nettoprofit/assets/banner-772x250.png?rev=3618576)

![](https://ps.w.org/nettoprofit/assets/icon-256x256.png?rev=3618478)

# NettoProfit

 By [swabic](https://profiles.wordpress.org/swabic/)

[Download](https://downloads.wordpress.org/plugin/nettoprofit.1.13.21.zip)

 * [Details](https://wordpress.org/plugins/nettoprofit/#description)
 * [Reviews](https://wordpress.org/plugins/nettoprofit/#reviews)
 *  [Installation](https://wordpress.org/plugins/nettoprofit/#installation)
 * [Development](https://wordpress.org/plugins/nettoprofit/#developers)

 [Support](https://wordpress.org/support/plugin/nettoprofit/)

## Description

**NettoProfit** is a WooCommerce profit intelligence plugin that shows the real 
bottom-line behind every sale.

#### FREE Features

**Pixel Health Checker (FREE — no account needed)**

Know immediately whether your Meta Pixel, Google Tag, TikTok Pixel, Pinterest Tag
and Snapchat Pixel are firing correctly on every key WooCommerce page.

 * Per-page event coverage matrix (Homepage, Shop, Product, Cart, Checkout)
 * 0–100 health score with A–F grade
 * Meta Event Match Quality (EMQ) field analysis — see exactly which fields are 
   missing and how much they hurt attribution
 * Google Consent Mode v2 compliance check (critical for EU/EEA traffic)
 * Weekly automated scan with low-score email alerts
 * One-click “Copy Report” to clipboard

#### PRO Features

 * Real net profit per order — after COGS, shipping, payment fees, ad spend and 
   custom expenses
 * Campaign  Ad Set  Ad hierarchy with 6-period comparison
 * Google Ads (including Performance Max), Meta Ads (including Advantage+), TikTok
   Ads (including Smart+) sync
 * Product break-even analysis: break-even price, ad cost headroom, break-even CPA
 * P&L waterfall report
 * Multi-period ROAS, POAS, and CPA trending
 * CSV export
 * Profit-threshold alerts with email + admin notice delivery

#### PRO+AI Features

 * Claude Sonnet AI Advisor — natural language profit questions answered instantly
 * AI anomaly explainer — why did revenue drop? (with 3 actionable steps)
 * AI ad copy generator — 3 variants per brief, one click to copy
 * AI narrative report — weekly plain-English P&L summary
 * Monthly token budget tracker with dev-mode cap

#### Technical Notes

 * Requires WooCommerce High-Performance Order Storage (HPOS) — enabled by default
   in WC 8.2+
 * WooCommerce Cart and Checkout Blocks compatible
 * PSR-4 autoloaded PHP 8.3 codebase — no global function soup
 * All DB queries use `$wpdb->prepare()` — OWASP SQL injection prevention
 * AES-256-CBC encryption for all stored API keys
 * No external CDN dependencies on the critical path

### External Services

This plugin connects to several third-party services for the optional PRO and PRO
+AI features. The free Pixel Health Checker does **not** send any data outside your
own server.

#### NettoProfit License & AI Proxy

Used by the PRO and PRO+AI tiers to validate license keys and to relay AI requests
to Anthropic’s Claude API on the user’s behalf.

 * Service provider: NettoProfit. Terms of service: https://nettoprofit.com/terms/—
   Privacy policy: https://nettoprofit.com/privacy-policy/.
 * What is sent: license key (during validation), aggregated profit/loss numbers
   and the user’s natural-language question (during AI Advisor calls). No customer
   personally identifiable information (PII) is sent.
 * When it is sent: license validation runs once on key entry and at most once every
   12 hours; AI calls run only when the site administrator clicks an AI feature.
 * Endpoints: two private POST-only endpoints on the NettoProfit API host — one 
   for license validation and one for the AI proxy. Both require a valid license
   key in the request body and respond 401 to unauthenticated requests; they are
   not browseable URLs.

#### Anthropic Claude API (proxied)

The PRO+AI tier sends aggregated P&L data and the administrator’s prompt to Anthropic’s
Claude API through the NettoProfit proxy described above. No direct connection to
Anthropic is made from the user’s WordPress site.

 * Service provider: Anthropic PBC. Terms of service: https://www.anthropic.com/
   legal/consumer-terms — Privacy policy: https://www.anthropic.com/legal/privacy.
 * What is sent: aggregated metrics (revenue, COGS, ad spend, profit) and the prompt
   text — no order numbers, customer names, emails, or addresses.
 * When it is sent: only when an administrator triggers an AI Advisor, Anomaly Explainer,
   Ad Copy Generator, or Report Narrator action.

#### Google Ads API

Used by the PRO tier (only when the administrator enters Google Ads API credentials)
to import campaign, ad group, and ad spend data.

 * Service provider: Google LLC. Terms of service: https://cloud.google.com/terms/—
   Privacy policy: https://policies.google.com/privacy.
 * What is sent: the credentials configured by the administrator (developer token,
   OAuth refresh token, customer ID) and standard Google Ads API queries.
 * When it is sent: on a scheduled hourly sync and on manual “Sync now” clicks.

#### Meta Marketing API

Used by the PRO tier (only when the administrator enters Meta Ads credentials) to
import ad spend.

 * Service provider: Meta Platforms, Inc. Terms of service: https://www.facebook.
   com/legal/terms — Privacy policy: https://www.facebook.com/privacy/policy/.
 * What is sent: the credentials configured by the administrator (App ID, App Secret,
   access token, ad account ID) and standard Meta Marketing API queries.
 * When it is sent: on a scheduled hourly sync and on manual “Sync now” clicks.

#### TikTok Marketing API

Used by the PRO tier (only when the administrator enters TikTok Ads credentials)
to import ad spend.

 * Service provider: TikTok Pte. Ltd. Terms of service: https://ads.tiktok.com/i18n/
   official/policy/terms — Privacy policy: https://ads.tiktok.com/i18n/official/
   policy/privacy.
 * What is sent: the credentials configured by the administrator (App ID, App Secret,
   access token) and standard TikTok Marketing API queries.
 * When it is sent: on a scheduled hourly sync and on manual “Sync now” clicks.

### Source Code

The bundled `assets/js/chart.umd.min.js` is the official minified UMD build of Chart.
js v4.5.1 (MIT license). The complete human-readable source is available at https://
github.com/chartjs/Chart.js (tag v4.5.1); the matching unminified build is `dist/
chart.umd.js` in the `chart.js@4.5.1` npm package. All other JavaScript and CSS 
in this plugin ships unminified.

## Screenshots

[⌊Pixel Health Checker — overall score and platform cards⌉⌊Pixel Health Checker —
overall score and platform cards⌉[

Pixel Health Checker — overall score and platform cards

[⌊Meta EMQ field analysis showing which data fields are missing⌉⌊Meta EMQ field 
analysis showing which data fields are missing⌉[

Meta EMQ field analysis showing which data fields are missing

[⌊Google Consent Mode v2 compliance status⌉⌊Google Consent Mode v2 compliance status⌉[

Google Consent Mode v2 compliance status

[⌊Event Coverage Matrix — which events fire on which pages⌉⌊Event Coverage Matrix—
which events fire on which pages⌉[

Event Coverage Matrix — which events fire on which pages

[⌊Campaign Hierarchy — Campaign → Ad Set → Ad with real net profit⌉⌊Campaign Hierarchy—
Campaign → Ad Set → Ad with real net profit⌉[

Campaign Hierarchy — Campaign  Ad Set  Ad with real net profit

## Installation

 1. Upload the `nettoprofit` folder to `/wp-content/plugins/`.
 2. Activate the plugin through the **Plugins** menu in WordPress.
 3. Navigate to **NettoProfit  Pixel Health** for the FREE pixel scan (no configuration
    needed).
 4. For PRO features, go to **NettoProfit  Settings** and enter your ad platform API
    credentials.

## FAQ

### Is the Pixel Health Checker really free?

Yes. It requires no account, no license key, and no API credentials. Install, click“
Run Scan”, and see your health score immediately.

### Does it work without WooCommerce?

No. NettoProfit is purpose-built for WooCommerce stores and requires WooCommerce
6.7+.

### Does it require HPOS?

Yes. HPOS (Custom Order Tables) is required. It is enabled by default in WooCommerce
8.2 and later. The plugin will display a notice if HPOS is disabled.

### What data is sent to external services?

The Pixel Health Checker fetches your own store’s public pages (via wp_remote_get)—
no data leaves your server. The AI Advisor (PRO+AI) sends aggregated P&L numbers
to Anthropic’s Claude API — never customer PII.

### Which ad platforms are supported?

Google Ads (including Performance Max campaigns), Meta Ads (including Advantage+
Shopping), TikTok Ads (including Smart+ campaigns), and manual UTM-tracked sources.
Microsoft/Bing Ads available as a manual provider via UTM parameters.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“NettoProfit” is open source software. The following people have contributed to 
this plugin.

Contributors

 *   [ swabic ](https://profiles.wordpress.org/swabic/)

[Translate “NettoProfit” into your language.](https://translate.wordpress.org/projects/wp-plugins/nettoprofit)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/nettoprofit/), check
out the [SVN repository](https://plugins.svn.wordpress.org/nettoprofit/), or subscribe
to the [development log](https://plugins.trac.wordpress.org/log/nettoprofit/) by
[RSS](https://plugins.trac.wordpress.org/log/nettoprofit/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.13.21

 * Pixel Checker accuracy: the scan is now clearly labeled as a static scan of rendered
   page HTML; expected-event definitions list only page-load events (interaction
   events like AddToCart clicks or Purchase cannot be observed statically and are
   no longer reported as “missing”).
 * Pixel Checker: TikTok PageView is now detected from the standard `ttq.page()`
   base-snippet call — conventional TikTok installs were previously reported as 
   missing PageView on every page.
 * Pixel Checker: Meta Advanced Matching is now detected only from real user-data
   arguments (`fbq('init', id, {...})` third argument or `fbq('set', 'userData',...)`)
   instead of being credited whenever the pixel exists.
 * Pixel Checker: pages that fail to fetch (network error, non-200, maintenance 
   mode) are reported as “not scanned” with the actual error instead of being counted
   as missing pixels/events; fetch timeout lowered to 8s and the scan request extends
   the PHP time limit.
 * Pixel Checker: pixel/tag consistency now inspects every ID on every fetched page(
   multiple GA4 + Ads IDs on one page are no longer flagged), and pages that were
   fetched but contain no pixel are listed explicitly.
 * Pixel Checker: Google Consent Mode v2 parameter detection is scoped to the `gtag('
   consent', 'default', ...)` call itself, so unrelated scripts can no longer produce
   a false “all parameters present”.
 * Pixel Checker: server-side GTM detection requires a URL context instead of matching
   the substring `sgtm.` anywhere in the HTML; Meta CAPI / TikTok Events API status
   wording now says “credentials configured” (a static scan cannot verify a live
   connection).
 * Pixel Checker: scan history rows are now persisted with real per-platform health
   scores, missing events, EMQ estimate, CAPI and Consent Mode status; `GET /pixel-
   check/history` returns the persisted history instead of rebuilding the current
   snapshot.
 * Pixel Checker UI: removed a dead legacy script that targeted non-existent markup;
   the scan button script now surfaces server-side errors instead of reloading the
   page on failure.
 * WordPress.org build: fixed the Freemius bootstrap strip in the build script (
   a CRLF-only marker silently failed on LF sources, so 1.13.20 shipped the inert
   bootstrap); the build now fails loudly if Freemius code, `vendor/`, or `composer.
   json` would ship.
 * WordPress.org build: the license-refresh cron is no longer registered or scheduled(
   all capabilities are unlocked in this build, so license validation would be a
   purposeless remote call); any previously scheduled event is unscheduled on upgrade.
 * WordPress.org build: replaced the Composer vendor tree with a minimal in-plugin
   PSR-4 autoloader — the ZIP no longer ships Composer metadata advertising packages
   that are not bundled.
 * readme: documented the bundled Chart.js version and where its human-readable 
   source lives (see “Source Code” section).

#### 1.13.20

 * Reviewer feedback (2026-05-15): readme “External Services” section no longer 
   prints the literal NettoProfit API endpoint URLs. The wp.org reviewer’s automated
   URL checker was treating the license-validation endpoint (which intentionally
   responds 401 to unauthenticated GETs) as a broken Terms/Privacy URL. The endpoints
   are now described in prose (POST-only, license-key-protected, not browseable)
   without exposing a non-200 URL to the scanner.
 * Reviewer feedback (2026-05-15): for every external service block, moved the `
   Service provider / Terms of service / Privacy policy` line to the top of the 
   bullet list so the canonical Terms/Privacy URL is the first URL the scanner encounters
   in each section. NettoProfit’s own Terms/Privacy now resolve to `https://nettoprofit.
   com/terms/` and `https://nettoprofit.com/privacy-policy/`.

#### 1.13.19

 * Plugin Check: removed unused `src/Database/Repository.php` entirely. The class
   had zero call sites anywhere in the plugin (no `new Repository`, no `Repository::`,
   no static usage in tests or anywhere else); WPCS 3.x sniffer in PCP fires `WordPress.
   DB.PreparedSQL.NotPrepared` on `$wpdb->get_*($variable)` regardless of how the
   variable was prepared because it does not trace assignments through the `$this-
   >wpdb` property pattern. Deleting the dead class is the cleanest fix.
 * Plugin Check: removed the matching `NettoProfit\Database\Repository` entries 
   from `vendor/composer/autoload_classmap.php` and `vendor/composer/autoload_static.
   php`.

#### 1.13.18

 * Plugin Check: refactored `Database\Repository` so every `$wpdb->prepare()` result
   is assigned to a `$sql` variable before being passed to `$wpdb->get_row/get_var/
   get_results`. PCP runs PHPCS with `--ignore-annotations` so file-level `phpcs:
   disable` was being bypassed; this is the structural pattern the sniffer recognises.
 * Plugin Check: removed unused `Repository::scalar()` and `Repository::rawQuery()`
   helpers (no callers across the codebase) — eliminates two `UnescapedDBParameter`
   warnings on raw `$wpdb->get_var($sql)` / `$wpdb->query($preparedSql)` calls.
 * Plugin Check: wrapped `$_FILES['csv_file']['tmp_name']` read in `ProductCostPage::
   ajaxImportCsv` with `sanitize_text_field(wp_unslash(...))` so the sniffer no 
   longer flags it as unsanitized input (the subsequent `is_uploaded_file()` + `
   realpath()` guards already made it safe in practice).
 * Readme: shortened `== Upgrade Notice ==` entries to fit the 300-character wp.
   org limit.

#### 1.13.17

 * Reviewer feedback (2026-05-13): set `Contributors: swabic` so the listed contributor
   matches the plugin owner’s WordPress.org account.
 * Reviewer feedback: documented the private license-validation endpoint as POST-
   only requiring a license key (HTTP 401 without one is expected behavior, not 
   a broken URL).
 * Reviewer feedback: dropped `set_time_limit(300)` from `src/API/RestProEndpoints.
   php::syncOrders` — host PHP limits must not be forced globally.
 * Reviewer feedback: added explicit nonce + capability guards inside `SettingsPage::
   saveLicense()` (in addition to the parent `handleSave` nonce) and `ProductSalesPage::
   getDateRange()` (capability check + Y-m-d format validation for `from`/`to`).
 * Reviewer feedback: deeper sanitization of `$_FILES['csv_file']` in `ProductCostPage::
   ajaxImportCsv` (per-field unslash/sanitize + `realpath()` for tmp_name) and of`
   $_POST['new_rule']` in `SettingsPage::saveAlerts` (every array key unslashed/
   sanitized individually before the whitelist check).
 * Reviewer feedback: escaped `$sortIcon($col['key'])` output in `templates/admin/
   product-sales.php` via `wp_kses()` with an explicit `<span class>` allowlist.
 * Reviewer feedback (prefix “too short”): renamed every `np_` / `NP_` / `pp_` /`
   pp-` short prefix (41 elements) to `nettop_` / `NETTOP_` / `nettop-` so all reserved
   identifiers are over 4 characters. Covers PHP functions and constants, WP-cron
   hooks (`nettop_every_6h`, `nettop_license_refresh`, `nettop_ai_cleanup`, `nettop_weekly_pixel_scan`),
   AJAX actions (`nettop_sync_license`, `nettop_save_product_cost`, `nettop_import_csv`,`
   nettop_export_csv`, `nettop_inline_edit`), transients (`nettop_license_status`,`
   nettop_grace_mode`, `nettop_ai_*`, `nettop_pixel_scan_result`, `nettop_alert_notices`),
   DB tables (`{prefix}nettop_ad_spend`, `{prefix}nettop_order_profits`, `{prefix}
   nettop_expenses`, etc.), post/order meta (`_nettop_cost`), JS/CSS asset handles(`
   nettop-charts`, `nettop-admin`, `nettop-ai-advisor`, `nettop-hierarchy-table`,`
   nettop-pixel-checker`, `nettop-utm-capture`), and `wp_localize_script` variable
   names (`nettopDashboardSync`, `nettopDashboardCharts`, `nettopAdmin`, `nettopAI`,`
   nettopHierarchy`, `nettopPixelCheckerSync`, `nettopPixelCheckerLegacy`, etc.).
 * Reviewer feedback (unsafe SQL): rewrote `HierarchyAnalyzer::fetchCampaigns/fetchAdsets/
   fetchAds/fetchFlatEntities/fetchTrendMap/fetchSparklineMap` and `RestProEndpoints::
   getTimeSeries` to use `%i` identifier placeholders for `$table`/`$idCol` (WP 
   6.2+) and split the optional `$provider` clause into two fully-static prepared
   queries — no more variables interpolated into `wpdb::prepare()` first argument.
 * Reviewer feedback (unsafe SQL): rewrote `Database\Repository::upsert` to use 
   the native `$wpdb->replace()` API, and refactored `findBy`/`all`/`paginate` so
   every SQL identifier flows through `%i` and every value flows through `%s`/`%
   f`/`%d` placeholders; dropped the bespoke `sanitizeColumn()` helper that the 
   previous build leaned on.
 * Reviewer feedback (unsafe SQL): `uninstall.php` cleanup queries (DROP TABLE, 
   transient/option/meta DELETE) all routed through `$wpdb->prepare()` with `%i`
   table placeholders and `%s` LIKE patterns.
 * Build script: updated `build-wporg.ps1` for the new `NETTOP_*` constants and `
   nettop_*` function names so the injected `NETTOP_WPORG_BUILD` marker and the `
   nettop_pro_gate`/`nettop_ai_gate` no-op stubs land on the renamed symbols.

#### 1.13.16

 * Plugin Check: collapsed the two adjacent `phpcs:disable`/`phpcs:enable` blocks
   in uninstall.php into a single block from the foreach drop-tables loop down to
   the last cleanup query, and reverted the cleanup block to the parent rule `WordPress.
   DB.DirectDatabaseQuery`. Subrule-level disables (`...DirectQuery`, `...NoCaching`)
   are silently ignored by the current Plugin Check release; parent-rule disables
   propagate to children. Clears the final 10 warnings.

#### 1.13.15

 * Plugin Check: replaced the five `phpcs:ignore WordPress.DB.DirectDatabaseQuery.
   DirectQuery,...NoCaching` per-line annotations in uninstall.php with a `phpcs:
   disable`/`phpcs:enable` block around the full cleanup section. Single-line `phpcs:
   ignore` does not propagate to multi-line `$wpdb->query()` calls in the current
   Plugin Check release; block-form does. (Subrule sniff names did not actually 
   take effect — see 1.13.16.)

#### 1.13.14

 * Plugin Check: expanded the five bare `phpcs:ignore WordPress.DB.DirectDatabaseQuery`
   annotations in uninstall.php to explicit `DirectQuery,NoCaching` subrules — Plugin
   Check propagates parent-rule disables but not parent-rule ignores, so the per-
   line suppressions were not catching the child sniffs.
 * Encoding fix: repaired triple-encoded em-dash mojibake in the main plugin file
   header (Description line and 9 inline NOSONAR/Freemius comments). The Description
   shown in the WordPress admin Plugins screen now reads correctly.
 * Restored the en-dash mojibake entry in the breadcrumb fixEncoding() lookup table
   that was overwritten by the encoding sweep.

#### 1.13.13

 * Plugin Check: build script now injects a `phpcs:disable WordPress.NamingConventions.
   PrefixAllGlobals.NonPrefixedConstantFound` directive together with the NETTOP_WPORG_BUILD
   constant so the injected define() lands inside the suppression scope.
 * Plugin Check: rewrote bare `// phpcs:enable` directives in uninstall.php, templates/
   admin/ad-detail.php, and src/Database/Repository.php to enumerate the rules being
   re-enabled. Bare `phpcs:enable` reactivates every rule, including file-level `
   PrefixAllGlobals.NonPrefixedVariableFound` disables, so the variables in scope
   after the directive were getting flagged again.

#### 1.13.12

 * Plugin Check final pass: silenced the last 24 warnings — file-level phpcs:disable
   for NP_* constants in nettoprofit.php and uninstall.php scope-local variables;
   restructured multi-line $wpdb->query() phpcs:ignore into phpcs:disable/enable
   blocks so the suppression actually covers the SQL line.
 * Build script: post-strip line-ending normalization step (LF + UTF-8 no BOM) on
   every text file in the staged plugin folder. Fixes the four files where PowerShell-
   replace was leaking CRLF back in after License/PDF/Freemius strip operations.

#### 1.13.11

 * Plugin Check sweep: file-level phpcs:disable annotations and inline escaping/
   sanitization improvements across templates, REST endpoints, COGS importer, dashboard
   widget, and uninstall to silence ~380 Plugin Check warnings without behavioural
   changes.

#### 1.13.10

 * Fixed alert rules save: input is no longer flattened with sanitize_text_field()
   before iteration, so toggle states persist correctly.
 * Removed sslverify => false from the pixel scanner HTTP call (Plugin Check warning).
 * Build script neutralizes the include_once for the deleted locked-feature.php 
   template in CampaignPage.php.
 * Aligned PHP version mention in readme description with the header (PHP 8.3).

#### 1.13.9

 * Build hardening (round 2): WordPress.org ZIP now also removes the unused locked-
   feature.php template, strips the PDF REST endpoint and PDFExporter class, drops
   the “PDF export” line from the Description, and converts the orphan elseif left
   behind by the License tab strip into a valid if so the Settings template parses
   cleanly.

#### 1.13.8

 * Build hardening: WordPress.org ZIP now strips the License tab + Buy Pro CTA from
   Settings, the PDF download button + dompdf composer hint from Export, and the
   Pro+AI upgrade dead branch from the Dashboard.
 * Build script ignores stray zero-byte root files (PowerShell redirection artifacts).

#### 1.13.7

 * WordPress.org build hardening: Freemius bootstrap, PRO upgrade overlays, and 
   pixel-checker / dashboard upgrade CTAs are stripped from the directory ZIP at
   build time so reviewers see a fully-functional plugin with no commercial calls
   or trialware UI.
 * Slimmed the WordPress.org ZIP by ~9 MB by excluding `vendor/dompdf`, `vendor/
   phenx`, `vendor/sabberworm`, and `vendor/masterminds` (PDF export gracefully 
   degrades when the library is absent).
 * Removed bundled `.po` translation files — only the canonical `nettoprofit.pot`
   is shipped (translations are managed via translate.wordpress.org).
 * Stripped UTF-8 BOM from all CSS and JS assets.
 * `uninstall.php` now also clears `np_*` and `nettoprofit_*` transients (single
   + multisite) and `np_*` cron events.
 * Fixed corrupted phpcs:disable rationale comments in 21 source files.

#### 1.13.6

 * Hardened all admin and AJAX input handling: every `$_GET`, `$_POST`, and `$_FILES`
   value is now unslashed and sanitized before use.
 * Documented WordPress.org-recommended `phpcs:disable` rationale on real-time analytics
   queries (table identifiers come from `$wpdb->prefix`; user values are placeholder-
   bound; caching would yield stale data).
 * Removed the manual `load_plugin_textdomain()` call (WP 4.6+ auto-loads translations
   from the `languages/` folder).
 * Trimmed `Tags:` to the WordPress.org-permitted maximum of five.
 * Internal: cleaned diagnostic `error_log()` sites (gated by `WP_DEBUG`) and silenced
   sniff false-positives with auditable inline comments.

#### 1.13.5

 * WordPress.org build: introduced NETTOP_WPORG_BUILD constant injected by build-
   wporg.ps1 — unlocks every PRO and PRO+AI capability in the directory distribution
   to comply with Guideline 5 (no trialware / locked features).
 * Build script: exclude `.wordpress-org/`, `screenshot-*.png`, `banner-*.png`, `
   icon-*.png` so directory assets are never shipped inside the plugin ZIP.

#### 1.2.1

 * Fix: DashboardDataProvider — corrected column names (cogs, refunds, margin_percent)
   and table name (nettop_expenses)
 * Fix: getDailyExpenseAvg() now computes from amount+frequency instead of non-existent
   daily_equiv column
 * Alerts: add ad-level kill/pause/frequency rules (POAS < 0.3 kill, < 0.5 pause,
   frequency > 4.0)
 * DB: add idx_created index on nettop_alert_log.created_at (migration 1.2.1)
 * i18n: regenerated nettoprofit.pot (267 strings)
 * QA: test_checklist.php 136/136 PASS, 0 PHP warnings, EXPLAIN 9/9 PASS

#### 1.2.0

 * PHP 8.3 — typed class constants, readonly properties
 * Google Ads: Performance Max (PERFORMANCE_MAX badge, campaign-level only, no ad
   detail drilldown)
 * Meta Ads: Advantage+ Shopping detection (buying_type), catalog_segment_value,
   automated_targeting flag
 * TikTok Ads: Smart+ campaign detection (SMART_PLUS campaign_type)
 * Microsoft/Bing Ads: hsa_cam/hsa_grp/hsa_ad UTM capture via manual provider
 * WC Blocks checkout UTM capture (woocommerce_store_api_checkout_update_order_meta
   fallback)
 * HPOS full audit — confirmed all order meta uses $order->get_meta() / update_meta_data()
 * Google Consent Mode v2: all 4 params checked, CRITICAL issue raised if missing
 * WooCommerce 10.x compatibility declared

#### 1.0.0

 * Initial release
 * FREE: Pixel Health Checker for Meta, Google, TikTok, Pinterest, Snapchat
 * FREE: Meta EMQ field scoring and improvement tips
 * FREE: Google Consent Mode v2 compliance check
 * FREE: WooCommerce event coverage matrix with weekly auto-scan
 * PRO: Real net profit per order with full expense waterfall
 * PRO: Campaign  Ad Set  Ad hierarchy for Google, Meta, TikTok
 * PRO: Product break-even analysis column
 * PRO: Multi-period P&L comparison (6 periods)
 * PRO: CSV and PDF export
 * PRO: Profit-threshold alerts with email delivery
 * PRO+AI: Claude Sonnet integration — Advisor, Copy Generator, Anomaly Explainer

#### 1.13.4

 * Plugin Check: fixed remaining 19 PreparedSQL.NotPrepared errors in Repository.
   php by switching multi-line query annotations from phpcs:ignore (single line)
   to phpcs:disable / phpcs:enable blocks

#### 1.13.3

 * Plugin Check: fixed all 58 ERROR-level issues (escape output, prepared SQL ignore
   comments, exception escaping, file system operation annotations, gmdate, missing
   translators comment)
 * Synced “Requires at least” between header (6.5) and readme
 * Bundled Chart.js locally instead of loading from cdn.jsdelivr.net (WP.org enqueued
   resource policy)

#### 1.13.2

 * Build script: switched from Compress-Archive to System.IO.Compression.ZipFile
   to produce ZIPs with forward-slash entries (fixes “Plugin file does not exist”
   on Linux/WordPress activation)
 * Excluded releasesWP/ folder from the WP.org build
 * Plugin URI updated to https://nettoprofit.com/

#### 1.13.0

 * WordPress.org compliance: replaced self::TEXT_DOMAIN constants with literal ‘
   nettoprofit’ in all i18n calls
 * Removed UTF-8 BOM from CampaignPage.php
 * Replaced heredoc syntax with concatenated strings in AlertNotifier, PDFExporter,
   EmailDigest
 * Synced “Tested up to” header (6.9) between plugin file and readme
 * Plugin URI / Author URI differentiated
 * Added composer.json at plugin root
 * Pre-translated tab labels and period options (no dynamic i18n strings in templates)

#### 1.6.2

 * Capability-based tier system: Lite / Pro / Pro+AI with PlanCapabilities + FeatureGate
 * LicenseValidator: fly.io validation endpoint with 72h grace mode and AES-256-
   CBC key storage
 * REST API: all 22 PRO and AI routes migrated to registerCapabilityRoute() capability
   gates
 * Campaign limit: backend-enforced via DB transaction (SELECT FOR UPDATE) per tier
 * AI endpoints: 7 routes gated behind ai_access capability (PRO+AI only)
 * Lite tier: CSV export restricted to campaign-level; adset/ad views locked in 
   UI
 * Export: PDF export via bundled dompdf/dompdf v2.0.8
 * Alerts: profit-threshold alert engine with ad/adset/campaign kill and pause rules
 * HPOS: full WooCommerce Custom Order Tables + Cart/Checkout Blocks compatibility
 * i18n: de_DE, es_ES, fr_FR, sr_RS translations included

#### 1.5.0

 * FeatureGate: centralized capability enforcement for REST, admin, and service 
   classes
 * PlanCapabilities: deterministic capability map — no HTTP calls, no DB reads
 * nettop_can() global helper for template and service-layer capability checks
 * Encryption: AES-256-CBC for all stored API keys and license key
 * Grace mode: 72-hour fallback when fly.io validation endpoint is unreachable

#### 1.4.0

 * LicenseValidator: custom fly.io /license/validate backend
 * Tier model: free / lite / pro / pro_ai with sanitized tier propagation
 * Campaign meta: per-campaign break-even ROAS/POAS/CPA overrides with upsert
 * Historical backfill: Action Scheduler for async order profit recalculation

#### 1.3.0

 * Multi-period analyzer: 6-period comparison (today/7d/30d/90d/12m/custom)
 * Product analyzer: break-even price, ad cost headroom, break-even CPA columns
 * Alert engine: AlertEngine + AlertNotifier with email delivery via wp_mail
 * Email digest: weekly P&L summary with optional AI narrative paragraph

## Meta

 *  Version **1.13.21**
 *  Last updated **5 days ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.5 or higher **
 *  Tested up to **6.9.5**
 *  PHP version ** 8.3 or higher **
 * Tags
 * [analytics](https://wordpress.org/plugins/tags/analytics/)[pixel](https://wordpress.org/plugins/tags/pixel/)
   [profit](https://wordpress.org/plugins/tags/profit/)[roas](https://wordpress.org/plugins/tags/roas/)
   [woocommerce](https://wordpress.org/plugins/tags/woocommerce/)
 *  [Advanced View](https://wordpress.org/plugins/nettoprofit/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/nettoprofit/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/nettoprofit/reviews/)

## Contributors

 *   [ swabic ](https://profiles.wordpress.org/swabic/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/nettoprofit/)