# Dog Academy: Meta Purchase tracking, the minimum

For Dog Academy's developer, 29 September 2026. **Goal:** Meta optimizes the ads to people who pay for Trained for
Life. That needs the sale to reach Meta as a **Purchase** event. Nothing else below is required.

## 1. The sale has to happen on dogacademy.org

The rep closes on the call and sends a **pay link**. The customer pays on your site and lands on a **thank-you page on
dogacademy.org**. A card taken over the phone can't train the ads, and Meta only counts payments made within 7 days of
the ad click.

## 2. The thank-you page fires Purchase (browser)

The pixel `481578137302100` is already on the site. On the thank-you page only, **replace the plain pixel init**
with one that includes the buyer's own email and phone. Then fire Purchase with the real amount and the order ID:

```html
<script>
  // this page's pixel init, with the buyer's details (the pixel hashes them itself)
  fbq('init', '481578137302100', { em: '<buyer email>', ph: '<buyer phone, digits incl. country code>' });
  fbq('track', 'Purchase', { value: <AMOUNT>, currency: 'USD' }, { eventID: 'da:purchase:<ORDER_ID>' });
</script>
```

## 3. Your server sends the same Purchase (strongly recommended, about half a day)

**Why it's needed:** the pay link usually opens in a different browser than the Facebook app where they clicked the
ad, and some browsers block the pixel. The server copy, with the hashed email and phone, is what lets Meta tie the sale
back to the ad.

When the thank-you page is served, POST once to Meta. The `access_token` comes from a system user in Meta Business
Settings; keep it in your secret store.

```
POST https://graph.facebook.com/v25.0/481578137302100/events
Content-Type: application/x-www-form-urlencoded

access_token=<SYSTEM_USER_TOKEN>
data=[{
  "event_name": "Purchase",
  "event_time": <UNIX SECONDS>,
  "event_id": "da:purchase:<ORDER_ID>",
  "action_source": "website",
  "event_source_url": "https://dogacademy.org/<thank-you path>",
  "user_data": {
    "em": ["<sha256 of lowercase, trimmed email>"],
    "ph": ["<sha256 of digits with country code, e.g. 1XXXXXXXXXX>"],
    "client_ip_address": "<buyer IP>",
    "client_user_agent": "<buyer user agent>",
    "fbp": "<_fbp cookie, if present>",
    "fbc": "<_fbc cookie, if present>"
  },
  "custom_data": { "value": <AMOUNT>, "currency": "USD" }
}]
```

Use the **same `event_id`** in the browser and on the server, so Meta counts the sale once. Wrap the call so a Meta
error can never break the thank-you page.

## 4. Check it (10 minutes)

1. Events Manager → dataset `481578137302100` → **Test Events**.
2. Pay a test order through the pay link.
3. Purchase should show from **Browser** and **Server**, marked deduplicated, with the right value.

Then we set the campaign to **Sales → Website → Purchase**.

## Two rules

- Never send service-dog, health or veteran information to Meta.
- Send only real, paid sales.

**Optional, later:** booking and quiz events, and a CRM feed, for reporting on cost per consultation. The full version
is [here](handoff-full.html). It isn't needed to optimize to sales.
