Référence technique : authentification, endpoints, formats de réponse et codes d’erreur. Deux scénarios d’intégration au choix.
Toutes les requêtes API Flowmerce sont authentifiées via une clé API serveur. Deux formats équivalents sont acceptés :
# Format Bearer (recommandé)
Authorization: Bearer flk_votre_cle_api
# OU format x-api-key
x-api-key: flk_votre_cle_apiFLOWMERCE_API_KEY). Aucun préfixe NEXT_PUBLIC_,VITE_, etc.Générez et gérez vos clés depuis votre tableau de bord. Maximum 5 clés actives par compte. La valeur brute n'est affichée qu'une seule fois — copiez-la immédiatement.
Deux scénarios selon que vous voulez garder la main sur le formulaire de retour ou que Flowmerce héberge tout pour vous.
Vous rendez le formulaire dans votre boutique à partir de sa définition JSON, puis votre backend transmet les réponses à Flowmerce. Les champs, les motifs et les résolutions proposés découlent de votre politique de retour — vous n'en codez aucun en dur. La clé API reste toujours côté serveur.
[Votre backend]
│ GET /api/v1/return-form
│ Authorization: Bearer flk_xxx
▼
[Flowmerce]
│ 200 { sections, fields, options, meta.policy }
▼
[Navigateur client]
│ 1. Rend le formulaire à partir de cette définition
│ 2. Le client saisit et envoie
│
│ POST /api/orders/return (votre endpoint local)
▼
[Votre backend]
│ 3. Vérifie que la commande appartient bien à l'utilisateur
│ 4. Transmet les réponses telles quelles
│
│ POST /api/v1/returns
│ Authorization: Bearer flk_xxx
│ { orderId, productId, answers }
▼
[Flowmerce]
│ 5. Revalide les réponses contre la définition du formulaire
│ 6. Rate limit, score de fraude, vérification policy
│ 7. Création du claim + appel ML synchrone
│ 8. Auto-approve / auto-reject / pending
│ 9. Email automatique au client
│
│ 201 { claim_id, status, message }
▼
[Votre backend]
10. Sauvegarde claim_id pour traçabilitéLa définition renvoyée par GET /api/v1/return-form porte deux entiers au premier niveau. Le contrôle de compatibilité de votre moteur doit se faire sur le second.
{
"version": 2,
"min_compatible_version": 1,
"sections": [ /* à AFFICHER au client */ ],
"merchant_fields": [ /* à FOURNIR depuis vos données de commande */ ]
}version | number | Version servie aujourd'hui. Incrémentée uniquement sur une RUPTURE : champ supprimé ou renommé, type modifié, contrainte durcie. |
min_compatible_version | number | Version de moteur la plus ancienne capable de rendre ce formulaire. |
// ✅ résiste aux évolutions additives
if (MY_ENGINE_VERSION < form.min_compatible_version) {
throw new Error("moteur trop ancien")
}
// ❌ bloque sur un ajout inoffensif
// (c'est ce contrôle qui casse au passage en v2, pas le formulaire)
if (![1].includes(form.version)) {
throw new Error("version non supportée")
}Contrepartie obligatoire
Votre moteur doit ignorer ce qu'il ne connaît pas: propriétés inconnues sur un champ, types de champ inconnus, sections inconnues. C'est ce qui permet d'enrichir le formulaire sans casser les intégrations en place. Les évolutions additives — nouvelle propriété, champ optionnel, contrainte relâchée, nouvelle option de select — ne changent pas version.
Champs source: "merchant"
Chaque champ porte source valant customer ou merchant. Un champ merchant est un fait de la commande que vous connaissez déjà : ne l'affichez pas au client, renseignez-le depuis vos données de commande. Le laisser saisir ajoute de la friction sur une information que vous possédez, et permet au client d'influencer la prédiction IA.
Vous n'avez rien à filtrer : ces champs vivent dans merchant_fields, hors de sections. Une boucle de rendu sur les sections fait donc la bonne chose par construction.
Sur le portail hébergé, où Flowmerce contrôle le navigateur, ces champs ne sont ni affichés ni acceptés depuis le body : la session fait foi.
https://flowmerce.app/api/v1/returns| Champ | Type | Description |
|---|---|---|
orderIdrequis | string | Identifiant de la commande dans votre système (clé de déduplication) |
productIdrequis | string | Identifiant du produit concerné dans votre système |
answersrequis | object | Réponses du formulaire, indexées par l'id de champ renvoyé par GET /api/v1/return-form |
answers — champs obligatoiresCette liste est celle du formulaire par défaut. Elle varie avec votre politique de retour : fiez-vous toujours à GET /api/v1/return-form, qui fait foi.
| Champ | Type | Description |
|---|---|---|
order_idrequis | string | Numéro de commande (repris de orderId s'il est absent) |
customer_namerequis | string | Nom complet du client |
customer_emailrequis | string | Email du client (format vérifié) |
product_namerequis | string | Nom du produit concerné |
reasonrequis | enum | Motif de retour — une des options du formulaire (ex: Produit défectueux) |
desired_resolutionrequis | enum | EXCHANGE | REFUND | REPAIR (choix du client, filtré par votre policy) |
data_consentrequis | boolean | true — accord explicite du client sur l'usage de ses données (section « consent » du formulaire). Voir ci-dessous. |
GET /api/v1/return-form renvoie désormais une section consent, dont le champ obligatoire data_consent porte le texte à afficher et la case à cocher. Si vous rendez le formulaire à partir de sa définition, comme recommandé, elle apparaît sans un mot de code de votre part.
Le client accepte que les informations de sa demande servent à trancher sa réclamation, à entraîner le modèle qui produit ces analyses, et à être rapprochées de ses retours précédents chez les boutiques partenaires. L'horodatage de son accord est conservé avec la réclamation.
Changement bloquant. Une soumission sans data_consent: true est refusée avec un 400 et le code CONSENT_REQUIRED. Cochez-le après acceptation réelle du client : le pré-cocher, ou l'envoyer en dur, n'est pas un consentement.
answers — champs boutiquesource: "merchant"Ces champs sont des faits de la commande, pas des saisies du client. Ils sont renvoyés dans merchant_fields, hors de sections: votre formulaire ne les affiche donc pas, vous les renseignez depuis vos données de commande. Aucun n'est obligatoire — un champ absent retombe sur une valeur neutre, mais la prédiction y perd. Toute valeur transmise est validée contre sa définition.
customer_id | string | Identifiant du client dans votre système (exporté en Customer_ID). Le client ne le connaît pas. |
customer_wilaya | string | Wilaya (région) de livraison. Feature du modèle. |
payment_method | enum | Cash on Delivery | Card | CCP | Bank Transfer. Feature du modèle. |
shipping_method | string | Mode de livraison. |
shipping_cost | number | Frais de livraison en DA. Feature du modèle. |
answers — champs optionnels (améliorent fortement la prédiction IA)description | string | Description du problème (max 2000 caractères, pas de HTML) |
customer_phone | string | Téléphone client (renforce la détection de fraude) |
customer_age | number | Âge du client |
customer_birth_date | string | Date de naissance ISO-8601 — l'âge en est déduit et prime sur customer_age |
customer_gender | string | Genre du client |
product_category | string | Catégorie produit — requise pour appliquer vos catégories non remboursables |
product_price | number | Prix unitaire en DA |
order_quantity | number | Quantité commandée |
order_total | number | Montant total de la commande en DA |
order_date | string | Date de commande ISO-8601 (calcule les jours écoulés) |
order_address | string | Adresse de livraison |
{
"success": true,
"claim_id": "clxxxxxxxxxxxxxx",
"status": "APPROVED", // ou PENDING / REJECTED
"customer_past_returns": 2,
"message": "Votre demande de retour a été enregistrée et approuvée automatiquement."
}Recommandation IA — contrat 3 classes
La recommandation du moteur IA vaut toujours Exchange, Repair ou Reject — jamais un remboursement. Le remboursement est une décision vendeur : lorsque le client demande un remboursement (desired_resolution: REFUND) et que la demande est éligible selon la politique de retour, le dashboard affiche un indicateur « Remboursement recommandé — décision vendeur ». Aucune action financière n'est déclenchée automatiquement.
# Appelé depuis VOTRE backend (jamais depuis le navigateur du client)
curl -X POST https://flowmerce.app/api/v1/returns \
-H "Authorization: Bearer flk_votre_cle_api" \
-H "Content-Type: application/json" \
-d '{
"orderId": "CMD-123",
"productId": "PROD-5678",
"answers": {
"order_id": "CMD-123",
"customer_name": "Ahmed Benali",
"customer_email": "ahmed@exemple.com",
"customer_wilaya": "Alger",
"product_name": "Nike Air Max",
"payment_method": "Cash on Delivery",
"reason": "Produit défectueux",
"desired_resolution": "REFUND",
"description": "Défaut visible sur la semelle à la réception.",
"data_consent": true
}
}'| Status | Code | Quand | Action recommandée |
|---|---|---|---|
| 400 | VALIDATION | Champ requis manquant, email invalide, HTML détecté, raison/résolution non reconnue | Corriger le payload côté votre backend |
| 400 | CONSENT_REQUIRED | answers.data_consent absent ou différent de true | Afficher la section « consent » du formulaire et transmettre la case cochée par le client |
| 401 | AUTH | Clé API invalide, désactivée, ou vendor non APPROVED | Vérifier la clé dans /dashboard/api-keys |
| 409 | DUPLICATE | Un claim existe déjà pour (vendorId, order_id) | Afficher "un retour existe déjà" au client |
| 422 | DELAY_EXCEEDED | Délai de retour dépassé (selon return policy vendor) | Afficher la raison au client (champ `extra.policy_days`) |
| 422 | NON_REFUNDABLE_CATEGORY | Catégorie produit configurée comme non remboursable | Proposer un échange à la place |
| 429 | RATE_LIMIT | 3 demandes/client/jour ou trop de tentatives pour la même commande | Demander au client de réessayer plus tard |
| 503 | ML_DOWN | Serveur ML temporairement indisponible (claim créé en PENDING) | Le claim sera rejoué automatiquement par le cron |
✓ FLOWMERCE_API_KEY uniquement dans vos variables d'env serveur
✓ Vérifier que la commande appartient à l'utilisateur connecté avant d'appeler Flowmerce
✓ Échapper / valider les inputs (longueur, pas de HTML — Flowmerce le fait aussi)
✓ Sauvegarder claim_id côté votre BDD pour le suivi
✓ Tester avec une clé de dev avant la prod ; révoquer si compromise
Un plugin Shopify officiel Flowmerce est en cours de développement. Il permettra d'intégrer Flowmerce en un clic, sans écrire une seule ligne de code.
Créez votre compte et générez votre première clé API en moins de 2 minutes. Aucune carte bancaire requise.