{"id":2178,"date":"2026-09-23T17:23:04","date_gmt":"2026-09-23T17:23:04","guid":{"rendered":"https:\/\/blog.domapphub.com\/?p=2178"},"modified":"2026-09-23T17:23:32","modified_gmt":"2026-09-23T17:23:32","slug":"send-whatsapp-message-php-code-example","status":"publish","type":"post","link":"https:\/\/blog.domapphub.com\/en\/blog\/send-whatsapp-message-php-code-example\/","title":{"rendered":"Send WhatsApp Messages via PHP &#8211; A Production-Ready 2026 Guide"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">In the fast-evolving landscape of backend development in 2026, integrating real-time communication into your application is a standard requirement. However, for many developers, the initial journey into server-side integration for WhatsApp is plagued by <\/span><b>&#8220;Broken Code&#8221; syndrome<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Staring at a PHP script that throws vague cURL errors\u2014or worse, returns a success code while the message never arrives\u2014is a rite of passage no one actually wants. Often, the culprit is a minor syntax error in the JSON payload or a missing header in the <\/span><b>curl request<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<h3><b>The Strategic Pivot<\/b><\/h3>\n<p><b>Stop debugging.<\/b><span style=\"font-weight: 400;\"> If you are tired of debugging raw HTTP calls and just want a working, production-ready example to move your project forward, you are in the right place. Copy our ready-made PHP SDK and send your first message in 5 minutes.<\/span><\/p>\n<h2><b>The WhatsApp PHP SDK (v21.0)<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">The following <\/span><b>PHP script to send WhatsApp messages<\/b><span style=\"font-weight: 400;\"> uses the native cURL library to interact with the <\/span><b>Meta Graph API (v21.0)<\/b><span style=\"font-weight: 400;\">. This script is designed for clean, modular <\/span><b>coding<\/b><span style=\"font-weight: 400;\"> and can be easily wrapped into a helper function within your Laravel, Symfony, or custom PHP backend.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">PHP<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&lt;?php<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\/**<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0* Send WhatsApp Message using PHP API (v21.0)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0* Optimized for production backend development in 2026.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0*\/<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">function sendWhatsAppMessage($recipient_phone, $message_text) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ 1. Core Identifiers from Meta Developer Portal<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0$phone_number_id = &#8216;YOUR_PHONE_NUMBER_ID&#8217;;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0$access_token = &#8216;YOUR_PERMANENT_ACCESS_TOKEN&#8217;;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0$api_version = &#8216;v21.0&#8217;;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ 2. The Endpoint URL<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0$url = &#8220;https:\/\/graph.facebook.com\/{$api_version}\/{$phone_number_id}\/messages&#8221;;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ 3. The JSON Payload Structure<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0$data = [<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;messaging_product&#8221; =&gt; &#8220;whatsapp&#8221;,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;recipient_type&#8221;\u00a0 \u00a0 =&gt; &#8220;individual&#8221;,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;to&#8221;\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 =&gt; $recipient_phone, \/\/ Format: 966XXXXXXXXX<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;type&#8221;\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 =&gt; &#8220;text&#8221;,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;text&#8221;\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 =&gt; [<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;preview_url&#8221; =&gt; false,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;body&#8221;\u00a0 \u00a0 \u00a0 \u00a0 =&gt; $message_text<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0];<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ 4. Initialize cURL Request<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0$curl = curl_init();<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0curl_setopt_array($curl, [<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CURLOPT_URL\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 =&gt; $url,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CURLOPT_RETURNTRANSFER =&gt; true,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CURLOPT_ENCODING \u00a0 \u00a0 \u00a0 =&gt; &#8220;&#8221;,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CURLOPT_MAXREDIRS\u00a0 \u00a0 \u00a0 =&gt; 10,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CURLOPT_TIMEOUT\u00a0 \u00a0 \u00a0 \u00a0 =&gt; 30,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CURLOPT_HTTP_VERSION \u00a0 =&gt; CURL_HTTP_VERSION_1_1,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CURLOPT_CUSTOMREQUEST\u00a0 =&gt; &#8220;POST&#8221;,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CURLOPT_POSTFIELDS \u00a0 \u00a0 =&gt; json_encode($data),<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CURLOPT_HTTPHEADER \u00a0 \u00a0 =&gt; [<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;Authorization: Bearer {$access_token}&#8221;,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;Content-Type: application\/json&#8221;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0]);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ 5. Execute and Handle Server-Side Integration<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0$response = curl_exec($curl);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0$err = curl_error($curl);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0curl_close($curl);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0if ($err) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return &#8220;cURL Error #:&#8221; . $err;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0} else {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return json_decode($response, true);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\/\/ Usage Example<\/span><\/p>\n<p><span style=\"font-weight: 400;\">$result = sendWhatsAppMessage(&#8216;966500000000&#8217;, &#8216;Hello from my PHP backend!&#8217;);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">print_r($result);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">?&gt;<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><b>Key Integration Steps<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">To ensure your <\/span><b>script automation<\/b><span style=\"font-weight: 400;\"> works perfectly in a 2026 production environment, verify the following configuration points:<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><b>Component<\/b><\/td>\n<td><b>Source \/ Requirement<\/b><\/td>\n<td><b>Description<\/b><\/td>\n<\/tr>\n<tr>\n<td><b>Phone Number ID<\/b><\/td>\n<td><span style=\"font-weight: 400;\">Meta Developer Dashboard<\/span><\/td>\n<td><span style=\"font-weight: 400;\">A unique ID for your number, distinct from the phone number itself.<\/span><\/td>\n<\/tr>\n<tr>\n<td><b>Permanent Token<\/b><\/td>\n<td><span style=\"font-weight: 400;\">Meta Business Suite<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Generated via the &#8220;System User&#8221; section to ensure 24\/7 service.<\/span><\/td>\n<\/tr>\n<tr>\n<td><b>Recipient Format<\/b><\/td>\n<td><span style=\"font-weight: 400;\">E.164 Standard<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Use format like <\/span><span style=\"font-weight: 400;\">966501234567<\/span><span style=\"font-weight: 400;\">. Do <\/span><b>not<\/b><span style=\"font-weight: 400;\"> include <\/span><span style=\"font-weight: 400;\">+<\/span><span style=\"font-weight: 400;\"> or leading <\/span><span style=\"font-weight: 400;\">00<\/span><span style=\"font-weight: 400;\">.<\/span><\/td>\n<\/tr>\n<tr>\n<td><b>API Version<\/b><\/td>\n<td><span style=\"font-weight: 400;\">Graph API v21.0<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Ensure your endpoint URL matches the current 2026 stable version.<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3><b>Error Handling Logic<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">A successful response will return a <\/span><span style=\"font-weight: 400;\">message_id<\/span><span style=\"font-weight: 400;\">. To monitor your <\/span><b>Success Rate<\/b><span style=\"font-weight: 400;\"> ($S_r$), you can track:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Sr = {M_{delivered}}{M_{total}} \\100<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If the script fails, check the returned JSON for specific Meta error codes, such as <\/span><b>Error 131047<\/b><span style=\"font-weight: 400;\"> (the 24-hour conversation window has expired).<\/span><\/p>\n<h2><b>Streamline Your Backend Development<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">By moving your <\/span><b>send WhatsApp message using PHP API<\/b><span style=\"font-weight: 400;\"> logic to a structured SDK, you eliminate the risk of manual cURL errors and ensure your application scales with Meta&#8217;s 2026 infrastructure. This &#8220;Validation-First&#8221; approach allows you to focus on the business logic rather than the plumbing of the <\/span><b>server-side integration<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the fast-evolving landscape of backend development in 2026, integrating real-time communication into your application is a standard requirement. However, for many developers, the initial journey into server-side integration for WhatsApp is plagued by &#8220;Broken Code&#8221; syndrome. Staring at a PHP script that throws vague cURL errors\u2014or worse, returns a success code while the message [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":2179,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49],"tags":[],"class_list":["post-2178","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-chatplus"],"_links":{"self":[{"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/posts\/2178","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/comments?post=2178"}],"version-history":[{"count":1,"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/posts\/2178\/revisions"}],"predecessor-version":[{"id":2180,"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/posts\/2178\/revisions\/2180"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/media\/2179"}],"wp:attachment":[{"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/media?parent=2178"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/categories?post=2178"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.domapphub.com\/en\/wp-json\/wp\/v2\/tags?post=2178"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}