Guide d'implémentation technique

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:

Header

Valeur

Authorization

Alma-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 :

Header

Valeur

Content-type

application/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

Client

Un objet client 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 Client.

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

Ces quatre étapes sont détaillées ci-après, avec le détail 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 HTTP

302

Location (header)

<payment.url>

Exemple

Location: https://pay[.sandbox].getalma.eu/payment_11gJxYm2LM9Gt9VyWOaY4kWQ4eC4r2sHpU

Vérification du paiement

Description

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 Alma transmet à vos serveurs l'ID du paiement validé à deux occasions une fois la carte bancaire du client débitée.

Callback IPN (webhook de succès de paiement)

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éthode

GET

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 et la commande est confirmée (ou bien la commande est déjà dans l'état souhaité de votre côté) : 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.

Retour 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éthode

GET

URL

<return_url>?pid=<pid>

Validation du paiement

L'appel au callback IPN étant asynchrone, Alma vous encourage à procéder à la vérification du paiement dès lors que l'URL de retour que vous avez choisie contient le paramètre pid qu'Alma y ajoute.

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.
  • payment.payment_plan[0].state — vérifiez que la valeur soit bien "paid"

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.


Did this page help you?