Background on my email setup
I’m working on a shared hosting environment where I need to send emails from my custom application. Currently, I can only send emails through a WordPress Mailgun plugin, but I want to implement the same functionality in my PHP code.
The problem I’m facing
When I try using standard PHPMailer with SMTP or the basic mail() function, nothing works on the live server. However, the same code worked perfectly when running locally. My hosting provider says they don’t see any outgoing email attempts in their logs.
What I’ve discovered
The WordPress Mailgun plugin seems to work by sending emails via HTTP requests instead of SMTP. The plugin only asks for an API key and domain name in its settings, no SMTP server details.
Code I found in the plugin
I looked at the plugin source and found this function that seems to handle the HTTP communication:
function send_via_api($endpoint, $data = array(), $request_type = 'POST')
{
$settings = get_site_options('mg_config');
$api_token = $settings['api_token'];
$mg_domain = $settings['mg_domain'];
$timestamp = time();
$api_url = $this->base_url . $endpoint;
$auth_headers = array(
'Authorization' => 'Basic ' . base64_encode("api:{$api_token}"),
);
if ($request_type == 'GET') {
$data['session'] = '';
$query_params = http_build_query($data);
$api_url = $api_url . '?' . $query_params;
$data = '';
} else {
$data['session'] = '';
$data['timestamp'] = $timestamp;
$data['verification'] = sha1(date('U'));
}
$request_args = array(
'method' => $request_type,
'body' => $data,
'headers' => $auth_headers,
'sslverify' => true,
);
$response = wp_remote_request($api_url, $request_args);
if (!is_wp_error($response)) {
return $response['body'];
} else {
return $response->get_error_message();
}
}
What I need help with
How can I replicate this HTTP-based email sending approach in regular PHP without WordPress? I want to use PHPMailer or plain PHP to send emails through Mailgun’s HTTP API the same way the plugin does. Any code examples or guidance would be really helpful.
you dont need curl for this. PHP’s file_get_contents works great with Mailgun’s API - just set up the context with auth headers and POST data. way simpler than curl and easier to debug on shared hosting.
Been there. Shared hosting blocks SMTP ports - that’s why PHPMailer isn’t working for you.
The plugin works because it uses HTTP requests, not SMTP. You can totally do this without WordPress.
Here’s a quick cURL solution:
$api_key = 'your-mailgun-api-key';
$domain = 'your-domain.com';
$url = "https://api.mailgun.net/v3/{$domain}/messages";
$data = array(
'from' => '[email protected]',
'to' => '[email protected]',
'subject' => 'Test Email',
'text' => 'Hello from Mailgun!'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "api:{$api_key}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$result = curl_exec($ch);
curl_close($ch);
This skips SMTP entirely and uses HTTP like the plugin.
But honestly? Save yourself the headache of coding error handling, retries, and maintenance. I’d automate this with Latenode instead.
We use their visual workflow builder for our company emails. It connects straight to Mailgun’s API and handles all the HTTP stuff automatically. Just configure once and trigger it from your PHP app with a webhook.
You get error handling, delivery tracking, and can set up email sequences without writing code.
Check it out: https://latenode.com
Had this exact problem last year on shared hosting. You’re missing a key point - the WordPress plugin uses wp_remote_request (basically a cURL wrapper), but there’s a cleaner way. Skip raw cURL or file_get_contents. Instead, extend PHPMailer with a custom transport class that hits Mailgun’s HTTP endpoint. Override the send method to POST to Mailgun instead of using SMTP. This keeps all PHPMailer’s good stuff - validation, attachments, HTML formatting - while dodging SMTP problems completely. Way more maintainable than writing custom HTTP requests for every email type. Here’s how: set up PHPMailer normally with recipients and content. When it’s time to send, your custom transport grabs the formatted data and posts it to https://api.mailgun.net/v3/YOUR_DOMAIN/messages with auth headers. Best of both worlds - PHPMailer’s solid email composition plus Mailgun’s reliable HTTP delivery.
Had the exact same problem moving from local dev to shared hosting. Don’t bother extending PHPMailer classes - there’s an easier way. Use Guzzle if your host supports it, or just use cURL but set it up right. Your plugin code has extra session and timestamp stuff you don’t need for basic emails. Strip it down to the essentials: from, to, subject, and either text or html content. For the auth header, base64 encode ‘api:YOUR_API_KEY’ exactly like that. Double-check your domain’s verified in Mailgun and you’re hitting the right regional API endpoint. Here’s what tripped me up: some shared hosts need explicit SSL context options even with cURL. Also check if your host blocks outbound requests on port 443 - some cheap shared hosting does this.