In a clinical laboratory setting, timely communication dramatically improves the patient experience. PatoLab integrates with the WhatsApp Business API (Meta Cloud API) to automatically dispatch specimen status updates — such as finalization notifications with a direct report download link — to patients’ WhatsApp numbers. Because WhatsApp is the dominant messaging platform across Latin America, this integration reaches patients on the channel they check most frequently, reducing inbound calls and front-desk workload.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/lerichardv/patolab-platform/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
Before configuring the integration, you will need:- A Meta Business account with the WhatsApp product enabled
- A WhatsApp Business API app created in the Meta Developer Portal
- A phone number ID associated with the WhatsApp Business account (found in the app’s WhatsApp > API Setup panel)
- A permanent System User access token with
whatsapp_business_messagingpermission
Environment Variables
Add the following keys to your.env file. All WhatsApp-related variables are grouped under the # WhatsApp Service section:
.env
The variable
WHATSAPP_BUSINEESS_ACCOUNT_ID contains a typo (BUSINEESS) — this is the exact key name used in the codebase and must be spelled this way in your .env to match the application configuration.config/services.php binding and are referenced in WhatsAppService as:
WhatsAppService
TheApp\Services\WhatsAppService class wraps the Meta Cloud API and exposes three public methods.
sendText()
Sends a free-form text message to a phone number. This method can only be used within the 24-hour customer service window (i.e., after the patient has messaged the business number first).
app/Services/WhatsAppService.php
preg_replace('/\D/', '', $phone). This means you can pass numbers in any common format (+504 9900-0000, (504) 99000000, etc.) and the service will normalize them to a digit-only string before submitting to the API.
sendTemplate()
Sends a pre-approved template message. Templates are required when initiating a conversation with a customer outside the 24-hour service window, or as the very first message sent to a customer who has never messaged the business.
app/Services/WhatsAppService.php
$components array lets you inject dynamic values into template placeholders (body variables, header media, URL button suffixes, etc.).
sendLinkButtonTemplate()
A convenience wrapper around sendTemplate() for the common pattern of sending a template that contains a body text variable and a dynamic URL button — for example, a “View your report” button that links to the patient’s unique report URL.
app/Services/WhatsAppService.php
Sending a Notification from Application Code
PatoLab automatically fires a WhatsApp notification when a specimen report is finalized (insideReportEditorController::transitionState). You can also call the service directly from any controller or action:
ReportEditorController normalizes Honduran local numbers (8-digit) by prepending the country code 504:
In non-production environments (
APP_ENV !== 'production'), all outbound WhatsApp messages in the finalization flow are redirected to the test number defined in ReportEditorController. This prevents accidental messages to real patients during development and staging. Set APP_ENV=production only on your live server.Webhook Setup
Meta requires a publicly accessible HTTPS endpoint to verify your webhook and forward incoming events. PatoLab exposes two routes inroutes/api.php:
| Method | Endpoint | Handler | Purpose |
|---|---|---|---|
GET | /api/whatsapp/webhook | WhatsAppWebhookController@verify | Meta’s one-time verification challenge |
POST | /api/whatsapp/webhook | WhatsAppWebhookController@handleIncoming | Incoming messages and delivery status events |
Verification Endpoint (GET)
When you register your webhook URL in the Meta Developer Portal, Meta sends aGET request with three query parameters: hub.mode, hub.verify_token, and hub.challenge. The controller checks that hub.mode === 'subscribe' and that hub.verify_token matches your WHATSAPP_VERIFY_TOKEN environment variable, then echoes back the hub.challenge value as plain text:
app/Http/Controllers/Api/WhatsAppWebhookController.php
Incoming Message Handler (POST)
Every message sent to your business number, and every delivery status update (sent, delivered, read, failed), is forwarded to thePOST endpoint. The current implementation logs all incoming payloads for observability:
app/Http/Controllers/Api/WhatsAppWebhookController.php
200 EVENT_RECEIVED so Meta does not retry the delivery.
Registering the Webhook in Meta Developer Portal
Open your App in Meta Developer Portal
Navigate to developers.facebook.com, select your app, then go to WhatsApp > Configuration.
Template messages must be created and approved in your Meta Business Manager (WhatsApp Manager > Message Templates) before they can be sent via
sendTemplate() or sendLinkButtonTemplate(). Approval typically takes a few minutes to a few hours.