# Envoyer des e-mails avec PHP

> Envoyez des e-mails depuis n’importe quelle application PHP avec le SDK emailit/emailit-php, cURL ou PHPMailer via SMTP, et vérifiez les signatures des webhooks Emailit.

Ce guide explique comment envoyer des e-mails depuis une application PHP sans framework : avec le SDK officiel `emailit/emailit-php`, avec cURL ou via SMTP avec PHPMailer. Il présente aussi un endpoint de webhook qui vérifie les signatures. Vous utilisez Laravel ? Suivez plutôt le [guide Laravel](/fr/docs/frameworks/laravel/).

## Prérequis

- PHP 8.1 ou version ultérieure et Composer.
- Un [domaine d’envoi vérifié](/fr/docs/domains/add-a-domain/), par exemple `acme.com`.
- Une [clé API](/fr/docs/developers/api-keys/). Une clé Sending Only limitée à votre domaine suffit.
- Tant que votre espace de travail n’a pas l’[accès production](/fr/docs/workspaces/production-access/), vous ne pouvez envoyer qu’aux adresses e-mail des comptes des membres de l’espace de travail.

## Installer le SDK

```bash
composer require emailit/emailit-php
```

Le SDK utilise Guzzle pour les requêtes HTTP ; Composer l’installe pour vous.

## Configurer votre clé API

Définissez la clé comme variable d’environnement dans votre serveur web, votre pool PHP-FPM ou votre panneau d’hébergement, et lisez-la à l’exécution :

```bash
```

```php
$apiKey = getenv('EMAILIT_API_KEY');
```

Si vous chargez un fichier `.env` avec un paquet comme `vlucas/phpdotenv`, gardez ce fichier hors de la racine web et hors du contrôle de version.

## Envoyer un e-mail

```php title="send.php"
require __DIR__.'/vendor/autoload.php';

$emailit = Emailit::client(getenv('EMAILIT_API_KEY'));

$email = $emailit->emails()->send([
    'from'    => 'Acme <hello@acme.com>',
    'to'      => 'ada@example.com',
    'subject' => 'Your receipt from Acme',
    'html'    => '<p>Thanks for your order.</p>',
    'text'    => 'Thanks for your order.',
]);

echo $email->id; // em_…
```

Le même appel accepte `cc`, `bcc`, `reply_to`, `attachments`, `template` avec `variables`, `scheduled_at` et `tracking`. Pour joindre un fichier, encodez-le en base64 :

```php
$email = $emailit->emails()->send([
    'from'        => 'Acme Billing <billing@acme.com>',
    'to'          => 'ada@example.com',
    'subject'     => 'Invoice INV-1042',
    'html'        => '<p>Your invoice is attached.</p>',
    'attachments' => [[
        'filename'     => 'INV-1042.pdf',
        'content'      => base64_encode(file_get_contents(__DIR__.'/INV-1042.pdf')),
        'content_type' => 'application/pdf',
    ]],
]);
```

Pour tous les champs, consultez [Envoyer un e-mail](/fr/docs/api-reference/emails/send/) ; pour les limites, consultez [Pièces jointes](/fr/docs/email-api/attachments/).

### Gérer les erreurs

```php
use Emailit\Exceptions\ApiErrorException;
use Emailit\Exceptions\AuthenticationException;
use Emailit\Exceptions\RateLimitException;
use Emailit\Exceptions\UnprocessableEntityException;

try {
    $emailit->emails()->send($message);
} catch (AuthenticationException $e) {
    // 401: the API key is missing or invalid
} catch (RateLimitException $e) {
    // 429: wait and retry
} catch (UnprocessableEntityException $e) {
    // 422: for example, the from domain isn't verified
} catch (ApiErrorException $e) {
    error_log('Emailit error '.$e->getHttpStatus().': '.$e->getMessage());
}
```

## Envoyer sans le SDK

Si vous ne pouvez pas utiliser Composer, appelez l’API avec cURL :

