Connect a shop.
Four steps link ad spend to PayPal-confirmed sales.
Step 1 code: keep the ad click
Meta and Google add fbclid or gclid to the link. Keep it for the visit and send it with the checkout; it goes into the PayPal order's custom_id. This is what the demo shop does.
const q = new URLSearchParams(location.search);
const id = q.get("fbclid") || q.get("gclid");
if (id) sessionStorage.setItem("ps-click", JSON.stringify({
source: q.get("fbclid") ? "fb" : "g", click_id: id, ad: q.get("ad"), clicked_at: Date.now() }));
// at checkout: POST /api/checkout with the saved click; the order's custom_id becomes
// a=<ad>;s=<fb|g>;c=<click id>;t=<click time>
Steps 2 to 4 in detail
PayPal: a webhook pointing at /api/webhook for PAYMENT.CAPTURE.COMPLETED, PAYMENT.CAPTURE.REFUNDED and INVOICING.INVOICE.PAID. Every delivery is checked with verify-webhook-signature, and Transaction Search cross-checks the ledger against PayPal's own history.
Meta and Google: the shop's Meta dataset id and a Conversions API token as Worker secrets (META_DATASET_ID, META_CAPI_TOKEN). Each confirmed payment from a Meta click is sent the moment PayPal captures it; a payment refunded before it is sent is held back, and a buyer from a Google click goes to Google, not Meta. Google offline conversions come out as rows to upload, with retractions and restatements for refunds.
Ad export: a CSV with three columns (ad, spend, leads). The reconciliation, the budget agent and the MCP tools read it next to what PayPal confirms. Invoices for leads who came through a chat keep the lead's ad in the ledger.
Not built yet
A sign-in for the owner (in this public demo anyone can approve and send, in the sandbox), and a one-click PayPal and Meta connection in place of secrets.