Facturation SaaS au Maroc : encaisser vos abonnements en dirhams et piloter l'accès au service
Facturation SaaS au Maroc : modéliser vos formules, envoyer un lien de paiement en dirhams à chaque échéance, ouvrir ou couper l'accès par les webhooks signés.
La facturation SaaS au Maroc se monte avec un abonnement en dirhams : à chaque échéance, ChariPay envoie à votre client, par e-mail, un lien de paiement qu'il règle par carte sur une page hébergée, avec 3-D Secure ; tant qu'il n'a pas payé, un rappel part chaque jour avec le même lien. Votre logiciel, lui, écoute des webhooks signés pour ouvrir l'accès à chaque paiement réussi et le restreindre quand une échéance reste impayée. Ce guide traduit vos formules en paramètres, décrit l'inscription, la coupure d'accès, les changements de formule, les factures et le cas des clients professionnels qui préfèrent le virement.
La facturation SaaS au Maroc : comment fonctionne l'abonnement
ChariPay est une plateforme de paiement marocaine, un PSP opéré par Chari Money, établissement de paiement agréé par Bank Al-Maghrib. Son module d'abonnements et paiements récurrents couvre le cycle de vie d'une souscription logicielle, du premier paiement à la résiliation.
Le principe tient en quelques règles. À chaque échéance, ChariPay génère un lien de paiement à usage unique et l'envoie à l'adresse e-mail de votre client ; il le règle par carte sur la page de paiement hébergée, avec 3-D Secure, sans qu'aucune donnée de carte ne transite par votre logiciel. Tant que l'échéance n'est pas réglée, un rappel part chaque jour avec le même lien, et aucune nouvelle période ne s'ouvre. Chaque abonnement a un statut lisible — à démarrer, actif, en pause, terminé, annulé — et ses échéances sont calculées sur le fuseau Africa/Casablanca.
Côté devise, tout est en dirhams marocains (MAD) : encaissements, soldes, virements et versements, sans conversion. Les montants de l'API sont en unités majeures (149.90 = 149,90 MAD).
Et Stripe ? Le Maroc ne figure pas dans la liste officielle des pays où Stripe est disponible, publiée sur stripe.com/global et relue le 2 octobre 2026 ; la page annonce que d'autres pays suivront, sans le citer. Une entreprise établie au Maroc ne peut donc pas y ouvrir de compte à son nom. Les contournements et leurs conséquences sont détaillés dans Stripe au Maroc.
Côté coûts : le mode test est gratuit, sans limite de durée et sans engagement. La mise en service coûte 6 000 MAD TTC, réglés une seule fois au passage en production. La commission est un pourcentage par transaction réussie, définie, comme la caution, après étude de votre dossier — nous ne publions pas de commission « à partir de ».
Modéliser vos formules : périodicité, date de départ, date de fin
Une formule commerciale se traduit en quelques paramètres de l'abonnement. Le client est d'abord créé (POST /v1/clients), puis l'abonnement lui est rattaché (POST /v1/subscriptions) avec un montant, une description et une périodicité.
| Votre formule | Paramètre de l'abonnement |
|---|---|
| Mensuelle | frequency: MONTHLY |
| Annuelle | frequency: YEARLY |
| Hebdomadaire ou quotidienne (usages particuliers) | frequency: WEEKLY ou DAILY |
| Date de la première échéance | startDate |
| Engagement à durée fixe (12 mois, une saison) | endDate ; sans endDate, l'abonnement court jusqu'à résiliation |
| Canal d'envoi des liens d'échéance | channels: ["EMAIL"] |
| Votre identifiant d'abonnement et vos attributs | externalId et metadata |
Le montant (amount) est celui de chaque période, en MAD, unités majeures. La description (description, 255 caractères au plus) doit parler au client : « Formule Pro — mensuel » plutôt qu'un code interne, car elle figure sur chaque lien d'échéance qu'il reçoit. Mettez dans metadata — un objet plat de 4 Ko au plus, repris sur chaque lien et chaque webhook — l'identifiant de l'espace client dans votre logiciel (par exemple tenantId) et le nom de la formule : c'est ce qui permettra à votre code de savoir quel compte ouvrir ou couper. L'externalId, unique par compte et par environnement, empêche de créer deux fois le même abonnement si votre serveur rejoue une requête : une création avec un externalId existant renvoie l'abonnement existant.
Les appels complets, champ par champ, sont dans le guide pour intégrer les abonnements par l'API, et la documentation de chaque module dans l'espace développeurs.
Voyez vivre vos formules avant de coder la suite : Commencer en mode test. Trois champs — nom, e-mail professionnel, entreprise —, un lien d'activation reçu par e-mail pour choisir votre mot de passe, puis le portail, où vous créez vous-même votre clé de test après une ré-authentification. En sandbox, créez un abonnement dont la date de début est aujourd'hui : le premier lien est créé immédiatement et renvoyé dans currentCharge ; payez-le avec la carte de test (4918 9141 0719 5005, CVV 123, code 3-D Secure 555) et l'abonnement passe actif. Avec une périodicité quotidienne (DAILY), l'échéance suivante arrive dès le lendemain : vous rejouez un cycle de facturation, et la prolongation d'accès qui va avec, sans attendre un mois. C'est gratuit, sans limite de durée et sans validation à attendre : la vérification de votre entreprise (KYB) ne conditionne que le passage en production.
Inscription, premier paiement et période d'essai
À l'inscription d'un client dans votre logiciel, votre serveur crée sa fiche client puis l'abonnement. Celui-ci reste au statut INCOMPLETE jusqu'au premier paiement : le client reçoit par e-mail le lien de la première échéance et le règle sur la page de paiement hébergée, avec 3-D Secure. Si la date de début est aujourd'hui, ce premier lien est aussi renvoyé dans currentCharge : vous pouvez diriger le client vers son payUrl juste après l'inscription, sans attendre qu'il ouvre l'e-mail. Tant que ce paiement n'a pas réussi, n'ouvrez pas l'accès payant.
L'e-mail du client est indispensable : c'est là que partent le lien de chaque échéance et ses rappels. Collectez donc une adresse vérifiée dès la création du compte dans votre logiciel, et utilisez l'adresse de facturation de l'entreprise plutôt que celle d'un utilisateur qui pourrait partir.
Il n'existe pas de période d'essai gratuite en tant que telle : un démarrage différé, avec un startDate placé à la fin de la période offerte, en tient lieu ; aucun lien n'est envoyé avant cette date. Ce que voit le client entre la souscription et cette date se vérifie en mode test, avant toute annonce sur votre page de tarifs. Une règle simple côté produit : pendant l'offre, votre logiciel donne l'accès ; ensuite, seul un paiement réussi le prolonge.
Ouvrir et couper l'accès au service avec les webhooks
Votre logiciel n'a pas à interroger ChariPay en boucle : les événements signés lui disent quoi faire. Trois événements suffisent à piloter l'accès :
| Événement | Ce qu'il signifie | Action dans votre logiciel |
|---|---|---|
subscription.payment_succeeded | Une échéance a été payée | Prolonger l'accès jusqu'à la fin de la période, émettre la facture |
subscription.payment_failed | Une tentative de paiement par carte a échoué sur le lien de l'échéance ; le lien reste payable | Prévenir le client si besoin ; l'échéance reste à régler |
subscription.canceled | L'échéance est restée impayée au-delà du délai de 14 jours : l'abonnement est annulé automatiquement | Couper l'accès à la fin de la période payée, ou tout de suite selon vos conditions |
subscription.canceled signale l'annulation automatique d'un abonnement dont l'échéance est restée impayée. Quand c'est vous qui annulez — depuis le portail ou par l'API —, n'attendez pas d'événement : la réponse de POST /v1/subscriptions/{reference}/cancel porte déjà le statut CANCELED ; mettez votre système à jour à ce moment-là. Arrivé à sa date de fin, l'abonnement passe à « terminé ».
Pour rattacher un événement de paiement d'abonnement au bon espace client, lisez votre metadata, renvoyé tel quel ; pour les abonnements, et pour eux seulement, le contrat de l'API documente aussi le renvoi de votre externalId et de la date de la période concernée (PeriodDate). Gardez en plus la reference de chaque abonnement, renvoyée à la création : GET /v1/subscriptions/{reference} en relit le statut à tout moment, et une relecture régulière de vos abonnements par GET /v1/subscriptions rattrape un événement manqué.
Trois règles techniques évitent les accès ouverts ou coupés par erreur. Routez sur l'en-tête Chari-Event-Type, pas sur une supposition du contenu. Dédupliquez sur Chari-Event-Id, pas sur Chari-Webhook-Id — ce dernier identifie la livraison, pas l'événement. Et vérifiez la signature (X-CHARI-SIGNATURE, X-CHARI-TIMESTAMP) avant toute action. La logique de rattachement entre un paiement et votre objet métier est détaillée dans relier un paiement à sa commande.
Échéance impayée : décider de votre période de grâce
Quand une échéance n'est pas réglée, les rappels sont automatiques : le client reçoit chaque jour un e-mail avec le même lien ; tant qu'une échéance reste impayée, aucune nouvelle période ne s'ouvre ; le lien reste payable 14 jours après la date d'échéance, puis, sans paiement, l'abonnement est annulé automatiquement.
La décision propre à un SaaS est ce que devient l'accès pendant ce délai. Trois politiques se défendent :
- 1Accès maintenu jusqu'à la fin du délai : le plus doux, adapté aux clients de longue date et aux outils critiques pour leur activité.
- 2Accès restreint — lecture seule, export possible, création bloquée : le client continue de voir ses données et comprend qu'il doit agir.
- 3Accès coupé dès que l'échéance n'est pas réglée à sa date : réservé aux offres à faible engagement, au risque de frustrer un client qui a simplement manqué l'e-mail.
Quelle que soit votre politique, écrivez-la dans vos conditions et affichez-la dans votre logiciel tant qu'une échéance attend son paiement, avec un bouton qui mène au lien de l'échéance (le payUrl de currentCharge). Votre logiciel connaît la date de chaque échéance : c'est l'absence de subscription.payment_succeeded pour cette période qui déclenche votre politique. Le détail du délai, des décisions et des messages types est dans échéance d'abonnement impayée.
Changer de formule : montée, descente, passage à l'annuel
Un abonnement ne change pas de formule en cours de route : pour passer de « Essentiel » à « Pro », de mensuel à annuel, ou pour baisser de gamme, annulez l'abonnement en cours puis créez-en un nouveau sur le même client. Cette annulation est la vôtre : elle prend effet sans échéance supplémentaire, et la réponse de l'appel porte déjà le statut CANCELED — n'attendez pas d'événement. Le nouvel abonnement suit le même cycle : un lien de paiement à sa première échéance, envoyé à l'e-mail de la fiche client ; vérifiez en mode test ce que voit votre client au démarrage de la nouvelle formule.
Il n'y a ni prorata ni coupons : c'est votre logiciel qui fixe la date d'effet. Deux méthodes courantes :
- Changement à la fin de la période payée : le nouvel abonnement démarre avec un
startDateau lendemain de la dernière période réglée, et l'ancien est annulé avant sa prochaine échéance. Personne ne paie deux fois la même période. - Montée en gamme immédiate : vous ouvrez les fonctions supérieures tout de suite et démarrez le nouvel abonnement à la prochaine échéance ; l'écart de la période en cours est un geste commercial que vous décidez.
Le passage à l'annuel suit la même logique : un nouvel abonnement en YEARLY. Pour une interruption temporaire — un client saisonnier, une fermeture annuelle —, préférez la pause : pause, reprise et annulation se font depuis le portail ou par l'API. La pause se pose sur un abonnement actif, et la reprise relance un abonnement en pause. Pendant la pause, aucun lien n'est envoyé ; à la reprise, les périodes écoulées pendant la pause ne sont pas facturées rétroactivement.
Vos factures restent dans votre logiciel
ChariPay encaisse et trace ; il ne produit pas vos factures. Le suivi des transactions et les reçus clients sont inclus, mais la facture, avec votre numérotation et vos mentions, reste l'affaire de votre logiciel. Le schéma à suivre :
- 1À chaque
subscription.payment_succeeded, votre logiciel émet la facture de la période et l'envoie au client. - 2Il note sur la facture la référence de l'abonnement et la période payée.
- 3En cas de doute, il relit l'historique des échéances d'un abonnement par
GET /v1/subscriptions/{reference}/charges.
Pour le rapprochement mensuel, l'export CSV du portail reprend chaque mouvement avec sa référence. Sur ce qu'une facture doit contenir et sur la fiscalité de votre activité, votre conseil reste seul à pouvoir se prononcer.
Clients professionnels : le virement sur votre RIB
Certains clients professionnels préfèrent payer un abonnement annuel par virement. Votre compte ChariPay le permet : c'est un vrai compte de paiement, tenu par Chari Money, établissement de paiement agréé par Bank Al-Maghrib, ouvert au nom de votre entreprise, avec un RIB à ce nom et une attestation PDF à télécharger depuis le portail ou par l'API. Il reçoit vos encaissements et des virements, et sert à vos opérations de paiement.
ChariPay n'est pas une banque : votre compte de paiement est tenu par Chari Money. Il complète votre banque, il ne la remplace pas.
Dans ce cas, ne créez pas d'abonnement ChariPay : émettez la facture annuelle depuis votre logiciel, communiquez le RIB et l'attestation, et ouvrez l'accès quand le virement est reçu sur votre compte de paiement, après l'avoir rapproché de la facture correspondante. Gardez les deux circuits séparés dans votre logiciel, abonnements par lien de paiement d'un côté, virement de l'autre, pour que la coupure automatique à l'impayé ne touche jamais un client qui paie par virement.
Questions fréquentes
Peut-on facturer un abonnement SaaS en dirhams depuis le Maroc ?
Oui. Avec ChariPay, vous créez un abonnement en dirhams : à chaque échéance, votre client reçoit par e-mail un lien de paiement qu'il règle par carte sur la page hébergée, avec 3-D Secure ; tant qu'il n'a pas payé, un rappel part chaque jour avec le même lien. Tout est en MAD, sans conversion, et vous testez le cycle complet en mode test avant la production.
Peut-on proposer une période d'essai gratuite ?
Pas sous la forme d'un essai intégré : un démarrage différé en tient lieu. Vous créez l'abonnement avec un startDate placé à la fin de la période offerte — aucun lien n'est envoyé avant —, et votre logiciel donne l'accès pendant cette période. Vérifiez en mode test ce que voit votre client entre la souscription et la date de départ avant d'annoncer l'offre sur votre page de tarifs, et indiquez clairement la date de départ de l'abonnement payant.
Comment gérer un changement de formule en cours d'abonnement ?
Un abonnement ne change pas de formule : annulez celui en cours et créez-en un nouveau sur le même client. Il n'y a ni prorata ni coupons, donc votre logiciel fixe la date d'effet, par exemple avec un startDate au lendemain de la dernière période payée. Le passage à l'annuel suit la même règle, avec un nouvel abonnement en YEARLY, en veillant à ce que le client ne paie pas deux fois la même période.
ChariPay émet-il les factures de mes clients ?
Non. Le suivi des transactions et les reçus clients sont inclus, mais la facture reste produite par votre logiciel, avec votre numérotation et vos mentions. Émettez-la à chaque subscription.payment_succeeded et relisez au besoin l'historique par GET /v1/subscriptions/{reference}/charges. Notez sur chaque facture la référence de l'abonnement et la période payée. Pour le contenu d'une facture, votre conseil reste seul à pouvoir se prononcer.
Comment couper l'accès d'un client qui ne paie plus ?
Écoutez les webhooks signés. Tant qu'une échéance n'a pas reçu de subscription.payment_succeeded, elle est impayée : appliquez votre période de grâce, accès maintenu, restreint ou coupé. Pendant ce temps, le client reçoit un rappel chaque jour, et le lien reste payable 14 jours après l'échéance ; sans paiement, l'abonnement est annulé automatiquement : à la réception de subscription.canceled, ou à la relecture du statut, fermez l'accès.
Peut-on facturer dans une autre devise que le dirham ?
Non. Tout est en dirhams marocains (MAD) : encaissements, soldes, virements et versements, sans conversion. Le champ currency des réponses vaut toujours MAD, et les montants de l'API sont en unités majeures (149.90 = 149,90 MAD). Affichez donc vos prix en dirhams sur votre page de tarifs, pour que vos clients voient exactement ce qu'ils paieront à chaque échéance.
Un client professionnel peut-il payer par virement plutôt que par carte ?
Oui. Votre compte de paiement ChariPay a un RIB au nom de votre entreprise et reçoit des virements ; l'attestation PDF se télécharge depuis le portail ou par l'API. Émettez la facture depuis votre logiciel, communiquez le RIB, et ouvrez l'accès quand le virement est reçu. Gardez ce client hors du circuit de coupure automatique des abonnements.
Prochaine étape
Ouvrez votre sandbox — Commencer en mode test — et créez un abonnement quotidien (DAILY) qui démarre aujourd'hui : payez le premier lien avec la carte de test, puis celui du lendemain, pour vérifier que chaque échéance payée prolonge l'accès dans votre logiciel. Branchez ensuite votre période de grâce sur les échéances restées sans subscription.payment_succeeded, la coupure d'accès sur subscription.canceled pour l'annulation automatique et sur la réponse de l'appel quand c'est vous qui annulez, puis passez en production. Le guide pour intégrer les abonnements par l'API donne les appels, et la page abonnements et paiements récurrents résume l'offre.
Sources
- Stripe — Global availability — lu le 2026-10-02
Écrit par Équipe ChariPay.