> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lekalao.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Étendre Lekalao

> Les points prévus pour brancher vos propres pièces.

Lekalao est une application Laravel : un fournisseur de services suffit pour remplacer une pièce par la vôtre. Gardez vos extensions dans un fournisseur à part (par exemple `app/Providers/InstallationServiceProvider.php`), pour que les mises à jour ne les écrasent pas.

## Les pays des lecteurs

Lekalao n'embarque aucune base de géolocalisation : elles sont lourdes, vieillissent vite et leurs licences varient. Sans elle, la colonne **Pays** des statistiques reste vide ; tout le reste fonctionne.

Pour l'afficher, implémentez `App\Domain\Analytics\Contracts\GeoLocator` :

```php app/Support/MaxMindGeoLocator.php theme={null}
namespace App\Support;

use App\Domain\Analytics\Contracts\GeoLocator;
use GeoIp2\Database\Reader;
use Throwable;

class MaxMindGeoLocator implements GeoLocator
{
    public function __construct(private readonly Reader $reader) {}

    public function country(?string $ip): ?string
    {
        if ($ip === null) {
            return null;
        }

        try {
            return $this->reader->country($ip)->country->isoCode;
        } catch (Throwable) {
            return null;
        }
    }
}
```

```php app/Providers/InstallationServiceProvider.php theme={null}
use App\Domain\Analytics\Contracts\GeoLocator;
use App\Support\MaxMindGeoLocator;
use GeoIp2\Database\Reader;

public function register(): void
{
    $this->app->singleton(GeoLocator::class, fn () => new MaxMindGeoLocator(
        new Reader(storage_path('app/GeoLite2-Country.mmdb')),
    ));
}
```

L'adresse IP n'est jamais enregistrée : elle sert à trouver le pays, puis elle est oubliée. Renvoyez un code à deux lettres (`CM`, `FR`) ou `null`.

## Une passerelle de paiement

`App\Domain\Billing\Gateways\BillingGateway` décrit ce qu'une passerelle doit savoir faire :

| Méthode                                | Rôle                                                                                    |
| -------------------------------------- | --------------------------------------------------------------------------------------- |
| `name()`                               | Le nom enregistré sur chaque paiement.                                                  |
| `checkout(Payment, string $returnUrl)` | Démarre un paiement et renvoie un `Checkout` : référence, adresse où envoyer le client. |
| `status(Payment)`                      | Demande à la passerelle où en est un paiement (bouton **Vérifier à nouveau**).          |
| `verifyWebhook(Request)`               | Vérifie qu'un appel vient bien de la passerelle.                                        |
| `readWebhook(Request)`                 | Extrait la référence et le nouveau statut d'un appel, ou `null`.                        |

Les appels de la passerelle arrivent sur `POST /webhooks/billing`. Branchez la vôtre dans `AppServiceProvider`, là où `LEKALAO_BILLING_GATEWAY` est lu, ou redéfinissez la liaison :

```php theme={null}
$this->app->bind(BillingGateway::class, fn () => new MaPasserelle(config('services.ma_passerelle')));
```

## Un fournisseur d'envoi

Les fournisseurs proposés (SMTP, Amazon SES, Postmark, Mailgun, SendGrid, Brevo, Resend) sont décrits dans `App\Domain\Settings\Enums\MailerTransport` : champs du formulaire, configuration du transport Symfony Mailer, lecture des retours. Pour un nouveau fournisseur, ajoutez un cas à cette énumération, en suivant un fournisseur existant.

## Les langues de l'interface

Ajoutez un fichier `lang/{code}.json` avec toutes les chaînes de `lang/fr.json`, et déclarez la langue dans `config/lekalao.php`, clé `locales`.

<Note>
  Ces points d'extension restent stables d'une version à l'autre. Le reste du
  code peut changer : évitez de modifier les fichiers de Lekalao directement.
</Note>
