Des formulaires de paiement sur son site Django avec Paymill

Friends, Fun, and Finally...a Waterfall

Dans le cadre de la création de DontForgetGrandma.com, un programmeur d'alertes par sms, j'ai testé l'intégration de formulaires de paiement avec Paymill.

J'ai déjà écrit récemment une introduction aux paiements sur le web, en quoi consiste Paymill et les différences entre les différentes solutions alternatives. Pour les paresseux et les gens pressés, rappelons que Paymill est une alternative à Paypal en ce sens qu'il s'agit d'un service qui vous permet de recevoir des paiements sur le web, à la différence que la saisie des informations de paiements ne se fait pas sur un site tiers, mais bel et bien sur le votre, dans la lignée de ce que propose Stripe outre-Atlantique.

L'avantage de Paymill est d'être disponible dans la plupart (tous ?) des pays européens, et d'offrir un support en allemand, anglais et français. D'ailleurs, si la maison mère se trouve à Munich, des bureaux ont ouvert à Londres et Paris (si je ne me trompe pas).

Premier contact

Parmi les fonctionnalités proposées par Paymill, on trouvera :

  • la mise à disposition d'une API, avec des librairies disponibles dans plusieurs langages ;
  • différents plugins pour intégrer Paymill dans différents cms et logiciels de gestion de e-boutiques ;
  • la possibilité d'intégrer facilement et rapidement des formulaires de paiement directement sur son site.

C'est bien sûr cette dernière option qui va nous intéresser. Au premier abord, le site de Paymill est plutôt bien foutu, même s'il pratique allègrement le tutoiement, ce que je trouve assez déroutant. Par contre, on sent trés fort que les traductions sont faites à l'arrache.

Le gros point positif, c'est qu'il est possible de commencer l'intégration dés la création du compte, qui ne nécessite rien de plus que les traditionnels email / mot de passe. Paymill vous communique alors des identifiants qui vous permettent de passer des transactions dans un environnement de test similaire en tout point à celui de production (sauf qu'aucune carte n'est débitée, ce qui est quand même mieux). Ceux qui ont déjà pleuré pour utiliser la sandbox Paypal apprécieront. Une fois l'intégration terminée, l'obtention d'un compte de production nécessite quelques étapes supplémentaires, mais nous y reviondront.

La documentation, quand à elle, est claire, complète et utile. Bon point.

Workflow de paiement

Recevoir un paiement va mettre en œuvre les interactions suivantes :

  1. Sur mon site, mon client rentre ses identifiants de CB.
  2. Ces données sont envoyées en ajax directement chez Paymill.
  3. Si la transaction est valide, Paymill retourne une clé qui identifie la requête de manière unique.
  4. Cette clé est insérée dans le formulaire, qui est alors posté de la manière classique.
  5. Notez que les informations de paiement sont retirées du formulaire, et ne transitent pas vers notre serveur.
  6. Côté Django, je récupère le fameux Token, et l'utilise pour confirmer la transaction via l'API de Paymill. La CB est alors débitée.

Premier formulaire de paiment

Commençons par définir notre formulaire de paiment, dans le html le plus basique qui soit.

{{ _('Credit card number:') }}




{{ _('Holder name:') }}




{{ _('Validation code:') }}




{{ _('Expiration date (MM/YYYY):') }}

Remarquez une chose essentielle : les champs n'ont pas d'attribut « name ». Ainsi, ces données ne seront jamais postées vers votre serveur.

Nous avons notre formulaire, reste à définir les traitements javascript.

    // Configuration de notre clé publique Paymill
    var PAYMILL_PUBLIC_KEY = '{{ PAYMILL_PUBLIC_KEY }}';




$(document).ready(function() {
    var payment_form = $('#payment-form');
    var submit_button = $('#submit-btn');

    payment_form.submit(function(e) {
        e.preventDefault();

        paymill.createToken({
            number: $('.card-number').val(),
            exp_month: $('.card-expiry-month').val(),
            exp_year: $('.card-expiry-year').val(),
            cvc: $('.card-cvc').val(),
            cardholder: $('.card-holdername').val(),
            currency: 'EUR',
            amount_int: '1',
            }, PaymillResponseHandler);
    });

    function PaymillResponseHandler(error, result) {
        if (error) {
            // Affiche l'erreur quelque part
        } else {
            var token = result.token;
            payment_form.append("");
            payment_form.get(0).submit();
        }
    }
});

Limpide, n'est-ce pas ? Notez que la librairie Js de Paymill permet de valider les différentes informations avant de soumettre les données à leur serveur.

Débiter la carte bleue

Si vous avez tout suivi, vous avez donc noté que nous envoyons une requête POST vers notre vue qui contient un paramètre « paymillToken ». Notez qu'à ce niveau là, la transaction est enregistrée par Paymill, mais la carte n'est pas encore débitée. Ce sera l'étape suivante.

