The complete Meta Pixel & Facebook Conversions API solution for Laravel.
Laravel Meta Conversions is a complete Meta Pixel Laravel Package and Facebook Pixel Laravel Package that integrates Laravel Facebook Pixel browser tracking with Laravel Meta Conversions API (CAPI) server-side tracking. It delivers accurate Server Side Tracking Laravel for reliable Meta Conversion Tracking and Facebook Conversion Tracking across your entire ecommerce funnel.
Goal: High-precision Laravel Ecommerce Tracking with event deduplication via unified
event_idacross browser + server for maximum Meta Advanced Matching quality. Built for Laravel Marketing Analytics and data-driven ad optimization.
- Laravel Meta Pixel + CAPI in a single package — full Laravel CAPI support
- Laravel 10.x / 11.x / 12.x and PHP 8.2+
- Auto-Discovery (install and run)
- Compatible with official Meta requirements
<x-facebook-conversion::pixel />— ready-to-use Blade component for Laravel Facebook Pixel@include('facebook-conversion::pixel')— alternative include approach- Auto
fbq('init')with your Pixel ID - Auto
fbq('track', 'PageView')on every page - Pass
event_idfrom backend to frontend for unified deduplication
- Send events via Laravel Facebook Conversions API →
graph.facebook.com/{version}/{pixel_id}/events - 12 standard events: PageView, ViewContent, Search, AddToWishlist, AddToCart, RemoveFromCart, InitiateCheckout, AddPaymentInfo, Meta Purchase Event, Lead, CompleteRegistration, Contact
- Fluent API:
FacebookConversion::event()->name('...')->value(...)->send()
- Automatic SHA-256 hashing as required by Meta Conversion Tracking
em,ph,fn,ln,ct,st,zp,country,external_id- Auto-extract
client_ip_addressandclient_user_agent - Auto-read
_fbp,_fbccookies - Auto-fill from
auth()->user()when available
- Queue support via
FACEBOOK_QUEUE=truefor non-blocking Server Side Tracking Laravel - Events dispatched through
SendFacebookEventJob - Auto-retry on failure: 3 attempts with 100ms delay
- Configurable HTTP timeout
- Artisan command:
php artisan facebook:test-eventto verify Laravel CAPI integration - Test Event Code support for validation in Meta Events Manager
- Dedicated
facebook_conversionlog channel with 30-day rotation - Access token is masked in all logs
- Master switch:
FACEBOOK_ENABLED=falsedisables all tracking - Graceful failure — never breaks your application
- Configuration validation before sending
- GDPR-compliant: easy opt-out
composer require aghfatehi/laravel-meta-conversionsLaravel auto-discovers the Service Provider. If you disable auto-discovery, register manually:
// config/app.php
'providers' => [
Aghfatehi\LaravelMetaConversions\FacebookConversionServiceProvider::class,
],
'aliases' => [
'FacebookConversion' => Aghfatehi\LaravelMetaConversions\Facades\FacebookConversion::class,
],php artisan vendor:publish --tag=facebook-conversion-configConfig file published to config/facebook-conversion-service.php.
php artisan vendor:publish --tag=facebook-conversion-viewsViews published to resources/views/vendor/facebook-conversion/pixel.blade.php.
- Open Facebook Events Manager → Meta Events Manager
- Select an existing pixel or create a new one for Laravel Meta Pixel
- Copy the Pixel ID from the top
- Set in your
.env:
FACEBOOK_PIXEL_ID=123456789012345- In Meta Events Manager → Settings
- Scroll to Conversion API
- Click Generate Access Token
- Copy the token (starts with
EAA...) - Set in your
.env:
FACEBOOK_PIXEL_API=EAAJjmXXfkp8BAMZCDLWDZB6ZCk4yUmMbITZBk...Tokens may expire. Regenerate periodically. Enable domain verification in Business Manager.
# ─── Core ───
FACEBOOK_PIXEL_ID=123456789012345 # Required
FACEBOOK_PIXEL_API=EAA... # Required
FACEBOOK_ENABLED=true # Master toggle
# ─── Testing ───
FACEBOOK_TEST_EVENT_CODE=TEST12345 # Test code (dev only)
# ─── Performance ───
FACEBOOK_QUEUE=true # Enable queue (recommended in production)
FACEBOOK_QUEUE_CONNECTION=redis # Queue connection (optional)
# ─── Logging ───
FACEBOOK_LOGGING=true # Enable logging
FACEBOOK_LOG_CHANNEL=facebook_conversion
# ─── API ───
FACEBOOK_API_VERSION=v21.0 # Graph API version
FACEBOOK_TIMEOUT=5 # HTTP timeout (seconds)
FACEBOOK_RETRY_ATTEMPTS=3 # Retry count
FACEBOOK_RETRY_DELAY=100 # Retry delay (ms)Insert this in your <head> tag:
{{-- === [Laravel Meta Pixel + CAPI] === --}}
<x-facebook-conversion::pixel />
{{-- =================================== --}}Or using @include:
@include('facebook-conversion::pixel')The pixel automatically fires
fbq('track', 'PageView')on every page load.
Use in HomeController@product when a visitor views a product page:
// When a visitor lands on a product page — triggers Laravel Ecommerce Tracking
FacebookConversion::viewContent(
productId: $product->id,
productName: $product->name,
category: $product->category->name,
value: $product->price,
currency: 'SAR'
);Use in CartController@addToCart after adding a product:
// When a visitor adds a product to cart
FacebookConversion::addToCart(
productId: $product->id,
productName: $product->name,
quantity: $request->quantity,
value: $price,
currency: 'SAR'
);Use in WishlistController@store:
// When a visitor adds a product to wishlist
FacebookConversion::addToWishlist(
productId: $product->id,
productName: $product->name,
value: $product->price,
currency: 'SAR'
);Use in OrderController@store after order creation:
// When a visitor completes a purchase — the Meta Purchase Event
FacebookConversion::purchase(
value: $order->grand_total,
currency: 'SAR',
productIds: $order->orderDetails->pluck('product_id')->toArray()
);// 1. PageView
FacebookConversion::pageView();
// 2. ViewContent
FacebookConversion::viewContent(
productId: 100,
productName: 'iPhone 15',
category: 'Phones',
value: 999,
currency: 'SAR'
);
// 3. Search
FacebookConversion::search('iphone 15');
// 4. AddToWishlist
FacebookConversion::addToWishlist(
productId: 100,
productName: 'iPhone 15',
value: 999,
currency: 'SAR'
);
// 5. AddToCart
FacebookConversion::addToCart(
productId: 100,
productName: 'iPhone 15',
quantity: 1,
value: 999,
currency: 'SAR'
);
// 6. RemoveFromCart
FacebookConversion::removeFromCart(
productId: 100,
productName: 'iPhone 15',
quantity: 1,
value: 999,
currency: 'SAR'
);
// 7. InitiateCheckout
FacebookConversion::initiateCheckout(
value: 999,
currency: 'SAR',
productIds: ['100', '101']
);
// 8. AddPaymentInfo
FacebookConversion::addPaymentInfo(
value: 999,
currency: 'SAR'
);
// 9. Purchase (the Meta Purchase Event — highest priority)
FacebookConversion::purchase(
value: 999,
currency: 'SAR',
productIds: ['100', '101']
);
// 10. Lead
FacebookConversion::lead(
value: 50,
currency: 'USD'
);
// 11. CompleteRegistration
FacebookConversion::completeRegistration(method: 'email');
// 12. Contact
FacebookConversion::contact();For full control over your Laravel CAPI event payload:
FacebookConversion::event()
->name('Purchase')
->value(100)
->currency('SAR')
->contentIds(['product-1', 'product-2'])
->contentType('product')
->eventId('custom-id-123')
->send();Or build the event object and send it later:
$event = FacebookConversion::event()
->name('ViewContent')
->value(599)
->currency('SAR')
->build();
// ... do some processing ...
FacebookConversion::sendEvent($event);Meta requires a unified event_id sent from both Laravel Facebook Pixel (browser) and Laravel CAPI (server) to identify duplicate events. This is the foundation of accurate Facebook Conversion Tracking.
Single event (e.g. Purchase)
│
├── Browser: fbq('track', 'Purchase', {...}, { eventID: 'uuid-123' })
│
└── Server: CAPI → { "event_name": "Purchase", "event_id": "uuid-123", ... }
Meta compares (event_id + event_name) and removes the duplicate
The package generates a UUID v4 automatically for every event. You can customize it:
// Custom event_id
FacebookConversion::event()
->name('Purchase')
->eventId('order_456_' . time())
->send();To pass event_id from server to Pixel (e.g., from an API response):
<x-facebook-conversion::pixel
event-name="Purchase"
event-id="{{ $eventId }}"
:custom-data="['value' => 999, 'currency' => 'SAR']"
/>Whenever you fire an event, the package automatically collects user data to enhance Meta Events Manager with Meta Advanced Matching:
// Auto-collected data for better Server Side Tracking Laravel
// 1. From auth()->user() → email, phone, name, last_name
// 2. From request() → ip, user_agent
// 3. From cookies → _fbp, _fbcAll data is hashed with SHA-256 as required by Meta Conversion Tracking:
// Pass custom UserData for better Facebook Conversion Tracking:
$userData = new UserData()
->email('user@example.com')
->phone('+966551234567')
->firstName('Ahmed')
->lastName('Ghfatehi')
->city('Riyadh')
->state('Riyadh Province')
->zip('12345')
->country('SA')
->fbp(request()->cookie('_fbp'))
->fbc(request()->cookie('_fbc'));
FacebookConversion::purchase(
value: 999,
currency: 'SAR',
userData: $userData
);| Field | Original | Hashed |
|---|---|---|
em |
user@example.com |
SHA-256(lowercase(trim(email))) |
ph |
+966 55 123 4567 |
SHA-256(strip non-numeric) |
fn |
Ahmed |
SHA-256(lowercase(trim)) |
ln |
Ghfatehi |
SHA-256(lowercase(trim)) |
ct |
Riyadh |
SHA-256(lowercase(trim)) |
st |
Riyadh Province |
SHA-256(lowercase(trim)) |
zp |
12345 |
SHA-256(lowercase(trim)) |
country |
SA |
SHA-256(lowercase(trim)) |
external_id |
user_123 |
SHA-256 |
In production, enable the queue to avoid blocking HTTP requests when using Laravel CAPI:
FACEBOOK_QUEUE=true
FACEBOOK_QUEUE_CONNECTION=redisMake sure a queue worker is running:
php artisan queue:workHow it works with FACEBOOK_QUEUE=true:
Controller → FacebookConversion::purchase(...)
↓
SendFacebookEventJob (dispatch)
↓
Queue Worker → MetaConversionApiClient → Facebook CAPI
The controller returns immediately. The event is processed in the background.
Automatically sends PageView via Server Side Tracking Laravel on every GET request:
// App\Http\Kernel.php
protected $middlewareGroups = [
'web' => [
\Aghfatehi\LaravelMetaConversions\Http\Middleware\TrackFacebookPageView::class,
],
];Or on specific routes:
Route::middleware('track-facebook-pageview')->group(function () {
Route::get('/', [HomeController::class, 'index']);
});The middleware sends the PageView after the response is sent (terminate method) to avoid slowing down the page.
In development, use Meta's test code to validate your Laravel CAPI integration:
FACEBOOK_TEST_EVENT_CODE=TEST12345Open Meta Events Manager → Test Events and watch your Laravel Meta Conversions API events arrive in real time.
# Send a test PageView event
php artisan facebook:test-event
# Send a Purchase event with value
php artisan facebook:test-event "Purchase" --value=99.99 --currency=SAR
# Send a ViewContent event
php artisan facebook:test-event "ViewContent" --value=599 --currency=SARAfter sending events:
- Open Meta Events Manager → Meta Events Manager
- Go to Test Events tab (if using Test Event Code)
- Or go to Diagnostics to see real events
- Check Event Match Quality for each event
Logs are written to storage/logs/facebook-conversion.log with daily rotation (30 days).
[2026-06-10 12:00:00] facebook_conversion.INFO: Sending event to Facebook Conversion API {"event_name":"Purchase","event_id":"uuid-123"}
[2026-06-10 12:00:01] facebook_conversion.INFO: Facebook Conversion API event sent successfully {"response":{"events_received":1}}
[2026-06-10 12:00:02] facebook_conversion.ERROR: Facebook Conversion API request failed {"status":401,"response":{"error":{"message":"Invalid token"}}}
Access token is masked:
EAAJjm****
-
FACEBOOK_PIXEL_IDandFACEBOOK_PIXEL_APIare set -
FACEBOOK_ENABLED=true -
FACEBOOK_TEST_EVENT_CODEis empty (remove in production!) -
FACEBOOK_QUEUE=trueand queue is running -
php artisan queue:work(or Supervisor) is active - Domain is verified in Facebook Business Manager
- Laravel Facebook Pixel fires on all pages
- Events appear in Meta Events Manager
- Event Match Quality > 90%
| Problem | Solution |
|---|---|
| Events not appearing | Check FACEBOOK_ENABLED=true and valid Pixel ID |
| 401 Unauthorized | Regenerate Access Token in Meta Events Manager |
| Low match quality | Send more user data (email, phone, fbp, fbc) for Meta Advanced Matching |
| Duplicate events | Ensure event_id is unique per event (package generates UUID automatically) |
| Queue not working | Check php artisan queue:work and queue connection |
| Config error | Check storage/logs/facebook-conversion.log |
| Token expired | Regenerate in Meta Events Manager → Settings → Conversion API |
composer testTests: 50 passed (113 assertions)
Duration: 2.50s
Controller / Middleware / Artisan
│
▼
FacebookConversionService ← Interface (Contract)
│
├── EventBuilder (Fluent API)
│
├── SendFacebookEventJob (Queue)
│
└── MetaConversionApiClient (HTTP)
│
▼
Facebook Graph API (CAPI)
[User] → [Browser Pixel] ─── fbq('track', ..., {eventID}) ──┐
├── → [Meta] ← Dedup
↓ [Server] → [Service] → [CAPI] ─── {event_id: same} ──┘
MIT License. See LICENSE for details.
Built by Ahmed Ghfatehi · fsoftdev.com