=== Zinn® Ads ===
Contributors: zinndigital
Plugin URI: https://zinndigital.com/wordpress-plugins/zinn-ads
Author: Neil Lock — CEO, Zinn Digital® Ltd
Author URI: https://zinndigital.com
Tags: conversion tracking, google ads, consent mode, woocommerce, click fraud
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 8.2
Stable tag: 1.0.1
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

No-code conversion tracking, a Consent Mode v2 banner, Cloudflare Zaraz mode and click-fraud checks for sites on Zinn® Ads.

== Description ==

**Zinn® Ads connects a WordPress site to your Zinn® Ads account, so the sales, sign-ups and form leads your ads bring in are counted — without editing a theme or pasting a tag.**

Paste a connection code from your Zinn® dashboard (Ads, WordPress sites) and the plugin does the rest.

= What it does =

* **Tracks conversions with no code.** WooCommerce purchases (once per order), free trials with WooCommerce Subscriptions, checkout started, added to cart and product views; Easy Digital Downloads purchases; and form submissions from Contact Form 7, WPForms, Gravity Forms and Fluent Forms. Switch each one on or off.
* **Asks for consent properly.** A small cookie banner sets Google Consent Mode v2: ad cookies stay off until the visitor allows them. If a consent plugin that uses the WP Consent API is active, Zinn® Ads follows its answer and shows no banner of its own.
* **Keeps the ad click id first-party.** After consent, the click id from the ad (gclid, msclkid and others) is kept in a first-party cookie and saved on the WooCommerce order, so the sale can be credited to the click.
* **Runs tags in Cloudflare Zaraz if you want.** When the site is behind Cloudflare the settings page offers Zaraz mode: no tag in the visitor's browser, and your Zinn® dashboard compares what was sent with what Google counted.
* **Checks paid clicks for fraud.** A visit that arrives from an ad, and the same visitor's next ten minutes, are sent to the Zinn® Ads click shield, which flags bots and repeat clickers. Needs the click shield on your Zinn® Ads plan or the click shield add-on.
* **Disconnects for real.** "Disconnect this site" revokes the site's token at once.

== Installation ==

1. Install and activate the plugin.
2. In your Zinn® dashboard open Ads, WordPress sites, and make a connection code.
3. In WordPress open Settings, Zinn® Ads, paste the code and press Connect.

== External services ==

This plugin connects to the Zinn® Ads API at `https://api.zinndigital.com`, run by Zinn Digital® Ltd. Terms: https://zinndigital.com/legal/terms — Privacy: https://zinndigital.com/legal/privacy

It sends nothing until you press Connect. Then:

* **Connect** (`POST /v1/public/ads-wordpress/claim`, once, when you press it): the connection code, the site address, the plugin and WordPress versions, and whether the site is behind Cloudflare.
* **Heartbeat** (`POST /v1/public/ads-wordpress/heartbeat`, about every six hours and when you save the settings): the plugin and WordPress versions, whether the site is behind Cloudflare, the tag mode, and per day the number of paid orders queued for upload and, in Zaraz mode, the number of purchases on order pages, how many the visitor's browser handed to Zaraz and how many it held back because the visitor declined ad cookies (counts only). The answer is the site's settings.
* **Click shield** (`POST /v1/public/ads-wordpress/clicks`, every five minutes while there is something to send, and only while the click shield is included): for each visit that arrived from an ad and that visitor's next ten minutes on the site — the time, IP address, request method, path, query string, response status and browser user agent. Rows older than those ten minutes are deleted from the site as soon as they are sent; newer rows from the same visitor are kept until their own ten minutes are over; unsent rows are deleted after one day.
* **Orders** (`POST /v1/public/ads-wordpress/outcomes`, once per WooCommerce or Easy Digital Downloads order and free trial, shortly after it is PAID — an order waiting for a bank transfer, a cheque or cash on delivery is sent when it is paid, not when it is placed): the order reference, its total and currency, the time, whether the visitor allowed ad cookies, and — only if they did — the ad click ids kept for the order (gclid, gbraid, wbraid, msclkid). No name, e-mail or address. Your Zinn® Ads account uploads it to the ad networks you connected so the sale is credited to the click.
* **Withdrawals** (`POST /v1/public/ads-wordpress/refunds`, once, when an order already sent is cancelled, fails or is refunded): the order reference and, for a part refund, the amount refunded so far and its currency. The ad networks are told the sale did not happen, or what it was really worth.
* **Disconnect** (`DELETE /v1/public/ads-wordpress/site`, when you press it): a request that revokes the site's token.

In browser mode the visitor's browser loads the Zinn® Ads tag from `https://zinndigital.com/zat/` (the address your Zinn® dashboard gives the plugin). It loads the tags whose ids you set under Install on any site: Google's tag (https://policies.google.com/privacy), Microsoft Advertising UET (https://privacy.microsoft.com/privacystatement) and, only after the visitor allows ad cookies, the Meta pixel (https://www.facebook.com/privacy/policy/). In Zaraz mode conversions are handed to Cloudflare Zaraz on your own Cloudflare zone (Cloudflare's privacy policy: https://www.cloudflare.com/privacypolicy/).

== Frequently Asked Questions ==

= Do I need WooCommerce? =

No. Without a shop the plugin still tracks form submissions, and the click shield still works.

= My pages are cached. Does the click shield still see ad clicks? =

Only requests that reach WordPress are seen. Most page caches pass URLs carrying an ad click id through; if yours does not, exclude the `gclid` and `msclkid` query parameters from the cache.

= What happens to the data if I delete the plugin? =

Deleting the plugin removes its settings, its scheduled tasks and its visit table.

== Changelog ==

= 1.0.1 =
* Only a paid order counts as a sale: an order waiting for a bank transfer, a cheque or cash on delivery is reported when it is paid, and an order cancelled, failed or refunded after it was reported is withdrawn from the ad networks.
* Zaraz mode: the dashboard now checks the browser and the server upload separately and says which one is losing sales.

= 1.0.0 =
* First release: connect with a code, conversion tracking with no code, Consent Mode v2 banner, Cloudflare Zaraz mode, click-shield collector.

== Upgrade Notice ==

= 1.0.1 =
Unpaid orders are no longer counted as sales, and refunded or cancelled orders are withdrawn.

= 1.0.0 =
First release.
