API professionnelle, versionnée, compressée et sécurisée
API versionnée avec endpoints `/api/v1/`, compression et CORS avancé.
Compression 60-80%, cache des preflights, en-têtes optimisés.
JWT, limitation de débit et bonnes pratiques de sécurité.
https://api.commercy.net/api/v1
// Connexion pour obtenir un token JWT
const response = await fetch('https://api.commercy.net/api/v1/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
identifier: 'user@example.com',
password: 'password'
})
});
const { token } = await response.json();
// Utiliser le token dans les requêtes suivantes
const apiResponse = await fetch('https://api.commercy.net/api/v1/orders', {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
Vérifiez si l'API est active et accessible
/api/v1/auth/login
Connexion utilisateur pour obtenir un token JWT
{
"identifier": "user@example.com",
"password": "password"
}
/api/v1/orders
Créer une commande (JWT requis). Le téléphone est obligatoire, le reste est optionnel.
Authorization: Bearer <token> (rôles : admin, reseller, agent)
{
"customerPhone": "+1234567890", // Obligatoire (nouveau nom)
"customerPhone1": "+1234567890", // Obligatoire si customerPhone absent (ancien nom)
"customerPhone2": "+1234567891", // Optionnel (téléphone secondaire)
"customerName": "John Doe", // Optionnel
"customerAddress": "123 Main St", // Optionnel (nouveau nom)
"address": "123 Main St", // Optionnel (ancien nom)
"customerCity": "Tunis", // Optionnel (nouveau nom)
"ville": "Tunis", // Optionnel (ancien nom)
"customerGovernorate": "Tunis", // Optionnel (nouveau nom)
"gouvernaurat": "Tunis", // Optionnel (ancien nom)
"customerZipCode": "1000", // Optionnel (code postal)
"notes": "Instructions de livraison", // Optionnel
"source": "manual", // Optionnel (défaut : "manual")
"status": "pending", // Optionnel (statut initial)
"resellerId": 12, // Admin uniquement
"supplierId": 3, // Admin uniquement
"shippingOption": "paid", // Optionnel : "paid" active shippingCost
"shippingCost": 8.5, // Optionnel : utilisé si shippingOption = "paid"
"shipping": 8.5, // Optionnel : ancien champ de livraison
"products": [
{
"productId": 1,
"quantity": 2,
"price": 99.99, // Nouveau nom de champ
"notes": "Variante: Bleu / Taille M"
},
{
"productId": 2,
"quantity": 1,
"unitPrice": 49.99, // Ancien nom de champ (supporté)
"notes": "Option: Pack cadeau"
}
]
}
paid)resellerId (integer) et supplierId (integer) obligatoires.resellerId et supplierId sont ignorés (pris depuis l'utilisateur authentifié).
Les commandes issues de Converty utilisent l'image du mapping produit côté serveur.
Pour les commandes provenant d'autres sources (site web, scraping, API externe), chaque item doit inclure
notes (variante/option). L'image est récupérée côté serveur depuis le mapping produit.
Si vous utilisez Converty, configurez d'abord le mapping produits avant d'envoyer des commandes.
Pour récupérer les IDs produits fournisseur, utilisez /api/v1/converty/product-mappings (mapping Converty → fournisseur)
ou /api/v1/products. Ne partagez pas cost_price (privé).
Si source est sur_place, le système force status = delivered, marque le paiement comme payé, et met "Sur place" pour la ville/gouvernorat si manquants.
{
"success": true,
"message": "Order created successfully",
"orderNumber": "ORD-1755436083209-123",
"orderStatus": "pending",
"order": {
"id": 123,
"orderNumber": "ORD-1755436083209-123",
"status": "pending",
"total": 249.97,
"customerName": "John Doe",
"customerPhone": "+1234567890",
"customerPhone2": "+1234567891",
"customerAddress": "123 Main St",
"customerCity": "Tunis",
"customerGovernorate": "Tunis",
"customerZipCode": "1000",
"notes": "Instructions de livraison",
"source": "manual",
"barcode": "ORD-1755436083209-123"
}
}
/api/v1/converty/product-mappings
Lister les mappings Converty ↔ fournisseur (sans cost_price)
{
"success": true,
"mappings": [
{
"id": 12,
"convertyProduct": { "id": 321, "name": "Produit A", "sku": "SKU-A", "price": 29.9 },
"supplierProduct": { "id": 7, "name": "Produit A", "code": "PA-01", "price": 29.9, "stock_quantity": 40 },
"converty_image": "https://cdn.commercy.net/converty/321.jpg",
"createdAt": "2026-01-19T10:00:00.000Z"
}
]
}
Utilisez supplierProduct.id comme productId dans l'API de commande.
/api/v1/converty/product-mappings
Créer un mapping Converty ↔ fournisseur
{
"convertyProductId": 321,
"supplierProductId": 7
}
/api/v1/converty/product-mappings/:id
Supprimer un mapping
/api/v1/converty/check-mappings/:resellerId
Vérifier si les mappings existent pour un revendeur
const api = new CommercyAPI({
baseURL: 'https://api.commercy.net',
apiVersion: 'v1'
});
// Connexion
const loginResult = await api.login('user@example.com', 'password');
// Lister les commandes
const orders = await api.getOrders({ limit: 10, page: 1 });
// Créer une commande
const newOrder = await api.createOrder({
customerName: 'John Doe',
products: [{ productId: 1, quantity: 2 }]
});
import requests
class CommercyAPI:
def __init__(self, base_url, token):
self.base_url = f"{base_url}/api/v1"
self.headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
def get_orders(self, params=None):
response = requests.get(
f"{self.base_url}/orders",
headers=self.headers,
params=params
)
return response.json()
# Utilisation
api = CommercyAPI('https://api.commercy.net', 'your-token')
orders = api.get_orders({'limit': 10, 'page': 1})
SDK complet avec tous les endpoints et la gestion d'erreurs
Collection Postman prête à l'emploi pour les tests
Exemples complets et bonnes pratiques
{
"success": true,
"data": {
"id": 123,
"customerName": "John Doe",
"status": "pending",
"createdAt": "2024-01-15T10:30:00.000Z"
},
"message": "Order created successfully",
"timestamp": "2024-01-15T10:30:00.000Z"
}
{
"success": true,
"data": [
{
"id": 1,
"customerName": "John Doe",
"status": "pending"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 100,
"totalPages": 10,
"hasNext": true,
"hasPrev": false
},
"timestamp": "2024-01-15T10:30:00.000Z"
}
{
"success": false,
"error": "Validation error",
"message": "Invalid input data",
"timestamp": "2024-01-15T10:30:00.000Z",
"details": {
"field": "email",
"message": "Email is required"
}
}
Cela arrive quand les dates ne sont pas au bon format. Utilisez le format ISO : YYYY-MM-DDTHH:mm:ss.sssZ
Vérifiez les champs obligatoires et les bons noms de champs (ancien ou nouveau format).
Vérifiez l'envoi d'un JWT valide dans l'en-tête Authorization : Bearer YOUR_TOKEN
Utilisez new Date().toISOString() pour un format correct en JavaScript.
Les anciens et nouveaux noms sont supportés. Utilisez le format déjà utilisé côté frontend.
Utilisez toujours les endpoints /api/v1/ pour les dernières fonctionnalités et la rétrocompatibilité.