Commandé avant 12h00 = expédié le jour ouvrable suivant*

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.

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
URL de base: https://api.tormino.com/dropship/v1
Wallet API: https://app.shopwaive.com/api
↑ Retour en haut

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.

POST /orders

RequĂȘte

ParamĂštreTypeRequisDescription
referencestringOuiVotre référence de commande interne
shipping.namestringOuiNom complet du client final
shipping.address1stringOuiRue et numéro
shipping.address2stringNonLigne d'adresse supplémentaire
shipping.citystringOuiVille
shipping.zipstringOuiCode postal
shipping.countrystringOuiISO 3166-1 alpha-2 (NL, BE, DE, FR)
shipping.phonestringNonTéléphone du client final
shipping.emailstringNonE-mail du client final
items[].eanstringOuiCode EAN du produit
items[].skustringNonSKU du produit (repli si EAN manquant)
items[].quantityintegerOuiQuantité à 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

En cas de solde insuffisant, la commande est refusee (HTTP 402). Aucune commande n'est creee.
{
  "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
}
Idempotence: Ajoutez un en-tĂȘte Idempotency-Key pour Ă©viter les commandes en double lors des rĂ©essais. MĂȘme clĂ© = aucune commande en double créée.
↑ Retour en haut

Synchroniser le stock

Vérifiez la disponibilité en temps réel des articles avant de les proposer dans votre boutique.

Article unique

GET /stock/{ean}
{
  "ean": "8711234567890",
  "sku": "TORM-12345",
  "available": true,
  "quantity": 47,
  "lead_time_days": 1
}

Lot (max 100 par requĂȘte)

POST /stock/batch
// Request
{ "eans": ["8711234567890", "8711234567891"] }

// Response
{
  "items": [
    { "ean": "8711234567890", "available": true, "quantity": 47 },
    { "ean": "8711234567891", "available": false, "quantity": 0 }
  ]
}
↑ Retour en haut

Gerer le wallet

Consultez votre solde actuel et l'historique des transactions, ou rechargez votre wallet via iDeal.

Powered by Shopwaive — Les endpoints du wallet utilisent l'API REST de Shopwaive avec une authentification separee.

Solde & transactions

GET /customer/{email}?activity=true
# 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"
    }
  ]
}
Parametres: ?activity=true pour l'historique des transactions, ?orders=true pour les commandes Shopify associees.

Recharger

Rechargement minimum de 100 EUR. Le solde ne expire pas.
GET /products/wallet-opwaarderen
Les rechargements se font via le checkout Shopify normal. Achetez le produit de rechargement du wallet, choisissez le montant et payez avec iDeal. Apres le paiement, le solde est automatiquement mis a jour via Shopwaive + Shopify Flow.
// 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 }
↑ Retour en haut

Apercu des commandes

Consultez vos récentes commandes avec le statut de traitement et le numéro de suivi.

GET /orders?status=confirmed&limit=20
{
  "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"
    }
  ]
}
ParamĂštres de requĂȘte: status (confirmed, shipped, cancelled), limit (max 50), offset pour la pagination.
↑ Retour en haut

Webhooks

Nous envoyons des notifications à votre URL webhook configurée lors des changements de statut de commande.

ÉvĂ©nementDĂ©clencheurCharge utile
order.confirmedCommande créée + wallet débitéorder_id, amount, wallet_balance_after
order.shippedTraitement créé dans Shopifyorder_id, tracking_number, tracking_carrier
order.cancelledCommande annuléeorder_id, reason, refund_amount
wallet.low_balanceSolde passe sous le seuilbalance, 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()
↑ Retour en haut

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.

CodeErreurDescription
401unauthorizedClé API manquante ou invalide
402insufficient_wallet_balanceSolde wallet trop bas pour la commande
404product_not_foundEAN/SKU introuvable dans le catalogue
409insufficient_stockQuantité demandée dépasse le stock disponible
422validation_errorChamps de requĂȘte manquants ou invalides
429rate_limit_exceededTrop de requĂȘtes (max 100/min)
500internal_errorErreur serveur - réessayer avec backoff
↑ Retour en haut

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');
}
↑ Retour en haut

Limites de debit & bonnes pratiques

Maximum 100 requĂȘtes par minute par clĂ© API. Utilisez les endpoints batch pour les contrĂŽles de stock.

LimiteValeur
RequĂȘtes par minute100 par clĂ© API
RequĂȘtes par heure1000 par clĂ© API
VĂ©rification stock par lotMax 100 EANs par requĂȘte
Commandes par requĂȘte1 (une commande par appel API)
En-tĂȘtes de limite de dĂ©bitX-RateLimit-Remaining, X-RateLimit-Reset
Bonne pratique: Synchronisez le stock via l'endpoint batch toutes les 15-30 minutes. Utilisez les webhooks pour les mises Ă  jour de statut de commande au lieu du polling. Incluez toujours Idempotency-Key dans les requĂȘtes de commande pour rĂ©essayer en toute sĂ©curitĂ© en cas d'erreurs rĂ©seau.