J’ai récemment du faire des tests de commandes via les Api de Prestashop et je n’ai pas trouvé de script tout fait qui le permettait.
Celui-ci utilise la librairie fournie par Prestashop et disponible sur github : https://github.com/PrestaShop/PrestaShop-webservice-lib/blob/master/PSWebServiceLibrary.php

En voici donc un basique qui va effectuer les actions suivantes :

  • Récupération de l’identifiant client ( création du client si nécessaire )
  • Récupération de l’identifiant de l’adresse du client ( création si nécessaire )
  • Création d’un panier
  • Passage de la commande

Ce script a été exécuté avec succès sur la version 1.7.3.3 de Prestashop et doit donc être compatible avec les versions suivantes.
Je n’ai pas constaté de changement fondamentaux dans l’api par rapport à Prestashop 1.6, pour lequel il devrait également fonctionner ( en changeant les produits )

N’hésitez pas à partager vos retours d’expériences sur l’utilisation de l’api de Prestashop

 
require_once('./PSWebServiceLibrary.php');
 
try {
 
    $host = 'https://yourshop.com';
    $apiKey = 'APIKEY';
 
    $webService = new PrestaShopWebservice($host, $apiKey, false);
 
    /**
     * On stocke ici les variables communes aux commandes créés via l'api
     */
 
      $customerEmail = '[email protected]'; //Email du client ( A dynamiser dans le cadre d'une utilisation complète )
      $carrierName = 'My carrier'; //Nom du transporteur dans prestashop ( utilisé pour récupérer son identifiant )
      $paymentLabel = 'Paiement par chèque'; // Nom du mode de paiement
      $paymentCode = 'ps_checkpayment'; //Module de paiement utilisé
 
    /**
     * Liste des produits qu'on souhaite ajouter au panier
     */
    $products = [
        [
            'reference' => 'demo_12',
            'qty' => 3,
        ],
        [
            'reference' => 'demo_19',
            'qty' => 1,
        ],
        [
            'reference' => 'demo_6',
            'qty' => 2,
            'combination' => [
                'reference' => 'demo_6'
            ]
        ],
    ];
 
    //Paramètres du client
    $customerDatas = [
        'firstname' => 'herve',
        'lastname' => 'test',
        'email' => '[email protected]',
        'passwd' => 'mypassword',
        'note' => 'Customer created with api',
    ];
 
    //Paramètres de l'adresse
    $addressDatas = [
        'alias' => 'addresse api',
        'id_customer' => $customerId,
        'firstname' => 'herve',
        'lastname' => 'test',
        'address1' => 'rue des tests',
        'address2' => 'encore rue des tests',
        'postcode' => '67000',
        'city' => 'strasbourg',
        'phone' => '063656565',
        'id_country' => 8,
    ];
 
 
    //On regarde si le client existe
    $searchCustomerXml = $webService->get([
        'resource' => 'customers',
        'filter' => ['email' => $customerEmail],
    ]);
 
    //Si il existe on récupère l'identifiant
    if (!empty($searchCustomerXml->children()->children())) {
        $customerId = (int)$searchCustomerXml->children()->children()[0]->attributes()['id'][0];
    } //Si il n'existe pas on le créé
    else {
        //Création d'un client
        $clientXml = $webService->get(['url' => $host . 'api/customers?schema=blank']);
        foreach ($clientXml->customer[0] as $nodeKey => $node) {
            if (array_key_exists($nodeKey, $customerDatas)) {
                $clientXml->children()[0]->$nodeKey = $customerDatas[$nodeKey];
            }
        }
        $opt = array('resource' => 'customers');
        $opt['postXml'] = $clientXml->asXML();
        $resultXml = $webService->add($opt);
        $customerId = (int)$resultXml->children()[0]->id;
    }
 
    //Récupération des adresses on part du principe qu'on récupère la première adresse du client si elle existe
    //On regarde si le client existe
    $searchAddressXml = $webService->get([
        'resource' => 'addresses',
        'filter' => ['id_customer' => $customerId],
    ]);
 
    //Si il existe on récupère l'identifiant de la première adresse
    if (!empty($searchAddressXml->children()->children())) {
        $addressId = (int)$searchAddressXml->children()->children()[0]->attributes()['id'][0];
    } //Si il n'existe pas on le créé
    else {
 
        //Création d'un client
        $addressXml = $webService->get(['url' => $host . 'api/addresses?schema=blank']);
        foreach ($addressXml->address[0] as $nodeKey => $node) {
            if (array_key_exists($nodeKey, $addressDatas)) {
                $addressXml->children()[0]->$nodeKey = $addressDatas[$nodeKey];
            }
        }
 
        $opt = array('resource' => 'addresses');
        $opt['postXml'] = $addressXml->asXML();
        $resultXml = $webService->add($opt);
        $addressId = (int)$resultXml->children()[0]->id;
    }
 
    //Création d'un panier
    $cartXml = $webService->get(['url' => $host . 'api/carts?schema=blank']);
 
    //Définition des paramètres par défaut du panier
    //Tout ces paramètres pourront être récupérés de l'api en une fois et stockés
    $cartXml->cart->id_customer = $customerId;
    $cartXml->cart->id_address_delivery = $addressId;
    $cartXml->cart->id_address_invoice = $addressId;
    $cartXml->cart->id_currency = 1; //@Todo récupérer via api
    $cartXml->cart->id_lang = 1; //@Todo récupérer via api
    $cartXml->cart->id_shop = 1; //@Todo récupérer via api
    $cartXml->cart->id_shop_group = 1;
 
    //Identifiant du transporteur à récupérer dynamiquement ( peut bouger en étant édité dans le backoffice )
    $carrierXml = $webService->get(['resource' => 'carriers', 'filter' => ['name' => $carrierName]]);
 
    if (!empty($carrierXml->children()->children()[0]->attributes()['id'][0])) {
        $id_carrier = (int)$carrierXml->children()->children()[0]->attributes()['id'][0];
    } //Si il n'existe pas on le créé
    else {
        exit('Mode de livraison existe pas');
    }
 
    $cartXml->cart->id_carrier = $id_carrier;
 
    //Récupération de identifiants des produits
    $productIds = array();
    foreach ($products as $cartProduct) {
        $productSearchXml = $webService->get([
            'resource' => 'products',
            'filter' => ['reference' => $cartProduct['reference']],
        ]);
 
        if (!empty($productSearchXml->children()->children()[0]->attributes()['id'][0])) {
            $id_product = (int)$productSearchXml->children()->children()[0]->attributes()['id'][0];
        } else {
            //Si pas de produit on ne peut pas continuer
            continue;
        }
 
        if (isset($cartProduct['combination'])) {
            $combinationSearchXml = $webService->get([
                'resource' => 'combinations',
                'filter' => ['reference' => $cartProduct['reference']],
            ]);
            if (!empty($combinationSearchXml->children()->children()[0]->attributes()['id'][0])) {
                $id_product_attribute = (int)$combinationSearchXml->children()->children()[0]->attributes()['id'][0];
            } else {
                $id_product_attribute = 0;
            }
        } else {
            $id_product_attribute = 0;
        }
        $productIds[] = [
            'id_product' => $id_product,
            'id_product_attribute' => $id_product_attribute,
            'qty' => $cartProduct['qty']
        ];
    }
 
    //Insertion des lignes de produits
    foreach ($productIds as $productId) {
        $child = $cartXml->cart->associations->cart_rows->addChild('cart_row');
        $child->id_product = $productId['id_product'];
        $child->id_product_attribute = $productId['id_product_attribute'];
        $child->quantity = $productId['qty'];
        $child->id_adddress_delivery = $addressId;
    }
 
    //Création du panier
    $opt = array('resource' => 'carts');
    $opt['postXml'] = $cartXml->asXML();
    $addCartXml = $webService->add($opt);
 
    //Création d'une commande ( à faire )
    $orderXml = $webService->get(['url' => $host . 'api/orders?schema=blank']);
 
    //On défini les éléments de la commande spécifiques
    $orderXml->order->valid = 1;
    $orderXml->order->module = 'ps_checkpayment'; //Module de paiement
    $orderXml->order->payment = 'Paiement par cheque'; //Libéllé du mode de paiment
 
    //Les éléments communs avec le panier sont récupérés depuis celui-ci
    $orderXml->order->id_address_delivery = $addCartXml->cart->id_address_delivery;
    $orderXml->order->id_address_invoice = $addCartXml->cart->id_address_invoice;
    $orderXml->order->id_cart = $addCartXml->cart->id;
    $orderXml->order->id_customer = $addCartXml->cart->id_customer;
    $orderXml->order->id_carrier = $addCartXml->cart->id_carrier;
    $orderXml->order->id_currency = $addCartXml->cart->id_currency;
    $orderXml->order->id_shop = $addCartXml->cart->id_shop;
    $orderXml->order->id_shop_group = $addCartXml->cart->id_shop_group;
    $orderXml->order->id_lang = $addCartXml->cart->id_lang;
 
    // les lignes des produits sont aussi récupérées depuis le panier
 
    $orderTotal = 0; //Variable pour calculer le total de la commande
    unset($orderXml->order->associations->order_rows->children()[0]); //Suppression de ligne order_detail de démo
    foreach ( $addCartXml->cart->associations->cart_rows->cart_row as $cartRow) {
 
        //On ne traite pas les lignes vides
        if ( $cartRow->id_product == 0 || $cartRow->id_product =="")
            continue;
 
        //On récupère les informations disponibles depuis le panier
        $orderRow = $orderXml->order->associations->order_rows->addChild('order_row');
        $orderRow->product_id = $cartRow->id_product;
        $orderRow->product_attribute_id = $cartRow->id_product_attribute;
        $orderRow->product_quantity = $cartRow->quantity;
 
        //Pour le reste on le récupère depuis les produits
        $productXml = $webService->get(['url' => $host . 'api/products/'.$cartRow->id_product]);
        $orderRow->product_name = $productXml->product->name;
        $orderRow->product_reference = $productXml->product->reference;
        $orderRow->product_price = $productXml->product->price;
 
        //Ajout du montant du produit au total du panier ( Le prix HT * la qté * 1+ Taux de tva )
        $orderTotal += ( (float)$productXml->product->price * (int)$cartRow->quantity ) * 1.20 ;
    }
 
    //Données spécifiques à la commande   
    $orderXml->order->total_paid_real = $orderTotal; //Montant payé réellement 
    $orderXml->order->total_paid = $orderTotal; //Montant payé 
 
    $orderXml->order->total_products = 1; //Montant total produit ht ( obligatoire mais indicatif car recalculé automatiquement )
    $orderXml->order->total_products_wt = 1; //Montant total produit ttc ( obligatoire mais indicatif car recalculé automatiquement )
    $orderXml->order->conversion_rate = 1; // Taux de conversion
 
 
    //Création de la commande
    $opt = array('resource' => 'orders');
    $opt['postXml'] = $orderXml->asXML();
    $addOrderXml = $webService->add($opt);
 
    echo 'Création de la commande '.$addOrderXml->order->id;    
} catch (PrestaShopWebserviceException $e) {
    echo $e->getMessage();
}

Des optimisations et des factorisations sont encore possibles mais cela donne déjà une bonne base fonctionnelle 🙂