Aller au contenu
Chargement des API keys…

Authentification

Authentification par clé : trois types de clés, permissions par scopes, listes d'IP autorisées.

Wajub vous authentifie avec une API key envoyée telle quelle dans l'en-tête Authorization. Pas de préfixe Bearer, pas de parcours OAuth, pas d'étape de signature.

En-têtes de requête
Authorization: sk_test.xxxxxxxxxxxxxxxx...
Content-Type: application/json

Anatomie d'une clé

Une clé se compose d'un préfixe, d'un point, puis d'une partie secrète aléatoire. Le préfixe est la partie qui vous renseigne :

Format de clé
sk_test . xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
└──┬──┘   └──────────────────┬──────────────────┘
 │                         └─ random secret, shown once at creation
 └─ type (sk/pk/rk) and environment (_test or nothing)

Le préfixe porte deux informations à la fois : le type de la clé et son environnement.

PréfixeTypeEnvironnement
pk.PubliqueLive
pk_test.PubliqueSandbox
sk.PrivéeLive
sk_test.PrivéeSandbox
rk.RestreinteLive
rk_test.RestreinteSandbox

C'est la clé qui choisit l'environnement, pas l'URL

https://api.wajub.com sert les deux environnements. Une clé _test n'atteint jamais que des données sandbox, si bien que le même code atteint les données de test ou les données live uniquement selon la clé que vous chargez. Changer d'environnement revient à changer de secret, jamais d'endpoint.

Les trois types de clés

Privée (sk.) donne accès à toutes les opérations et ne doit jamais quitter votre serveur. Restreinte (rk.) est une clé privée limitée à une liste explicite de scopes, destinée à un tiers ou à une seule intégration. Publique (pk.) est la clé que vous embarquez dans un navigateur ou une application mobile pour créer un paiement, et elle n'atteint que ce dont un checkout a besoin :

  • créer un paiement (POST /payments), le débiter ou en débiter une échéance et terminer l'étape du payeur (POST /payments/{id}, /splits et /confirm), et le lire par son identifiant (GET /payments/{id}) ;
  • les moyens de payer (GET /payments/options), et créer un client (POST /customers) ;
  • les données de référence : GET /, /channels, /countries, /currencies et /providers.

Toute autre route lui répond 406 Private Key Required : lister les paiements, en annuler, en activer, en modifier ou en clôturer un et lister ses remboursements ; lister, lire ou modifier les clients ; les liens et les factures ; et tout ce qui fait sortir de l'argent, lit votre solde ou gère votre compte, les tax_ids d'un client compris. En sandbox, les liens et les factures, réservés au live, répondent d'abord 403. Quiconque lit votre page peut utiliser ce qu'atteint une clé publique : la détenir n'est donc pas une autorisation, ne vous en servez jamais comme contrôle d'accès.

Ce qu'une clé publique relit est restreint de la même façon. Sur POST /payments, customer, shipping_address et billing_address ne contiennent que ce que la requête a envoyé, jamais le client que votre compte a déjà avec cet e-mail ou ce téléphone. Lu avec GET /payments/{id}, ou renvoyé par POST /payments/{id}, /splits ou /confirm, un paiement n'a ni customer, ni shipping_address, ni billing_address, et son payment_method ne contient que channel, sans account, le numéro ou la carte du payeur. Sur POST /customers, un client que votre compte a déjà avec cet e-mail ou ce téléphone revient avec son id et les champs envoyés par la requête, jamais ce que votre compte détient. Lisez-les depuis votre serveur, avec une clé secrète ou restreinte.

Types de clés acceptés par chaque endpoint :

EndpointsPublique pk.Privée sk.Restreinte rk.
GET /, /channels, /countries, /currenciesOuiOuiOui
GET /providers, GET /payments/optionsOuiOuiAvec le scope
POST /payments, GET /payments/{id}, POST /payments/{id}, /payments/{id}/splits, /payments/{id}/confirmOuiOuiAvec le scope
POST /customersOuiOuiAvec le scope
Le reste de /payments et de /customers, /links, /invoicesNonOuiAvec le scope
/balance, /transfers, /refunds, /beneficiaries, /disputes, /webhooks, /events, /identity, /accountsNonOuiAvec le scope
/taxNonOuiAvec le scope
/shieldNonOuiNon

Une clé publique envoyée sur une ligne marquée Non est refusée avant que l'appel ne fasse quoi que ce soit :

Réponse · 406 Not Acceptable
{
"code": 406,
"status": "Not Acceptable",
"message": "Private Key Required"
}

Scopes des clés restreintes

Une clé restreinte porte une liste de scopes au format resource.action. Les appels GET, HEAD et OPTIONS exigent read, tout le reste exige write. Un GET /transfers exige donc transfer.read, et un POST /transfers exige transfer.write.

