Implémentation d'Alma

Clients d'API

Alma fournit un client d'API PHP sur Github : https://github.com/alma/alma-php-client

Celui-ci permet de suivre les détails d'implémentation ci-dessous de façon simplifiée en s'abstrayant des détails des requêtes HTTP.

Par exemple pour vérifier l'éligibilité d'une commande et créer le paiement correspondant chez Alma :

<?php
$alma = new Alma\API\Client($apiKey, ['mode' => Alma\API\TEST_MODE]);

// Fetch payment data from your backend
$paymentData = dataFromCart();
$eligibility = $alma->payments->eligibility($paymentData);

if($eligibility->isEligible) {
    $payment = $alma->payments->createPayment($paymentData);
    redirect_to($payment->url);
}

Notez que $paymentData est un tableau associatif qui doit suivre le format JSON décrit dans Créer un Payment

Environnement de test

Alma met une "sandbox" à disposition pour vos tests et développements : https://dashboard.sandbox.getalma.eu.

Vous pouvez vous y connecter avec les mêmes identifiant et mot de passe que le dashboard de production.

📘

Pour utiliser l'API en mode test, il faut effectuer les appels HTTP sur l'URL de sandbox: https://api.sandbox.getalma.eu

Authentification des appels API

Lorsqu'un appel à l'API doit être authentifié, il faut ajouter le header suivant à la requête HTTP:

HeaderValeur
AuthorizationAlma-Auth <API key>

Tous les appels authentifiés doivent se faire depuis vos serveurs, afin d'assurer la sécurité de la clef d'API et ainsi d'éviter toute utilisation frauduleuse de votre accès à l'API Alma.

Si un appel authentifié échoue pour des raisons d'authentification, la réponse sera :
Code HTTP 401

{
  "message": "Credentials invalid or not supplied"
}

Représentation des données

Généralités

Pour tous les appels à l'API effectués en POST, les paramètres de l'appel doivent être passés en JSON dans le corps de la requête.

Par exemple :

{
    "payment": {
        "amount": 34500
    }
}

Headers HTTP

Il est impératif de spécifier le header HTTP suivant dans vos requêtes :

HeaderValeur
Content-typeapplication/json

Types de données spécifiques

Montants

Tous les montants sont convertis en centimes et exprimés en entiers (int). Ainsi, une commande de 199.90€ est représentée par la valeur 19990.

📘

PHP et bien d'autres langages utilisent une représentation en mémoire des nombres à virgule flottante qui est sujette à des problèmes d'arrondis. Pour convertir correctement un prix de type float en centimes de type int, utilisez la fonction suivante (ou équivalent) :

<?php
function price_to_cents($price)
{
    return (int)(round($price * 100));
}

Adresses

Toutes les adresses sont représentées par des objets avec leurs champs séparés.

Vous trouverez les attributs acceptés dans la représentation d'une adresse à la section Créer une Address

Customer

Un objet Customer est généralement envoyé en même temps que les détails d'un paiement lors de la création de celui-ci, ainsi que sur les vérifications d'éligibilité.

L'objet reprend les détails classiques fournis par un client dans votre tunnel de paiement (Nom, prénom, adresse, ...).

Vous trouverez les attributs acceptés dans la représentation d'un client dans la section Customer.

Paiement

Un objet paiement contient les informations typiques d'un e-commerce (adresses de livraison et facturation, identité du client, ...), qui sont passées lors de la création de celui-ci, mais aussi les informations liées au système de paiement en plusieurs fois : échéancier, frais, etc.

Création d'un paiement

Les attributs d'un objet paiement à fournir sur les appels d'éligibilité et de création de paiement sont détaillés dans la référence de l'API à la section Créer un Payment.

Représentation complète

Lorsque vous récupérez un objet Payment via l'API, il contient plus d'attributs que ceux fournis lors de la création. La liste complète des attributs est décrite à la section Payment

Exemple d'un objet Payment complet :