# views.py
import pymill


@render_to('payment_form.html')
def payment_form(request):
    if request.method == 'POST':
        token = request.POST.get('paymillToken')
        py = pymill.Pymill(settings.PAYMILL_PRIVATE_KEY)
        py.transact(amount=1000, currency="eur", token=token)

        # Message de succès, redirection, etc.

Nous aurions pu aller plus loin, et utiliser l'API pour créer un client, gérer des abonnements, demander un remboursement, etc.

Ah, au fait, il n'y a pas encore de packet pypi pour pymill, donc on l'installe directement depuis Github, ce qui j'en conviens n'est certainement pas l'idée du siècle :

pip install -e git+https://github.com/kliment/pymill.git#egg=pymill

Passer en production

Alors ça-y-est ! Notre site est prêt, nos tests sont concluants, il est temps de passer en production. Côté Paymill, cela signifie qu'il va falloir activer votre compte pour passer du mode test au mode live. C'est là que nous abordons à mon avis le gros, gros point noir du service.

En théorie, il s'agit d'un processus simple : quelques formulaires à remplir, quelques informations officielles à communiquer, on attend la validation, et voilà ! Sauf qu'au lieu du simple formulaire qu'il aurait pu être, le processus s'est transformé en véritable procédure administrative légèrement kafkaïenne sur les bords.

D'abord, le processus n'est pas que virtuel. À l'issue de la validation des différents formulaires, il faudra imprimer des pdfs générés à la volée, les signer, leur adjoindre quelques documents et envoyer tout ça par courrier ! En allemagne, qui plus est ! Admettons.

Mais attendez. On vous demandera une copie de pièce d'identité valide en regard de la loi allemande, ce qui signifie apparemment qu'elle doit être signée *et* tamponnée par un bureau de poste ou une banque ! Avez-vous déjà vu la tête d'une postière quand vous lui demandez de signer une copie de votre passeport ? Moi oui… Et il m'a fallu tester deux ou trois banques avant de tomber sur un guichetier sympa qui a accepté de donner un coup de tampon sur ma photocopie.

De plus, certains éléments du formulaire ne sont pas ou mal traduits. Par exemple, à la question « quelle est le statut de votre entreprise ? », les éléments de réponse sont… en allemand (mais apparaissent en français dans le pdf) ! J'ai été réduit à en tester plusieurs successivement jusqu'à tomber sur le bon.

Dans le pdf généré, certaines informations ne se trouvent pas à la bonne place, rendant le document caduque d'entrée si vos adresses pro et perso sont différentes. Suite à ces problèmes, j'ai été contacté par différentes personnes (fort courtoises et réactives au demeurant), de Paris et Berlin, qui n'avaient pas forcément toutes les mêmes infos.

Bref, c'est quand même beaucoup de b**el pour rien. Et le pire du pire, c'est qu'il ne suffit pas de passer l'étape une fois pour toute. L'utilisation de Paymill sur *chaque* nouveau site nécessitera l'ouverture et l'activation d'un nouveau compte. Autant pour la mise en production rapide de MVPs.

Un support au top !

J'imagine que ce fonctionnement un peu brut est du à la jeunesse du service (quelques mois à peine) et que tout ça sera dégrossi au fur et à mesure. En revanche, j'ai pu tester plusieurs fois la réactivité du support client, et je suis bien obligé de dire qu'il est excellent. Que ce soit par mail ou téléphone, j'ai toujours eu une réponse quasi-immédiate à mes questions, et j'ai même été rappelé plusieurs fois par quelqu'un qui voulait simplement vérifier que mes problèmes étaient bien résolus. C'est plutôt rare, et trés appréciable.

Qu'en est-il de la régularité des paiements, de la fiabilité du système, etc. ? Je ne peux pas encore le dire, mais ça ne tient qu'à vous.

En conclusion, l'expérience est plutôt positive. Paymill comble un réel manque, et c'est un outil vraiment utile pour un dev web, rien que pour la possibilité de ne plus jamais à avoir à utiliser Paypal. Même si le service est jeune et un peu brut de décoffrage, leur évolution me paraît aller dans le bon sens. White and sea.

Edit le 5 juillet 2013. Suite à la parution de cet article, j'ai été contacté directement par Paymill. On m'a fait remarquer plusieurs choses :

  1. L'obligation de faire tamponner la copie de sa pièce d'identité n'existe plus aujourd'hui. Alleluia !
  2. Rocket Internet n'est plus le seul investisseur, d'autres tours de tables ayant été réalisés depuis.
  3. Mes retours seraient pris en compte :)

C'est pas la classe ?