{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Getting Started","description":"Developer documentation for the WHMCS API — the","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"getting-started","__idx":0},"children":["Getting Started"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Mail providers determine how WHMCS transmits email to admins and their customers."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"sample-module","__idx":1},"children":["Sample Module"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SenderModuleInterface"]}," interface for mail providers ships with WHMCS. The class that you create must be in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WHMCS\\Module\\Mail"]}," namespace."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"choosing-a-name","__idx":2},"children":["Choosing A Name"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Mail provider modules are in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["modules/mail"]}," directory. Each module has its own subdirectory, which you should use to store the files relating to the module."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Mail provider modules are PHP files that contain a class that implements the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SenderModuleInterface"]}," interface."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To create a new mail provider module, perform these steps:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Choose a name for your module. Module names must be a single string that consists of only alphanumeric characters (no spaces or other characters). Names must begin with a letter and must be unique."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Create a new directory using your desired module name."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Create a new file within the directory, using your module name as the filename and the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".php"]}," extension."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Add the following code to the file, replacing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["YourModuleName"]}," with the name of your module:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"<?php\n\nnamespace WHMCS\\Module\\Mail;\n\nuse WHMCS\\Authentication\\CurrentUser;\nuse WHMCS\\Exception\\Mail\\SendFailure;\nuse WHMCS\\Exception\\Module\\InvalidConfiguration;\nuse WHMCS\\Mail\\Message;\nuse WHMCS\\Module\\Contracts\\SenderModuleInterface;\nuse WHMCS\\Module\\MailSender\\DescriptionTrait;\n\n/**\n* YourModuleName\n*\n* @copyright Copyright (c) WHMCS Limited 2005-2020\n* @license http://www.example.com/\n*/\nclass YourModuleName implements SenderModuleInterface\n{\n    use DescriptionTrait;\n\n    /**\n     * Provider settings.\n     *\n     * @return array\n     */\n    public function settings()\n    {\n        return [\n            'username' => [\n                'FriendlyName' => 'Username',\n                'Type' => 'text',\n                'Description' => 'The Your Module Name username.',\n            ],\n            'password' => [\n                'FriendlyName' => 'Password',\n                'Type' => 'password',\n                'Description' => 'The Your Module Name password.',\n            ],\n        ];\n    }\n\n    /**\n     * Module name used internally\n     *\n     * @return string\n     */\n    public function getName()\n    {\n        return 'Yourmodulename';\n    }\n\n    /**\n     * Module name shown in the Admin Area\n     *\n     * @return string\n     */\n    public function getDisplayName()\n    {\n        return 'Your Module Name';\n    }\n\n    /**\n     * Test connection.\n     *\n     * @param array $settings\n     *\n     * @return array\n     */\n    public function testConnection(array $settings)\n    {\n        $currentAdmin = (new CurrentUser)->admin();\n\n        try {\n            $ch = curl_init();\n            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);\n            curl_setopt($ch, CURLOPT_USERPWD, $settings['username'] . ':' . $settings['password']);\n            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);\n\n            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');\n            curl_setopt($ch, CURLOPT_URL, 'https://example.com/api/messages');\n            curl_setopt($ch, CURLOPT_POSTFIELDS, [\n                'from' => 'test@example.com',\n                'to' => $currentAdmin->email,\n                'subject' => 'Your Module Name Test',\n                'html' => 'This email was sent to test the new mail configuration. If you received this message, '\n                    . 'it confirms that email is sending correctly. You do not need to take any further action.'\n            ]);\n\n            curl_exec($ch);\n            curl_close($ch);\n        } catch (Exception $e) {\n            throw new Exception(\"Unable to send a Test Message: \" . $e->getMessage());\n        }\n    }\n\n    /**\n     * This is responsible for delivering mail to the mail provider.\n     *\n     * @param array $settings\n     * @param Message $message\n     */\n    public function send(array $settings, Message $message)\n    {\n        try {\n\n            $postFields = [\n                'from' => $message->getFromName(),\n                'fromEmail' => $message->getFromEmail(),\n                'subject' => $message->getSubject(),\n            ];\n\n            // Retrieve recipients.\n            foreach ($message->getRecipients('to') as $to) {\n                $postFields['toEmail'][] = $to[0];\n                $postFields['toName'][] = $to[1];\n            }\n            foreach ($message->getRecipients('cc') as $cc) {\n                $postFields['ccEmail'][] = $cc[0];\n                $postFields['ccName'][] = $cc[1];\n            }\n            foreach ($message->getRecipients('bcc') as $bcc) {\n                $postFields['bccEmail'][] = $bcc[0];\n                $postFields['bccName'][] = $bcc[1];\n            }\n\n            $replyTo = $message->getReplyTo();\n            if ($replyTo) {\n                $postFields['replyToName'] = $replyTo['name'];\n                $postFields['replyToEmail'] = $replyTo['email'];\n            }\n\n            // Build body\n            $body = $message->getBody();\n            $plainText = $message->getPlainText();\n            if ($body) {\n                $postFields['html'] = $body;\n                if (empty($plainText)) {\n                    $plainText = ' ';\n                }\n                $postFields['text'] = $plainText;\n            } else {\n                $postFields['text'] = $plainText;\n            }\n\n            //Prepare attachments\n            $attachments = [];\n            foreach ($message->getAttachments() as $attachment) {\n                if (array_key_exists('data', $attachment)) {\n                    $filename = $attachment['filename'];\n                    $data = $attachment['data'];\n                } else {\n                    $filename = $attachment['filename'];\n                    $data = file_get_contents($attachment['filepath']);\n                }\n                $attachments[] = ['filename' => $filename, 'data' => $data];\n            }\n\n            $postFields['attachments'] = $attachments;\n\n            $ch = curl_init();\n            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);\n            curl_setopt($ch, CURLOPT_USERPWD, $settings['username'] . ':' . $settings['password']);\n            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);\n\n            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');\n            curl_setopt($ch, CURLOPT_URL, 'https://example.com/api/messages');\n            curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);\n\n            curl_exec($ch);\n            curl_close($ch);\n        } catch (Exception $e) {\n            throw new Exception(\"Unable to send a Test Message: \" . $e->getMessage());\n        }\n    }\n}\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For more information on the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SenderModuleInterface"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Message"]}," class, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://classdocs.whmcs.com/8.1/WHMCS/Mail_ns.html"},"children":["our additional documentation"]},"."]}]},"headings":[{"value":"Getting Started","id":"getting-started","depth":1},{"value":"Sample Module","id":"sample-module","depth":2},{"value":"Choosing A Name","id":"choosing-a-name","depth":2}],"frontmatter":{"title":"Getting Started","seo":{"title":"Getting Started"}},"lastModified":"2026-08-03T17:00:42.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/mail-providers/getting-started","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}