Paire de scopesDonne accès à
payment.read / payment.write/payments et /providers
customer.read / customer.write/customers
transfer.read / transfer.write/transfers
refund.read / refund.write/refunds, et les remboursements d'un paiement : GET /payments/{id}/refunds exige refund.read en plus de payment.read, et POST /payments/{id}/close avec outcome: refund exige refund.write en plus de payment.write
recipient.read / recipient.write/beneficiaries
invoice.read / invoice.write/invoices
dispute.read / dispute.write/disputes
webhook.read / webhook.write/webhooks
event.read / event.write/events, y compris le renvoi d'une livraison
link.read / link.write/links
identity.read / identity.write/identity
tax.read / tax.write/tax
balance.read/balance, aucun endpoint d'écriture n'existe
account.read/accounts, en lecture seule

Deux scopes de la liste n'ont pas d'équivalent en écriture. balance.read est en lecture seule parce que le solde n'a aucun endpoint d'écriture. /accounts est un cas différent : créer, modifier ou supprimer un sous-compte est une écriture, et aucun scope account.write n'existe encore, donc ces trois appels exigent une clé privée. Il en va de même pour /shield, qui n'a aucun scope et n'accepte donc que les clés privées.

Quatre chemins ignorent complètement les scopes, car ils renvoient les mêmes données pour toutes les clés de la plateforme : GET /, /channels, /countries et /currencies.

Un scope que vous n'avez pas accordé renvoie un 403 qui nomme exactement ce qui manquait :

Réponse · 403 Forbidden
{
"code": 403,
"status": "Forbidden",
"message": "This API key does not have permission to write transfer"
}

Restreindre davantage une clé

Deux contraintes facultatives s'appliquent à tous les types de clés. Vous les définissez à la création de la clé dans Paramètres → Développeurs → Clés API. Vous pouvez les modifier ensuite depuis la même page, quel que soit le type de clé, et modifier autre chose sur la clé les laisse telles qu'elles étaient. La date d'expiration s'affiche à côté de la clé.

allowed_ipsarrayfacultatif
Adresses IPv4/IPv6 exactes ou plages CIDR. Une requête venant d'ailleurs est refusée avec 403 IP address not allowed for this API key, quel que soit le type de clé.
expires_attimestampfacultatif
Passé cette date, la clé répond 401 Invalid or revoked API credentials. Laissez vide pour une clé sans date de fin.

Authentifier une requête

Le même appel dans les cinq stacks prises en charge. GET /balance exige une clé privée, ce qui en fait un bon moyen de vérifier que votre identifiant côté serveur est bien chargé :

curl https://api.wajub.com/balance \
-H "Authorization: $WAJUB_API_KEY"

Ou envoyez-la directement depuis cette page. Connectez-vous d'abord depuis la barre supérieure, la requête part alors avec votre clé sandbox :

Erreurs d'authentification

Quatre échecs différents, tous identifiables grâce au message :

CodemessageCe qui s'est passé
401Invalid API credentialsAucune clé, ou aucun compte ne lui correspond.
401Invalid or revoked API credentialsLa clé a existé mais elle est inactive, supprimée ou expirée.
403IP address not allowed for this API keyLa clé a une liste d'IP autorisées et vous n'en faites pas partie.
406Private Key RequiredUne clé publique sur un endpoint réservé aux clés privées.
Réponse · 401 Unauthorized
{
"code": 401,
"status": "Unauthorized",
"message": "Invalid API credentials"
}

Les clés privées sont bloquées dans le navigateur

N'utilisez jamais une clé privée (sk. ou sk_test.) depuis un navigateur ou du code front-end. Lorsque Wajub détecte une clé privée utilisée depuis un navigateur, il refuse la requête et vous alerte : le secret a atteint le front-end.

Réponse · 403 Forbidden
{
"code": 403,
"status": "Forbidden",
"message": "Security Alert: You are trying to use a Private Key from a browser/frontend. Private keys must ONLY be used in server-side code. Please use a Public Key for frontend requests.",
"documentation_url": "https://docs.wajub.com/api/authentication#private-keys-are-blocked-in-the-browser"
}

Lorsque ce blocage se déclenche, le propriétaire du compte et les administrateurs reçoivent une alerte de sécurité par e-mail. Si vous le rencontrez sans vous y attendre, cherchez une clé privée embarquée dans du code front-end, puis déplacez l'appel vers votre serveur ou passez à une clé publique.

Une clé restreinte (rk. ou rk_test.) a aussi sa place sur un serveur. Lorsque Wajub en détecte une utilisée depuis un navigateur, le propriétaire du compte et les administrateurs reçoivent la même alerte de sécurité. Pour l'instant, la requête aboutit encore ; Wajub la refusera plus tard avec le même 403. Déplacez donc l'appel vers votre serveur dès maintenant et remplacez la clé.

Bonnes habitudes

  • Gardez vos clés dans des variables d'environnement, jamais dans le dépôt ni dans un bundle front-end.
  • Utilisez une clé distincte par service, pas une seule clé partagée par toute votre infrastructure : une fuite ou une révocation ne touche alors qu'un service. Cela ne donne aucun débit supplémentaire : la limite de requêtes se compte pour tout le compte, quelle que soit la clé de l'appel.
  • Donnez aux tiers une clé restreinte avec les deux ou trois scopes dont ils ont réellement besoin.
  • Définissez expires_at sur tout ce qui est temporaire : un script de migration, l'accès d'une agence, un prototype.
  • Renouvelez vos clés après le départ de toute personne qui y avait accès.

Que pensez-vous de ce contenu ?