Blog tech

Service So Colissimo et SOAP

Rédigé par Alexandre Salaun | 2 août 2012

Lors du développement de sites ou d’applications e-commerce, il est nécessaire de gérer les différents modes de livraison afin de permettre au client de recevoir sa commande. En France, l’un des services les plus utilisés est celui de La Poste via So Colissimo et la livraison en point de retrait.

Présentation du service So Colissimo

Il existe différentes solutions proposées par La Poste, il est donc nécessaire de choisir celle qui correspond à vos besoins.

Ensuite, différentes méthodes sont également disponibles suivant ce que l’on veut récupérer comme informations. Dans notre cas, nous utilisons la méthode findRDVPointRetraitAcheminement. Celle-ci permet donc grâce à un appel SOAP de savoir si une livraison avec rendez-vous est possible et de connaître les points de retrait situés à proximité.

Il est également possible de récupérer ces informations via une interface https.

Utilisation du service So Colissimo

L’appel SOAP

Afin de faire un appel au service So Colissimo via SOAP nous allons utiliser la gem Savon.

Les paramètres d’entrée nécessaire au bon fonctionnement sont :

  • l’identifiant client
  • le mot de passe
  • une adresse complète (numéro, rue, code postal, ville)
  • un numéro unique permettant d’identifier la requête
  • une valeur (0 ou 1) permettant d’inclure ou non les points commerces de proximité
  • une date d’envoi estimée

Il est également possible d’indiquer le poids du colis mais ce paramètre est optionnel.

Il existe des validations sur ces paramètres coté serveur (format des données, présence…), il est donc nécessaire de passer tous les paramètres nécessaires.

client   = Savon::Client.new { wsdl.document = "https://ws.colissimo.fr/pointretrait-ws-cxf/PointRetraitServiceWS?wsdl" }
response = client.request method do |soap|
   soap.version = 2
   soap.body    = { "accountNumber" => 123456, "password" => "my_password", "address" => "XXX rue de Paris", "zipCode" => "59000", "city" => "Lille", "shippingDate" => "02/07/2012", "filterRelay" => 1, "requestId" => "NUMERO_DE_TEST_1234" }
end

Il est important de passer le numéro de compte et le mot de passe avant le reste des paramètres.

Nous obtenons donc comme réponse une Hash avec un code d’erreur (qui vaut 0 si il n’y a pas d’erreur), un message d’erreur, la liste des points de retrait, un indiquateur de qualité de la réponse, l’identifiant de la requête et un indicateur permettant de savoir si une livraison avec rendez-vous est possible.

Création d’un client SOAP

Dans le but de faciliter les choses, un module ColissimoClient va être utilisé. Nous allons donc créer ce dernier ainsi qu’une classe Client qui permettra de faire appel au web service.

# un fichier de configuration est utilisé pour le wsdl ainsi que l'identifiant et le mot de passe
module Colissimo
  class Client
    attr_accessor :settings

    def initialize
      self.settings = COLISSIMOWS

      @client = soap_client_new settings["wsdl"] # Savon::Client.new settings["wsdl"]
      @client.http.auth.ssl.verify_mode = :none
    end

    def get_all_withdrawal_points(address)
      call_ws :findRDVPointRetraitAcheminement, address, :find_rdv_point_retrait_acheminement_response
    end

    private

      def soap_client_new(wsdl)
        (settings["soap_client"].constantize)::Client.new { wsdl.document = wsdl }
      end

      def call_ws(method, params, return_hash)
        body = Hash.new
        body["accountNumber"] = settings["accountNumber"]
        body["password"]      = settings["password"]

        params.each do |key, value|
          body[key] = value
        end

        begin
          response = @client.request method do |soap|
            soap.version = soap_version
            soap.body    = body
          end
        rescue Exception => error
          raise WebServiceError, "Error: #{error.class} #{error.message}"
        end

        result_code    = response.body[return_hash][:return][:error_code]
        result_message = response.body[return_hash][:return][:error_message]

        case result_code
          when "0"
            response # success
          when "101"
            raise MissingAccountNumber
          when "102"
            raise MissingPassword
          when "104"
            raise MissingZipCode
          when "105"
            raise MissingCity
          when "106"
            raise MissingShippingDate
          when "107"
            raise MissingWithdrawalPointId
          when "120"
            raise WeightIsNotNumber
          when "121"
            raise InvalidWeight
          when "122"
            raise MalformedShippingDate
          when "123"
            raise InvalidFilter
          when "124"
            raise InvalidWithdrawalPointId
          when "125"
            raise InvalidZipCode
          when "201"
            raise InvalidLoginOrPassword
          when "202"
            raise Forbidden
          when "300"
            raise NoWithdrawalPoints
          else
            raise WebServiceError, "#{result_code} : #{result_message}" # autres erreurs
        end
      end

      def soap_version
        2
      end
  end
