Authentification et conventions

Le fonctionnement des clés API, ce que chaque scope autorise et la séparation du mode test. Les règles communes à tous les endpoints : montants, dates, pagination, limites et erreurs.

Vérifié sur le code de l'API le 13 octobre 2026

URL de base

Text
https://api.ezuspay.app/v1

La même URL sert à la production et au test. C'est la clé API envoyée qui détermine l'environnement atteint.

Appelez l'API depuis votre serveur. Elle n'envoie pas d'en-têtes CORS aux domaines tiers. Un navigateur sur votre site ne peut donc pas l'appeler directement. C'est aussi ce qui protège votre clé API.

Clés API

Envoyez la clé API dans l'en-tête x-api-key à chaque requête. L'API ne lit pas Authorization: Bearer.

Shell
curl https://api.ezuspay.app/v1/ping -H "x-api-key: ezpay_live_4f1c..."
PréfixeEnvironnementFormat
ezpay_live_Agence en productionpréfixe + 64 caractères hexadécimaux en minuscules
ezpay_test_Copie de test de l'agencepréfixe + 64 caractères hexadécimaux en minuscules
  • Qui crée les clés. Les admins de l'agence, dans Paramètres → Intégrations → Clés API. Les autres rôles ne peuvent ni voir ni créer de clés.
  • Affichée une seule fois. Ezus Pay ne conserve qu'un hash de la clé. Copiez-la au moment de sa création.
  • Expiration. Facultative. L'application propose aucune expiration, 90, 180 ou 365 jours.
  • Révocation. Depuis le même écran. Une clé révoquée cesse de fonctionner dès la requête suivante.
  • Vérifier une clé avec GET /v1/ping. L'appel renvoie l'agence, l'environnement et les scopes de la clé.
ErreurCas
401 API_KEY_MISSINGPas d'en-tête x-api-key
401 API_KEY_INVALIDFormat incorrect, clé inconnue, ou clé de test utilisée sur une agence en production
401 API_KEY_REVOKEDLa clé a été révoquée, ou l'agence a été fermée
401 API_KEY_EXPIREDLa date d'expiration est passée

Scopes

Une clé API n'accède qu'aux endpoints autorisés par ses scopes. Donnez à chaque intégration le minimum dont elle a besoin.

ScopeAutorise
bookings:writePOST /v1/bookings, POST /v1/bookings/:id/resync
payment-links:readGET /v1/checkout-fields, GET /v1/bookings/:id/payment-links, GET /v1/payment-links/:id
payment-links:writePOST /v1/bookings/:id/payment-links
transactions:readGET /v1/transactions, GET /v1/transactions/:id, GET /v1/bookings/:id/transactions, GET /v1/payment-links/:id/transactions
refunds:writePOST /v1/transactions/:id/refunds

GET /v1/ping ne demande aucun scope. Un appel sans le bon scope renvoie 403 SCOPE_INSUFFICIENT. Le message précise le scope manquant.

Mode test

Le mode test est une copie complète de votre agence. Il a ses propres dossiers, liens, paiements, webhooks et un compte Stripe de test. Vos paramètres, votre charte graphique et vos champs de checkout sont partagés avec lui.

  • Créez une clé de test lorsque l'application est en mode test. Elle commence par ezpay_test_.
  • Chaque appel avec cette clé lit et écrit uniquement des données de test. GET /v1/ping renvoie "mode": "TEST".
  • En mode test, les liens de paiement utilisent l'identifiant de votre agence suivi de --sandbox. Ils affichent un badge Test.
  • Une clé de test ne peut jamais accéder aux données de production.
  • Un admin peut réinitialiser les données de test depuis l'application. Les dossiers, liens et paiements sont effacés. Les clés API, les webhooks et le compte Stripe de test sont conservés.

Valeurs de test Stripe acceptées sur la page de paiement :

UsageValeur
Carte acceptée4242 4242 4242 4242, n'importe quelle date future, n'importe quel CVC
Carte qui demande 3D Secure4000 0027 6000 3184
Prélèvement SEPA (EUR)FR1420041010050500013M02606

Limites de requêtes

Les limites s'appliquent par clé API, sur une minute glissante.

RequêtesLimite
Lectures (GET)600 par minute
Écritures (POST)60 par minute

Chaque réponse contient les en-têtes standard RateLimit et RateLimit-Policy. Au-delà de la limite, vous recevez 429 RATE_LIMIT_EXCEEDED avec un en-tête Retry-After en secondes. Attendez ce délai, puis réessayez.

Réponses et erreurs

Toutes les réponses ont la même enveloppe.

JSON
{ "success": true, "data": { } }
JSON
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "fields": [{ "path": "amountCents", "message": "Minimum amount is 1 unit" }]
  }
}
  • Basez votre logique sur error.code. Les messages sont destinés aux humains et certains sont en français.
  • fields n'apparaît que sur les erreurs de validation, avec une entrée par champ invalide.
  • Les propriétés inconnues dans le corps d'une requête sont ignorées.
StatutSignification
200 / 201Succès. 201 lorsqu'une ressource a été créée
202Accepté, traité plus tard. Utilisé pour les remboursements
401Clé API absente, invalide, révoquée ou expirée
403Scope manquant
404Ressource introuvable dans cette agence
409Conflit avec l'état actuel
422Validation échouée, ou requête refusée par une règle métier
429Limite de requêtes atteinte
502Ezus ou Stripe a répondu par une erreur

Les codes propres à chaque endpoint sont listés dans la référence de l'API.

Conventions

  • Les montants sont des entiers dans la plus petite unité de la devise. Les noms de champs se terminent par Cents. 144000 en EUR vaut 1 440,00 €. Le maximum est 99999999.
  • Les devises utilisent les codes ISO 4217 en majuscules. Un dossier prend par défaut la devise de l'agence. Un lien de paiement utilise toujours la devise de son dossier.
  • Les horodatages sont au format ISO 8601 en UTC, avec les millisecondes : 2026-04-22T14:30:00.000Z.
  • Les dates calendaires dans les requêtes utilisent YYYY-MM-DD.
  • Les identifiants sont des UUID. Les références Ezus ezusProjectId et ezusAlternativeId sont des chaînes libres.
  • La pagination ne concerne que les listes de transactions : page (à partir de 1) et limit (de 1 à 100, 50 par défaut). La réponse contient pagination.total et pagination.totalPages.
  • Idempotence. Il n'existe pas d'en-tête Idempotency-Key. POST /v1/bookings avec un ezusProjectId renvoie le dossier existant au lieu d'un doublon. Relancer la création d'un lien ou d'un remboursement en crée un second. Vérifiez donc le premier résultat avant de réessayer.
  • Les corps de requête sont en JSON, jusqu'à 1 Mo.