{
    "id": "payment_11gJxYm2LM9Gt9VyWOaY4kWQ4eC4r2sHpU",
    "mode": "insured",
    "state": "in_progress",
    "created": 1547562399,
    "url": "https://pay.getalma.eu/11gJxYm...",
    "return_url": "https://myshop.com?pid=payment_11gJxYm...",
    "customer_cancel_url": "https://myshop.com/cart?pid=payment_11gJxYm...",
    "purchase_amount": 10000,
    "customer_fee": 0,
    "payment_plan": [
      {
          "customer_fee": 0,
          "due_date": 1547562399,
          "purchase_amount": 3333,
          "state": "paid"
      },
      {
          "customer_fee": 0,
          "due_date": 1550240799,
          "purchase_amount": 3333,
          "state": "pending"
      },
      {
          "customer_fee": 0,
          "due_date": 1552659999,
          "purchase_amount": 3333,
          "state": "pending"
      }
    ],
    "custom_data": { ... },
    "customer": { ... },
    "shipping_address": { ... },
    "billing_address": { ... }
  }

Intégration dans le tunnel d'achat

L'intégration d'Alma à un site marchand se passe en plusieurs étapes :

  • Vérification de l'éligibilité de la commande au paiement en plusieurs fois
  • Création du paiement chez Alma pour la commande en cours
  • Redirection vers la page de paiement
  • Vérification du paiement lors du retour depuis la page de paiement

Le diagramme de séquence ci-dessous montre les interactions qui prennent place pour ces différentes étapes, qui sont détaillées ci-après, avec le détails des appels API pertinents.

Éligibilité du paiement

Cette étape, bien que facultative, est fortement recommandée car elle permet de ne présenter le bouton de paiement en plusieurs fois que lorsqu'il est effectivement possible de proposer ce mode de paiement. Cela évitera notamment des frustrations aux clients, et donc potentiellement une perte de conversions.

Les cas de non-éligibilité sont :

  • Un problème avec le compte marchand (compte non activé, pièces manquantes, …)
  • Un montant inférieur/supérieur au minimum/maximum autorisé pour le paiement en plusieurs fois (contractualisé avec le marchand)
  • Une forte suspicion de fraude

L'appel à effectuer à l'API est décrit dans la référence de l'API à la section Vérifier l'éligibilité d'un achat.

Dans la plupart des cas, les contraintes renvoyées avec la réponse permettent d'identifier la raison de la non-éligibilité, et de l'indiquer au client. Les codes d'erreur pour les différents champs sont donnés à titre indicatif ; pour des raisons de sécurité, Alma déconseille d'en afficher les valeurs au client final, ou d'adapter vos messages d'erreur en fonction de ces codes.

Création du paiement

Lorsque vous affichez un bouton de paiement en plusieurs fois et que l'utilisateur clique dessus, vous devez dans un premier temps créer un objet paiement via notre API, qui contiendra les informations de la commande et du client.

Si cet objet paiement est correctement créé vous pourrez alors exécuter l'étape suivante. Dans le cas contraire et en fonction de l'erreur rencontrée, vous devrez inviter l'utilisateur :

  • Soit à corriger ses informations
  • Soit à choisir un autre mode de paiement

Consulter la section Créer un Payment de la référence de l'API pour les détails de l'appel API à effectuer.

Redirection vers la page de paiement

Description

Dès que le paiement est créé (i.e. dans la même requête HTTP initiée par le clic sur le bouton de paiement), utilisez le champ url du JSON renvoyé par l'appel à l'API précédent pour renvoyer votre client vers notre page de paiement.

L'implémentation dépend du langage, du framework ou de la plateforme utilisés côté backend.

L'important est que la réponse finale au clic sur le bouton de paiement soit :

Code HTTP302
Location (header)<payment.url>
ExempleLocation: https://pay[.sandbox].getalma.eu/payment_11gJxYm2LM9Gt9VyWOaY4kWQ4eC4r2sHpU

Validation du paiement

Afin de s'assurer qu'il n'y a aucune tentative de fraude, il convient de vérifier que le montant total payé et le montant du panier en cours sur votre boutique correspondent bien avant de valider la commande définitivement.

À cette fin, en plus de rediriger le client vers une URL spécifique de votre site, Alma transmet à vos serveurs l'ID du paiement validé une fois la carte bancaire du client débitée.

