API Dropshipping
Intégrez votre boutique ou votre systÚme ERP avec Tormino via notre API REST. Passez des commandes automatiquement, synchronisez le stock en temps réel et gérez votre solde wallet.
Sommaire
Authentification
Toutes les requĂȘtes API nĂ©cessitent une clĂ© API (Bearer token). Vous la recevez aprĂšs approbation de votre demande de dropshipping.
# Header format - Orders & Stock API Authorization: Bearer YOUR_API_KEY Content-Type: application/json # Header format - Wallet API (Shopwaive) X-Shopwaive-Access-Token: YOUR_SHOPWAIVE_API_KEY X-Shopwaive-Platform: shopify Content-Type: application/json
https://api.tormino.com/dropship/v1Wallet API:
https://app.shopwaive.com/api
Passer des commandes
Placez une nouvelle commande depuis votre systÚme directement dans notre entrepÎt. La commande n'est créée qu'avec un solde wallet et un stock suffisants.
RequĂȘte
| ParamĂštre | Type | Requis | Description |
|---|---|---|---|
| reference | string | Oui | Votre référence de commande interne |
| shipping.name | string | Oui | Nom complet du client final |
| shipping.address1 | string | Oui | Rue et numéro |
| shipping.address2 | string | Non | Ligne d'adresse supplémentaire |
| shipping.city | string | Oui | Ville |
| shipping.zip | string | Oui | Code postal |
| shipping.country | string | Oui | ISO 3166-1 alpha-2 (NL, BE, DE, FR) |
| shipping.phone | string | Non | Téléphone du client final |
| shipping.email | string | Non | E-mail du client final |
| items[].ean | string | Oui | Code EAN du produit |
| items[].sku | string | Non | SKU du produit (repli si EAN manquant) |
| items[].quantity | integer | Oui | Quantité à commander |
// POST /orders { "reference": "ORD-2024-12345", "shipping": { "name": "Jan Jansen", "address1": "Kerkstraat 1", "address2": "", "city": "Amsterdam", "zip": "1011AB", "country": "NL", "phone": "+31612345678", "email": "jan@example.com" }, "items": [ { "ean": "8711234567890", "quantity": 2 } ] }
Réponse 200 OK
{
"order_id": "TORM-500123",
"status": "confirmed",
"wallet_balance_after": 425.50,
"currency": "EUR",
"estimated_ship_date": "2026-07-17"
}
Réponse 402 Payment Required
{
"error": "insufficient_wallet_balance",
"message": "Insufficient balance. Current: EUR 25.00. Required: EUR 74.50.",
"wallet_balance": 25.00,
"amount_required": 74.50,
"top_up_url": "https://tormino.nl/pages/b2b-dashboard#wallet"
}
Réponse 409 Conflict
{
"error": "insufficient_stock",
"message": "Item 8711234567890 has insufficient stock.",
"item_ean": "8711234567890",
"requested": 2,
"available": 1
}
Idempotency-Key pour Ă©viter les commandes en double lors des rĂ©essais. MĂȘme clĂ© = aucune commande en double créée.Synchroniser le stock
Vérifiez la disponibilité en temps réel des articles avant de les proposer dans votre boutique.
Article unique
{
"ean": "8711234567890",
"sku": "TORM-12345",
"available": true,
"quantity": 47,
"lead_time_days": 1
}
Lot (max 100 par requĂȘte)
// Request { "eans": ["8711234567890", "8711234567891"] } // Response { "items": [ { "ean": "8711234567890", "available": true, "quantity": 47 }, { "ean": "8711234567891", "available": false, "quantity": 0 } ] }
Gerer le wallet
Consultez votre solde actuel et l'historique des transactions, ou rechargez votre wallet via iDeal.
Solde & transactions
# Headers X-Shopwaive-Access-Token: YOUR_SHOPWAIVE_API_KEY X-Shopwaive-Platform: shopify Content-Type: application/json # Response { "balance": 425.50, "activity": [ { "id": "action_739281", "type": "deposit", "amount": 500.00, "note": "Top-up via iDeal", "date": "2026-07-15T14:00:00Z", "status": "active" }, { "id": "action_739282", "type": "withdrawal", "amount": -74.50, "note": "Order TORM-500123", "date": "2026-07-16T10:30:00Z", "status": "active" } ] }
?activity=true pour l'historique des transactions, ?orders=true pour les commandes Shopify associees.
Recharger
// Programmatore top-up (via Shopwaive API) PUT /customer X-Shopwaive-Access-Token: YOUR_SHOPWAIVE_API_KEY X-Shopwaive-Platform: shopify { "email": "partner@example.com", "amount": 500.00 }
Apercu des commandes
Consultez vos récentes commandes avec le statut de traitement et le numéro de suivi.
{
"orders": [
{
"order_id": "TORM-500123",
"reference": "ORD-2024-12345",
"status": "fulfilled",
"tracking_number": "3S1234567890",
"tracking_carrier": "PostNL",
"total": 74.50,
"created_at": "2026-07-16T10:30:00Z",
"shipped_at": "2026-07-17T09:15:00Z"
}
]
}
status (confirmed, shipped, cancelled), limit (max 50), offset pour la pagination.Webhooks
Nous envoyons des notifications à votre URL webhook configurée lors des changements de statut de commande.
| ĂvĂ©nement | DĂ©clencheur | Charge utile |
|---|---|---|
| order.confirmed | Commande créée + wallet débité | order_id, amount, wallet_balance_after |
| order.shipped | Traitement créé dans Shopify | order_id, tracking_number, tracking_carrier |
| order.cancelled | Commande annulée | order_id, reason, refund_amount |
| wallet.low_balance | Solde passe sous le seuil | balance, threshold, top_up_url |
Vérification webhook
// Verify HMAC-SHA256 signature X-Tormino-Signature: sha256=hex_signature // Pseudocode expected = HMAC_SHA256(webhook_secret, raw_body) if expected == received_signature: process_webhook(payload) else: reject()
Gestion des erreurs
L'API utilise les codes de statut HTTP standards. Les réponses d'erreur contiennent un code d'erreur lisible par machine.
| Code | Erreur | Description |
|---|---|---|
| 401 | unauthorized | Clé API manquante ou invalide |
| 402 | insufficient_wallet_balance | Solde wallet trop bas pour la commande |
| 404 | product_not_found | EAN/SKU introuvable dans le catalogue |
| 409 | insufficient_stock | Quantité demandée dépasse le stock disponible |
| 422 | validation_error | Champs de requĂȘte manquants ou invalides |
| 429 | rate_limit_exceeded | Trop de requĂȘtes (max 100/min) |
| 500 | internal_error | Erreur serveur - réessayer avec backoff |
Exemples de code
Exemples prĂȘts Ă l'emploi pour passer une commande dans les langues les plus utilisĂ©es.
$payload = [ 'reference' => 'ORD-2024-12345', 'shipping' => [ 'name' => 'Jan Jansen', 'address1' => 'Kerkstraat 1', 'city' => 'Amsterdam', 'zip' => '1011AB', 'country' => 'NL', ], 'items' => [ ['ean' => '8711234567890', 'quantity' => 2], ], ]; $ch = curl_init('https://api.tormino.com/dropship/v1/orders'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json', 'Idempotency-Key: ' . uniqid(), ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($httpCode === 200) { $result = json_decode($response, true); echo "Order confirmed: " . $result['order_id']; } elseif ($httpCode === 402) { echo "Insufficient wallet balance"; } curl_close($ch);
import requests import uuid payload = { "reference": "ORD-2024-12345", "shipping": { "name": "Jan Jansen", "address1": "Kerkstraat 1", "city": "Amsterdam", "zip": "1011AB", "country": "NL", }, "items": [ {"ean": "8711234567890", "quantity": 2}, ], } headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json", "Idempotency-Key": str(uuid.uuid4()), } response = requests.post( "https://api.tormino.com/dropship/v1/orders", json=payload, headers=headers, ) if response.status_code == 200: data = response.json() print(f"Order confirmed: {data['order_id']}") elif response.status_code == 402: print("Insufficient wallet balance")
const response = await fetch('https://api.tormino.com/dropship/v1/orders', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', 'Idempotency-Key': crypto.randomUUID(), }, body: JSON.stringify({ reference: 'ORD-2024-12345', shipping: { name: 'Jan Jansen', address1: 'Kerkstraat 1', city: 'Amsterdam', zip: '1011AB', country: 'NL', }, items: [ { ean: '8711234567890', quantity: 2 }, ], }), }); const data = await response.json(); if (response.ok) { console.log(`Order confirmed: ${data.order_id}`); } else if (response.status === 402) { console.log('Insufficient wallet balance'); }
Limites de debit & bonnes pratiques
Maximum 100 requĂȘtes par minute par clĂ© API. Utilisez les endpoints batch pour les contrĂŽles de stock.
| Limite | Valeur |
|---|---|
| RequĂȘtes par minute | 100 par clĂ© API |
| RequĂȘtes par heure | 1000 par clĂ© API |
| VĂ©rification stock par lot | Max 100 EANs par requĂȘte |
| Commandes par requĂȘte | 1 (une commande par appel API) |
| En-tĂȘtes de limite de dĂ©bit | X-RateLimit-Remaining, X-RateLimit-Reset |
Idempotency-Key dans les requĂȘtes de commande pour rĂ©essayer en toute sĂ©curitĂ© en cas d'erreurs rĂ©seau.