```php title="send-curl.php"
$ch = curl_init('https://api.emailit.com/v2/emails');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer '.getenv('EMAILIT_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode([
        'from'    => 'Acme <hello@acme.com>',
        'to'      => 'ada@example.com',
        'subject' => 'Your receipt from Acme',
        'html'    => '<p>Thanks for your order.</p>',
    ]),
]);

$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

if ($status >= 400) {
    throw new RuntimeException("Emailit returned $status: $body");
}

$email = json_decode($body, true); // $email['id'] is the em_ ID
```

## Envoyer plutôt via SMTP

Toute bibliothèque d’e-mail PHP compatible SMTP fonctionne. Avec [PHPMailer](https://github.com/PHPMailer/PHPMailer) (`composer require phpmailer/phpmailer`) :

```php title="send-smtp.php"
use PHPMailer\PHPMailer\PHPMailer;

require __DIR__.'/vendor/autoload.php';

$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host       = 'smtp.emailit.com';
$mail->Port       = 587;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->SMTPAuth   = true;
$mail->Username   = 'emailit';
$mail->Password   = getenv('EMAILIT_API_KEY');

$mail->setFrom('hello@acme.com', 'Acme');
$mail->addAddress('ada@example.com');
$mail->Subject = 'Your receipt from Acme';
$mail->isHTML(true);
$mail->Body    = '<p>Thanks for your order.</p>';
$mail->AltBody = 'Thanks for your order.';

$mail->send();
```

Avec Symfony Mailer, utilisez le DSN `smtp://emailit:API_KEY@smtp.emailit.com:587`. Pour le TLS implicite, utilisez le port 465 (`PHPMailer::ENCRYPTION_SMTPS`) ; si votre hébergeur bloque le port 587, essayez 2525 ou 2587. Consultez [Paramètres SMTP](/fr/docs/smtp/settings/).

## Recevoir des webhooks

[Créez un webhook](/fr/docs/webhooks/set-up/) qui pointe vers votre endpoint et enregistrez son secret de signature dans `EMAILIT_WEBHOOK_SECRET`. Lisez le corps brut depuis `php://input` et vérifiez-le avant de vous y fier :

```php title="webhook.php"
$payload   = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_EMAILIT_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_EMAILIT_TIMESTAMP'] ?? '';
$secret    = getenv('EMAILIT_WEBHOOK_SECRET');

$expected = hash_hmac('sha256', $timestamp.'.'.$payload, $secret);

if (abs(time() - (int) $timestamp) > 300 || ! hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

// The body is a JSON array of up to 100 events.
foreach (json_decode($payload, true) as $event) {
    if ($event['type'] === 'email.bounced') {
        $address = $event['data']['object']['to'];
        // Stop emailing $address.
    }
}

http_response_code(200);
```

Répondez dans les 30 secondes avec un `2xx` ; pour toute autre réponse, Emailit réessaie. Consultez [Signature des requêtes](/fr/docs/webhooks/request-signature/).

## Conseils pour la production

- **Réutilisez un seul client** par requête ou par worker au lieu d’en créer un par e-mail.
- **Envoyez en arrière-plan.** Pour les envois en masse, placez les messages dans une file d’attente et envoyez-les depuis un worker : vos pages restent rapides et vous restez sous vos [limites d’envoi](/fr/docs/limits/) (2 e-mails par seconde par défaut).
- **Sécurisez les relances.** Si vous relancez une requête après un timeout, envoyez un en-tête `Idempotency-Key` avec cURL pour que l’e-mail ne soit pas envoyé deux fois. Consultez [Idempotence](/fr/docs/email-api/idempotency/).
- **Gardez les clés hors de la racine web.** Ne commitez jamais de clés ni de fichiers `.env`, et utilisez une clé distincte par application.

## Étapes suivantes

  - [Laravel](/fr/docs/frameworks/laravel/): Transport mail et façade pour les applications Laravel.
  - [WordPress](/fr/docs/frameworks/wordpress/): Faites passer les e-mails de WordPress par le SMTP d’Emailit.
  - [Envoyer des e-mails avec l’API](/fr/docs/email-api/send-email/): Modèles, programmation et suivi.
  - [Types d’événements webhook](/fr/docs/webhooks/event-types/): Tous les événements et leur payload.

---
Source: https://emailit.com/fr/docs/frameworks/php/
