Configurez les comptes connectés
Les comptes associés vous intéressent?Contactez votre gestionnaire de compte Affirm pour confirmer la disponibilité et les prochaines étapes.
La liste de vérification de l'intégration peut être utilisée pour suivre votre progression.
Conditions préalables
- Compte commerçant Affirm activé pour Connected Accounts (communiquez avec votre conseiller technique pour l’activer)
- Identifiants API (clé publique et clé privée)
- Point de terminaison HTTPS pour la transmission des webhooks ou la possibilité d'appeler l'API de récupération
- Stockage sécurisé côté serveur pour les jetons d'actualisation
- Coordination de la sécurité du compte effectuée avec votre représentant Affirm
Préparation
Identifiant de liaison de compte
L’intégration de Connected Accounts nécessite un account_linking_id. Un identifiant d’association de compte est une valeur stable qui identifie de façon unique un client dans votre système.
L'identifiant doit :
- Rester identique au fil du temps pour ce client donné.
- Être unique pour chaque client.
Par exemple, cet identifiant pourrait être votre identifiant de base de données client interne ou un identifiant unique universel.
Chemin d'intégration
Choisissez l'intégration du passage à la caisse qui correspond à votre configuration Affirm actuelle. Les deux types d'intégration prennent en charge le même flux d'association de compte et les mêmes options de transmission de jetons.
| Type d'intégration | Description |
|---|---|
| Intégration d'Affirm.js | Vous utilisez déjà les méthodes affirm.checkout() / affirm.checkout.open() de la trousse de développement logiciel. |
| Intégration de l'API directe | Vous appelez directement les API REST d'Affirm (pas d'Affirm.js sur la page). |
Exigences relatives au jeton d'actualisation
Tous les jetons d’actualisation doivent :
- Être stockés côté serveur et ne jamais être exposés côté client
- Être chiffrés au repos à l’aide de votre système de gestion des secrets habituel
- Rester associés à l’identifiant
account_linking_idapplicable - Fait l'objet d'une rotation atomique immédiatement lors de l'échange
- Être supprimé lorsque les clients dissocient ou ferment leur compte auprès de vous
Schéma de stockage recommandé
| Colonne | Type | Description |
|---|---|---|
customer_id | chaîne de caractères (clé primaire) | Votre valeur account_linking_id |
refresh_token | Chaîne de caractères (chiffrée) | Jeton d'actualisation actuel |
expires_at | Horodatage | Expiration du jeton (180 jours après la création) |
created_at | Horodatage | Lorsque le compte a été associé pour la première fois |
updated_at | Horodatage | Last token rotation timestamp |
Rotation
Chaque échange de jeton invalide le jeton d'actualisation précédent.
À chaque échange, vous devez :
- Stocker le nouveau jeton d’actualisation immédiatement après la réception de la réponse
- Remplacez l'ancien jeton de manière atomique dans votre base de données
- Ne jamais réessayer avec un ancien jeton d’actualisation, car il serait automatiquement rejeté
Flux de liaison initial
Le flux d’association initial décrit la manière dont un client adhère pour la première fois à Connected Accounts. Lorsque ce dernier coche « Rester connecté(e) » (ou une option équivalente) pendant le processus de paiement, Affirm lie cet utilisateur à l’identifiant account_linking_id fourni et, une fois l’association terminée, vous transmet un jeton d’actualisation que vous utiliserez pour accélérer son prochain passage à la caisse.
Création d’une procédure de paiement avec un identifiant d’association de compte
Intégration d'Affirm.js
Incluez account_linking_id dans votre demande de paiement Affirm.js.
affirm.checkout({
...
account_linking_id: "customer_12345"
});
affirm.checkout.open();| Champ | Type | Requis | Description |
|---|---|---|---|
account_linking_id | string | Oui, pour les comptes associés seulement | Votre identifiant client stable |
Intégration de l'API directe
Incluez account_linking.id dans votre requête Direct Checkout. Pour la liaison initiale, omettez access_token et code_challenge.
curl -X POST https://api.affirm.com/api/v2/checkout/direct \
-u "{public_key}:{private_key}" \
-H "Content-Type: application/json" \
-d '{
...
"account_linking": {
"id": "customer_12345"
}
}'| Champ | Type | Requis | Description |
|---|---|---|---|
account_linking.id | string | Oui, pour les comptes associés seulement | Votre identifiant client stable |
Livraison du jeton d’actualisation
La transmission par lien de rappel HTTP est recommandée. Utilisez l’API de recherche de jetons (Token Lookup) uniquement si vous n’avez pas d’infrastructure de liens de rappel HTTP en place.
| Méthode | Description |
|---|---|
| Webhook (recommandé) | Recevoir le jeton d’actualisation de manière asynchrone lors du passage à la caisse |
| Token Lookup API | Récupérer manuellement le jeton d’actualisation une fois le passage à la caisse terminé |
Webhook (recommandé)
Affirm envoie le lien de rappel HTTP une fois que le client a accepté et qu’un jeton d’actualisation a été créé.
Exigences
Le point de terminaison de votre lien de rappel HTTP doit :
- Être un point de terminaison HTTPS (HTTP est rejeté)
- Répondez avec un statut 2xx dans les 30 secondes
- Gérer les nouvelles tentatives de livraison d'Affirm pendant un maximum de 72 heures avec une temporisation exponentielle
Enregistrer votre point de terminaison webhook
Pour enregistrer votre point de terminaison webhook, envoyez un courriel à votre TAM avec les détails suivants :
- Votre URL de point de terminaison HTTPS
- Le type d’événement pour l’association de compte : linking_status_changed
- L'environnement que vous souhaitez associer à ce point de terminaison (sandbox, production ou les deux)
Votre conseiller technique configurera le lien de rappel HTTP et vous fournira un secret de signature pour vérifier les charges utiles entrantes. Votre point de terminaison doit être accessible publiquement via HTTPS et renvoyer un code de statut 2xx dans un délai de 30 secondes. Avec votre conseiller technique, configurez l’envoi d’un événement de test afin de valider la transmission avant la mise en production.
Payload
{
"event_type": "linking_status_changed",
"reference_id": "customer_12345",
"linked": true,
"refresh_token": "ref_initial_abc123...",
"expires_at": 1762257600000,
"created_at": 1746360000000
}| Champ | Type | Description |
|---|---|---|
event_type | string | Toujours linking_status_changed pour les nouvelles connexions |
reference_id | string | Votre identifiant client de la requête de paiement (le account_linking_id) |
linked | boolean | true, lorsqu'un nouveau lien a été créé |
refresh_token | string | Jeton de longue durée pour une authentification ultérieure |
expires_at | integer | Expiration du jeton (en millisecondes, temps Unix) |
created_at | integer | Horodatage de création du jeton |
API de recherche de jeton (alternative)
Vous récupérerez manuellement un jeton d’actualisation après avoir reçu le rappel d’annulation ou de confirmation.
Détails
| Propriété | value |
|---|---|
| Point de terminaison | POST /api/pba/v1/oauth/token/lookup |
| Authentification | HTTP Basic Auth
|
| Type de contenu | application/json |
demande
curl -X POST https://api.affirm.com/api/pba/v1/oauth/token/lookup \
-u "{public_key}:{private_key}" \
-H "Content-Type: application/json" \
-d '{
"id": "customer_12345",
"type": "account_linking"
}'| Champ | Type | Requis | Description |
|---|---|---|---|
id | string | Oui | Votre identifiant client stable (le même identifiant account_linking_id transmis lors de la création du paiement). |
type | string | Oui | Doit être account_linking |
Réponse
{
"refresh_token": "ref_initial_abc123...",
"expires_at": "2026-08-04T12:00:00Z",
"scope": "checkout",
"created_at": "2026-02-04T12:00:00Z"
}
| Champ | Type | Description |
|---|---|---|
refresh_token | string | Jeton de longue durée pour une authentification ultérieure |
expires_at | string | Expiration du jeton (ISO 8601) |
scope | string | Portée accordé, toujours « checkout » |
created_at | string | Horodatage de création du jeton |
Flux pour un utilisateur récurrent
Lorsqu’un utilisateur reconnu retourne à la caisse et que vous avez un jeton d’actualisation enregistré pour lui, effectuez les étapes suivantes :
Intégration d'Affirm.js
- Générez le défi de code et le vérificateur de code PKCE à l’aide de la méthode
affirm.checkout.prepareAuth(). - Échangez le jeton d’actualisation stocké du client contre un jeton d’accès de courte durée en envoyant une requête à
/api/pba/v1/oauth/token. - Échangez le jeton d’accès et le défi de code contre un code de session en envoyant une requête à
/api/pba/v1/oauth/session. - Transmettez le code de session à
affirm.checkout.open().
Intégration de l'API directe
- Générez le code challenge et le code verifier PKCE manuellement à l'aide de l'API Web Crypto.
- Échangez le jeton d’actualisation stocké du client contre un jeton d’accès de courte durée en envoyant une requête à
/api/pba/v1/oauth/token. - Transmettez le jeton d’accès et le défi de code lors de la création du paiement et recevez un code de session.
- Ajoutez le code de session et le vérificateur de code à l'URL de redirection de paiement.
Générer PKCE
Intégration d'Affirm.js
Si vous utilisez Affirm.js, appelez affirm.checkout.prepareAuth() pour générer la paire PKCE. Le SDK gère la génération du vérificateur de code, le hachage SHA-256 et l'encodage Base64url en interne.
Intégration de l'API directe
Si vous n'utilisez pas Affirm.js, générez vous-même la paire PKCE à l'aide de l'API Web Crypto.
function generateCodeVerifier() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return base64UrlEncode(array);
}
async function generateCodeChallenge(verifier) {
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const hash = await crypto.subtle.digest('SHA-256', data);
return base64UrlEncode(new Uint8Array(hash));
}
// Base64url encoding: URL-safe variant of Base64 without padding
function base64UrlEncode(buffer) {
return btoa(String.fromCharCode(...buffer))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}Point de terminaison de jeton OAuth
Détails
| Propriété | value |
|---|---|
| Point de terminaison | POST /api/pba/v1/oauth/token |
| Authentification | HTTP Basic Auth
|
| Type de contenu | application/json |
demande
curl -X POST https://api.affirm.com/api/pba/v1/oauth/token \
-u "{public_key}:{private_key}" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "ref_stored_abc123..."
}'| Champ | Type | Requis | Description |
|---|---|---|---|
grant_type | string | Oui | Doit être refresh_token |
refresh_token | string | Oui | Le jeton d’actualisation stocké pour ce client |
scope | string | Non | Par défaut, la valeur est « checkout » |
Réponse
{
"access_token": "at_temp_xyz789...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "ref_new_def456...",
"scope": "checkout"
}| Champ | Type | Description |
|---|---|---|
access_token | string | Jeton de courte durée pour le passage à la caisse. Expire au bout de 15 minutes. |
token_type | string | Toujours Bearer |
expires_in | integer | Durée de vie du jeton en secondes (900 = 15 minutes) |
refresh_token | string | Nouveau jeton d’actualisation. Vous devez le stocker immédiatement. |
scope | string | La portée accordée |
Comme décrit ci-dessus dans Exigences relatives au jeton d'actualisation, chaque échange de jeton invalide le jeton d'actualisation précédent. Vous devez :
- Stocker le nouveau jeton d’actualisation immédiatement après la réception de la réponse
- Remplacez l'ancien jeton dans votre base de données
- Ne réessayez jamais avec un ancien jeton d'actualisation, il sera rejeté
Error Codes
| Code | HTTP Status | Description | Action |
|---|---|---|---|
unauthorized | 401 | Le jeton d’actualisation a été rejeté comme étant non valide (cela signifie qu’il pourrait avoir expiré, a déjà été utilisé ou a été révoqué) ou l’authentification de votre paire de clés API a échoué. | Tout d’abord, vérifiez votre paire de clés API. Si c’est exact, supprimez le jeton d’actualisation stocké et demandez au client de recommencer l’association. |
invalid_argument | 400 | Requête rejetée, par exemple en raison d’un jeton d’actualisation (refresh_token) au mauvais format | Vérifiez que le format de la requête correspond aux spécifications. |
internal_server_error | 500 | Erreur inattendue côté serveur | Défaillance non bloquante; poursuivez avec le passage à la caisse standard, non accéléré. |
Point de terminaison de session OAuth
Détails
| Propriété | value |
|---|---|
| Point de terminaison | POST /api/pba/v1/oauth/session |
| Authentification | HTTP Basic Auth
|
| Type de contenu | application/json |
demande
curl -X POST https://api.affirm.com/api/pba/v1/oauth/session \
-u "{public_key}:{private_key}" \
-H "Content-Type: application/json" \
-d '{
"access_token": "at_temp_xyz789...",
"code_challenge": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
}'| Champ | Type | Requis | Description |
|---|---|---|---|
access_token | string | Oui | Le jeton d’accès de l’API Token Exchange |
code_challenge | string | Oui | Hachage SHA-256 encodé en Base64url de code_verifier (généré côté client) |
Réponse
{
"session_code": "auth_abc123...",
"expires_in": 60
}| Champ | Type | Description |
|---|---|---|
session_code | string | Code à usage unique. Valide pendant 60 secondes. |
expires_in | integer | Durée de vie du code en secondes |
Error Codes
| Code | HTTP Status | Description | Action |
|---|---|---|---|
unauthorized | 401 | access_token est expiré, non valide ou déjà utilisé, ou l'authentification par clé API a échoué | Défaillance non bloquante; poursuivez avec le passage à la caisse standard, non accéléré. |
invalid_argument | 400 | Jeton d’actualisation (access_token) ou défi de code (code_challenge) manquant ou au mauvais format | Vérifiez que le format de la requête correspond aux spécifications. |
internal_server_error | 500 | Erreur inattendue côté serveur | Défaillance non bloquante; poursuivez avec le passage à la caisse standard, non accéléré. |
Passage en caisse accéléré
Intégration d'Affirm.js
Incluez le code de session (session_code) dans votre appel de méthode affirm.checkout.open.
affirm.checkout.open({
...
session_code: "auth_abc123..."
});Intégration de l'API directe
demande
Incluez account_linking.access_token et account_linking.code_challenge dans votre requête Direct Checkout.
curl -X POST https://api.affirm.com/api/v2/checkout/direct \
-u "{public_key}:{private_key}" \
-H "Content-Type: application/json" \
-d '{
...
"account_linking": {
"id": "customer_12345",
"access_token": "at_temp_xyz789...",
"code_challenge": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw"
}
}'| Champ | Type | Requis | Description |
|---|---|---|---|
account_linking.id | string | Oui, pour les comptes associés seulement | Votre identifiant client stable |
account_linking.access_token | string | Oui, pour le paiement accéléré | Jeton d’accès de l’API Token Exchange |
account_linking.code_challenge | string | Oui, lorsque access_token est fourni | Défi de code PKCE |
Réponse avec jeton d'accès valide
Si le jeton d’accès était valide, l’URL de redirection contiendra un code de session (session_code).
{
"checkout_id": "7WYDR0M83CGE47GJ",
"redirect_url": "https://affirm.com/products/checkout?session_code=eyJ...&checkout_ari=7WYDR0M83CGE47GJ"
}Lorsque vous ouvrez l’URL de redirection dans le navigateur du client, ajoutez le code de vérification (code_verifier) :
https://affirm.com/products/checkout?session_code=eyJ...&checkout_ari=7WYDR0M83CGE47GJ&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXkRéponse avec un jeton d'accès manquant ou non valide
Si le jeton d’accès était invalide, l’URL de redirection ne contiendra pas de code de session (session_code), mais fonctionnera normalement.
{
"checkout_id": "7WYDR0M83CGE47GJ",
"redirect_url": "https://affirm.com/products/checkout?checkout_ari=7WYDR0M83CGE47GJ"
}Nouvelle association et dissociation
Lorsqu'un client dissocie son compte
Un client peut dissocier son compte connecté sur le portail utilisateur d'Affirm ou en se déconnectant au moment du paiement. Lorsque cela se produit :
- Le jeton d'actualisation est révoqué du côté d'Affirm
- Le prochain échange de jetons que vous tenterez pour cet utilisateur retournera
unauthorized - Supprimez le jeton stocké de votre base de données
- Le client peut suivre le processus d’authentification standard d’Affirm à la caisse
Vous pouvez également supprimer la connexion d'un client de votre côté en supprimant son jeton d'actualisation de votre base de données. Aucun appel d'API n'est requis pour aviser Affirm, le jeton expirera simplement sans être utilisé.
Lorsqu'un client lie à nouveau son compte
Si un client non associé auparavant active l’option « Rester connecté(e) » lors d’un passage à la caisse ultérieur, Affirm crée un nouveau jeton d’actualisation et le transmet au moyen d’un lien de rappel HTTP ou de l’API de recherche de jetons (Token Lookup). Stockez le nouveau jeton à l’aide du même identifiant d'association de comptes (account_linking_id). Le flux est identique au processus d’association initial.
Mis à jour 11 days ago