end

Nous avons donc une méthode get_all_withdrawal_points(address) qui nous permettra d’obtenir les informations souhaitées, tout en sachant que seule l’adresse sera à passer en paramètre.

Il y a également une gestion des erreurs retournées par le web service. Si l’on utilise uniquement le Français, il est possible de retourner directement les messages d’erreurs du web service. Dans notre cas, on lance des exceptions suivant les codes d’erreur afin d’être multilingue ou de générer des messages personnalisés.

Utilisation de la réponse

Nous allons enrichir notre module Colissimo afin de faire un traitement sur la réponse. Pour cela, nous ajoutons une classe Shipping avec une méthode de classe appointment_and_withdrawal_points_from_address. Il est nécessaire de passer en paramètre l’adresse, le code postal, la ville, la date d’envoi ainsi que l’identifiant de la requête. Un booléen sera retourné pour savoir si une livraison avec rendez-vous est possible ainsi que la liste des points de retrait.

module Colissimo
  class Shipping
    def self.client
      @client ||= Colissimo::Client.new
    end

    def self.appointment_and_withdrawal_points_from_address(address, zip_code, city, shipping_date, request_id)
      parameters = { "address" => address, "zipCode" => zip_code, "city" => city, "shippingDate" => shipping_date, "filterRelay" => 1, "requestId" => request_id }

      response = client.get_all_withdrawal_points(parameters).body[:find_rdv_point_retrait_acheminement_response][:return]

      return { :appointment => response[:rdv], :withdrawal_points => response[:liste_point_retrait_acheminement]}
    end
  end
end

Il va donc maintenant être possible d’appeler cette méthode depuis un controller par exemple pour afficher les points de retrait afin de permettre à un utilisateur de choisir celui qui lui convient.

response           = Colissimo::Shipping.appointment_and_withdrawal_points_from_address(address, zipcode, city, date, number)
@withdrawal_points = response[:withdrawal_points]
@appointment       = response[:appointment]

Dans la vue on pourra parcourir chaque point de retrait pour afficher les informations le concernant. Le web service nous retourne un certain nombre d’informations telles que le nom, l’adresse, l’identifiant du point de retrait, la distance par rapport à l’adresse donnée ainsi que les horaires d’ouverture et les congés éventuels.

L’utilisateur aura donc à disposition un certain nombre d’informations pour faire son choix.

S’il choisit une livraison en point de retrait, il est indispensable de conserver l’identifiant de ce dernier car il sera utile lors de l’expédition.

Conclusion

Grâce au web service So Colissimo et à la gem Savon, il est donc possible de proposer aux utilisateurs d’un site ou d’une application e-commerce la méthode de livraison de leur choix.

Suite à cet appel les modes de livraison suivant seront disponibles: So Colissimo classique, So Colissimo contre signature, livraison en point relais et éventuellement livraison sur rendez-vous.

L’équipe Synbioz.

Libres d’être ensemble.