Authentification
Chaque requête API doit être authentifiée par une signature. Cette page explique exactement comment.
Principe
GerminoPay utilise HMAC-SHA256 pour signer chaque requête. Contrairement aux clés API simples (qui peuvent être volées et réutilisées), HMAC signe le contenu de la requête avec votre secret, garantissant :
- Que la requête vient bien de vous
- Que le contenu n'a pas été modifié en transit
- Que les attaques par rejeu sont impossibles (timestamp inclus)
Clés API
| Clé | Format | Utilisation |
|---|---|---|
| Public Key | pk_live_xxxxxxxxxxxx |
Envoyée dans chaque requête via l'en-tête X-Public-Key |
| Secret Key | sk_live_xxxxxxxxxxxx |
Jamais envoyée. Sert à calculer la signature HMAC. |
Ne jamais exposer votre clé secrète
Elle doit vivre uniquement sur votre serveur (variable d'environnement). Ne jamais la mettre dans du JavaScript côté client, du code mobile ou un dépôt Git.
Signature HMAC
Pour signer une requête, concaténez ces éléments dans cet ordre exact :
- La méthode HTTP en majuscules (
GET,POST, etc.) - Le chemin de la requête (sans le domaine) — ex.
/v1/paiement/initier - Le corps brut de la requête (JSON, exactement tel qu'envoyé)
- Le timestamp Unix (secondes)
Puis calculez :
Pseudo-code
signature = HMAC_SHA256(
key = secret_key,
message = METHOD + PATH + BODY + TIMESTAMP
)
Important
Le corps doit être exactement la même chaîne que celle envoyée. Même un espace en plus change la signature.
En-têtes obligatoires
| En-tête | Valeur | Requis |
|---|---|---|
Content-Type |
application/json |
Oui |
X-Public-Key |
Votre clé publique | Oui |
X-Timestamp |
Timestamp Unix (secondes) | Oui |
X-Signature |
Signature HMAC-SHA256 en hexadécimal | Oui |
Exemples par langage
<?php
function germinoSign(string $method, string $path, string $body, string $secret): array
{
$timestamp = time();
$message = $method . $path . $body . $timestamp;
$signature = hash_hmac("sha256", $message, $secret);
return [
"X-Timestamp" => $timestamp,
"X-Signature" => $signature,
];
}
// Utilisation
$body = json_encode(["montant" => 5000, "devise" => "XOF"]);
$headers = germinoSign("POST", "/v1/paiement/initier", $body, getenv("GERMINOPAY_SECRET"));
Anti-replay
Comme le timestamp fait partie de la signature, un attaquant qui intercepte une requête ne peut pas la réutiliser. Toute requête avec un timestamp de plus de 5 minutes est automatiquement rejetée.
Synchronisation d'horloge
L'horloge de votre serveur doit être synchronisée (NTP). Une dérive de plus de 5 minutes invalidera toutes vos requêtes.
Bonnes pratiques
- ✅ Stocker le secret dans des variables d'environnement
- ✅ Renouveler vos clés régulièrement
- ✅ Utiliser exclusivement HTTPS
- ✅ Journaliser chaque appel pour audit
- ❌ Ne jamais committer votre secret sur Git
- ❌ Ne jamais exposer le secret au client