Conversions API for WooCommerce, without plugins that break
WooCommerce users say it plainly: “the pixel is reporting a wrong number of purchases (sometimes double the correct number and sometimes even more)” (a thread on r/woocommerce). Usually two tools send the same purchase. Basketly reads the purchase from the order through the shop’s API and sends it to Meta server-side, so it adds no further Pixel plugin.
The demo has sample data; the login comes to your e-mail.
Where a duplicate purchase comes from
The Pixel in the browser and a send from the server are two paths for the same purchase. Meta counts it once only when both events carry the same id. In a shop with several tools that send a purchase (say two plugins, or a plugin and a checkout builder) it is easy to end up with three paths and nobody knows which does what. A user in one thread wrote about “6 purchases vs 2 real orders”.
What Basketly does on WooCommerce
You give the shop address and a REST API key. The app does the rest, and you see every purchase and where it went.
- Saving the key checks it by reading one order, creates the shop’s webhooks (orders and products, each with its own secret) and queues the reads. A webhook is accepted only with a valid signature.
- Orders changed since the last read come back every 15 minutes, so nothing hangs on a single notification.
- A paid, not cancelled order becomes a purchase: value, currency, products from the lines, e-mail, phone (hashed before sending), and the buyer’s IP and browser from checkout. Cancelled, refunded, failed and trashed orders are not sent.
- Every purchase is saved first and then sent with retries. When Meta has an outage, the purchase waits instead of getting lost.
- WooCommerce products (name, description, price, photo, stock, brand, GTIN from GTIN plugin fields) land on the Products screen with a diagnosis for Google Merchant Center and the Meta catalogue, and from there in a fixed feed.
- The key is stored sealed and is never shown again.
Connect WooCommerce in 4 steps
It takes a few minutes. You need no developer, but you will paste a short snippet from the guide into the shop.
Create a REST API key in WooCommerce
In the WordPress admin create a WooCommerce REST API key and note the Consumer key (ck_…) and the Consumer secret (cs_…).
Add the shop in the app
In Basketly open Integrations → Data sources → Add source, choose WooCommerce and enter a name and the shop address. From the source’s menu open the API connection, enter the WordPress address and the keys, tick the bought statuses and confirm the legal basis for passing the data.
Connect Meta and paste the guide’s snippet
Sign in with your Meta account, choose the dataset (Pixel) and keep the purchase flow from the shop to Meta. The connection guide shows the shop script and the PHP snippet that saves the id in the order.
Check the first purchase
Click “Fetch now”, send a Test event with the code from Events Manager and, after the first orders, open the purchase balance.
Bank transfer, cash on delivery and statuses
An order paid online has a payment date and is bought at once. A bank transfer usually waits in “on hold”, and cash on delivery gets its payment date when the order is completed. When connecting you tick the statuses that count as bought (by their technical names, for example on-hold). Cancelled, refunded, failed and trashed orders never become a purchase. Keep Meta’s limit in mind: a purchase older than 7 days is not accepted.
Tying the purchase to the visit
Reading an order alone does not tell where the buyer came from. The connection guide adds a snippet to the shop that saves the Basketly script’s id in the order (a cookie and a PHP snippet, for classic and block checkout). The purchase sent to Meta then carries what the script saw during the visit, but only after the buyer’s consent, because the script runs only then.
How to check that it works
- Test event: one click sends the newest shop purchase with the test code from Events Manager, and you see it under Test Events.
- Purchase balance: shop orders next to purchases Meta accepted, day by day, with the most common error reasons. A Pixel duplicate shows in Events Manager as more purchases than orders.
- Self-check: compares the dataset’s statistics in Meta with what was actually sent, and says what to fix.
- Orders: each order shows whether its purchase was accepted, failed or is waiting.
What it does not do
- It does not fix or switch off other plugins. If a plugin also sends the purchase server-side, you have two server paths for the same purchase: keep one, or make sure both use the same event id, and check the result in Events Manager.
- It does not replace the Pixel in the browser: events such as product views or add to cart stay on the shop side. It is a second, independent path for purchases.
- Without the Basketly script in the shop and the buyer’s consent Meta gets no ad click id, so matching the purchase to an ad can be weaker.
- It does not make Meta’s numbers equal the shop’s: Meta counts purchases by its attribution windows. Both numbers are shown side by side.
- It does not send a purchase older than 7 days and does not work without the shop’s confirmed legal basis.
It does not replace the Pixel in the browser. It sends purchases from the order, independent of the browser. What to do with the plugin depends on what it sends today: check in Events Manager that purchases are not doubled, and keep one server path for the purchase.
Most often the same purchase arrives by two paths without a shared event id. The purchase balance shows shop orders next to purchases Meta accepted, and the self-check compares the dataset’s statistics with what we sent.
Yes, when the order has a payment date or a status you tick as bought. The purchase goes after such a change, as long as the order is not older than 7 days.
The first read goes 7 days back, because Meta does not accept older purchases. 24 months of history are read once into Orders and Clients but never sent to Meta.
The free plan covers up to 100 orders a month, with no card and no time limit. The limit counts orders, not sends to platforms. Other plans are on the pricing page.
See also
- Meta Conversions APIPaid shop orders sent to Meta from the server, through a queue that does not drop purchases, with a result for every delivery.Read
- Self-checkOne check of your whole setup: the shop, purchases sent to Meta, logins, background jobs and automations, with a link to the fix for every problem.Read
- Basketly vs StapeStape (server-side GTM, CAPI Gateway) next to Basketly (purchases from shop orders): a table, Stape's prices from its own page with the date, when to pick which.Read
- Conversions API (CAPI)Sending events, such as purchases, to Meta from the shop’s server instead of the buyer’s browser.Read
- Pixel and Conversions API Deduplication: event_id, event_name and the 48-Hour WindowHow Meta merges the same event from the Pixel and the Conversions API: event_id, event_name, the 48-hour window, the fbp method, common mistakes and how to check.Read
- Purchase balance: how to check that shop orders really reach Meta and other platformsHow to read the day-by-day purchase balance: shop orders, purchases Basketly accepted and sends to Meta and other platforms. What each gap means and what to check.Read
Get started in under 5 minutes
Connect your shop and Meta and see how many purchases really arrive.
- Free up to 100 orders a month
- No developer needed
- Purchase balance and self-check