La suite détaille ces deux retours (redirection client et callback IPN) et la réponse à y apporter

Webhook / Callback IPN

Appel asynchrone

Si une URL de callback IPN a été fournie (configurée dans la dashboard ou dans les attributs du paiement), elle sera appelé de façon asynchrone juste après l'exécution du paiement par notre API :

MéthodeGET
URL<ipn_callback_url>?pid=<pid>

L'ID du paiement est ajouté aux paramètres de l'URL afin que vous puissiez faire les vérifications nécessaires de votre côté.

Réponse au callback

Votre serveur doit répondre à l'appel du callback IPN selon deux cas de figure :

  1. Le paiement est valide (voir plus bas) et la commande est confirmée, ou bien la commande existe déjà pour ce paiement : renvoyez un code HTTP 200 en réponse
  2. Une erreur est survenue de votre côté : renvoyez un code HTTP d'erreur quelconque (4xx ou 5xx donc).

En cas d'erreur, vous pouvez inclure dans votre réponse un objet JSON décrivant le problème.

Par exemple :

{
  "error": "Database connection error"
}

Nouvelles tentatives

En cas de problèmes de connectivité (serveur KO, problème réseau, …) ou si votre serveur renvoie à Alma un code d'erreur en réponse à l'appel du callback IPN, notre système planifiera automatiquement une nouvelle tentative d'appel du callback dans les 30 secondes qui suivent.

En cas d'erreurs répétées, Alma réessaye un maximum de 10 fois, avec un délai de plus en plus long entre chaque tentative.

Redirection client

Une fois le paiement exécuté, Alma redirige le client vers votre boutique en utilisant l'URL fournie dans return_url lors de la création du paiement :

MéthodeGET
URL<return_url>?pid=<pid>

Comment valider le paiement ?

L'appel au callback IPN étant asynchrone, Alma vous encourage à procéder à la vérification du paiement également lors de la redirection du client. Cela vous permet de donner une réponse immédiate à votre client.

Il est tout à fait possible de n'afficher qu'un écran de confirmation de commande sans passer par cette validation, mais si le premier appel au callback IPN devait tarder à arriver, vos clients pourraient trouver dans leur compte une commande encore non validée, alors que le paiement a été effectué et qu'ils viennent de voir une page de confirmation.

Valider la commande dès le retour client permet d'éviter cette situation, qui peut être anxiogène pour votre client.

La validation du paiement suit la même cinématique au retour du client et sur le callback IPN, et le code peut donc être partagé :

  • Si la commande est déjà validée : sortir immédiatement et afficher la confirmation de commande (ou renvoyer 200 OK dans le cas du callback IPN)
  • Si la commande n'est pas encore validée : utiliser pid pour valider le paiement avant de continuer (détaillé ci-après)
  • Si la commande est dans un autre état (annulée, par exemple) : informer le client de l'erreur, ou renvoyer 200 OK dans le cas du callback IPN (pour éviter de nouvelles tentatives inutiles)

Que ce soit au niveau du callback IPN ou au retour du client, il est recommandé d'utiliser le paramètre pid pour récupérer l'objet Payment et procéder aux vérifications suivantes :

  • payment.state — vérifiez que la valeur soit bien "in_progress" ou "paid" (dans le cas où le client a finalement payé en une seule fois via Alma)
  • payment.purchase_amount — vérifiez que cette valeur corresponde à la valeur du panier (convertie en centimes). Si ce n'est pas le cas, vous êtes très probablement face à une tentative de fraude.

Notez que le webhook envoyé par Alma n'est pas signé, la méthode proposée ci-dessus est la seule manière disponible de vérifier que le webhook a bien été envoyé par Alma.

Remboursement

End-point

Notre end-point Créer un Remboursement vous permet de réaliser les remboursements totaux ou partiels désirés.

Nous nous chargeons de recalculer l'échéancier et procéder aux annulations et remboursements éventuellement nécessaires.

📘

Lors de l'utilisation du reversement par carte virtuelle, le remboursement doit être opéré depuis le partenaire.