Aller au contenu

Factures récurrentes

Ce que configure l'indicateur de récurrence, ce qui génère la facture suivante et ce qui ne le fait pas.

Une facture récurrente n'est pas un abonnement. C'est une facture classique marquée comme modèle : Wajub la copie dans un nouveau document à chaque cycle, pendant la nuit. Chaque copie doit encore être ouverte au paiement et réglée par le client. Rien n'est débité automatiquement, car aucune donnée réutilisable pour un débit n'est enregistrée.

Marquer une facture comme récurrente

Il n'existe ni endpoint distinct ni ressource d'abonnement. Deux champs de l'appel de création classique couvrent toute la fonctionnalité.

POSThttps://api.wajub.com/invoices
is_recurringbooleanfacultatifdéfaut : false
Marque cette facture comme celle que Wajub copie à chaque cycle. La première copie est due un intervalle après invoice_date. Seule une facture peut être récurrente : sur un devis ou une estimation, true répond 422.
recurring_intervalenumfacultatif
daily, weekly, monthly, quarterly ou yearly. Intervalle entre les copies.
recurring_frequencyenumfacultatif
Accepté à la création comme autre nom de recurring_interval, avec les cinq mêmes valeurs.
customer_idstringfacultatif
Obligatoire ici. Une facture récurrente sans fiche client ne génère jamais rien.

Tout le reste de la facture, notamment les lignes, les totaux et les notes, fonctionne exactement comme sur une facture ponctuelle.

curl https://api.wajub.com/invoices \
  -H "Authorization: sk.xxxxxxxxxxxxxxxx…" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cus_7Kq2mX9vL4tRb3nP8sZcWd1e",
    "customer_name": "Amina Traoré",
    "invoice_date": "2026-09-11",
    "currency": "XAF",
    "items": [
      { "name": "Retainer", "quantity": 1, "unit_price": 250000 }
    ],
    "is_recurring": true,
    "recurring_interval": "monthly"
  }'

La réponse est la même que pour toute autre facture, avec 201 Created, status: "draft", les deux champs de récurrence et rien de plus.

Réponse · 201 Created, abrégée
{
"invoice": {
"id": "inv_LRQqYvlhrgUOE225KMKU",
"invoice_number": null,
"status": "draft",
"currency": "XAF",
"total": 250000,
"is_recurring": true,
"recurring_interval": "monthly"
}
}

Ce que l'API ne peut pas définir

La récurrence possède d'autres réglages. Aucun n'est disponible dans l'API. Une fin après N occurrences, ou un intervalle de N mois, ne peut pas être défini par l'API.

RéglageRôleEmplacement
Une date de débutPlace la première copie à la date de votre choix, au lieu d'un intervalle après la factureLe formulaire du Dashboard
Une date de finLe dernier jour pour lequel un cycle est généréLe formulaire du Dashboard
Une fin après un nombre de copiesArrête la génération après ce nombre de copiesNon disponible
Un multiple de l'intervalleTous les deux mois, toutes les trois semainesNon disponible

Une date de fin saisie dans le Dashboard est appliquée : le cycle qui tombe ce jour-là est le dernier généré, puis la série s'arrête définitivement. Une récurrence créée par l'API n'a aucune règle de fin : elle court jusqu'à ce que vous l'arrêtiez.

Ce qui est renvoyé et ce qui ne l'est pas

Quatre champs de récurrence reviennent sur l'objet facture.

ChampSur une facture récurrenteSur une copie générée
is_recurringtrue tant que la série court, false une fois arrêtéefalse : une copie ne génère rien
recurring_intervaldaily, weekly, monthly, quarterly ou yearlyCelui du modèle, recopié
next_invoice_dateLa date de la prochaine copie, YYYY-MM-DD. null une fois la série arrêtée ou la facture annulée. Elle reste renseignée tant que la génération est ignorée faute de plan, et après une date de fin jusqu'au passage nocturne suivantnull
recurring_parentnullL'id de la facture récurrente dont elle a été générée

Une copie est donc la facture dont recurring_parent est renseigné. La règle de fin ne figure pas dans la réponse, et GET /invoices n'a pas de filtre de récurrence, contrairement à la liste du Dashboard.

Déroulement d'un cycle

La prochaine date est fixée quand la facture est créée récurrente, ou rendue récurrente par une mise à jour : un intervalle après son invoice_date. Elle n'est jamais fixée dans le passé : une facture antidatée ne produit donc pas les cycles écoulés avant qu'elle soit récurrente. Une mise à jour qui désactive l'indicateur l'efface. Une série désactivée puis réactivée reprend après sa dernière copie : un cycle déjà généré ne l'est jamais deux fois. Une copie ne peut pas devenir récurrente elle-même (422), et le duplicata d'une facture récurrente est un simple brouillon, qui ne se répète que si vous le décidez.

Chaque nuit à 02 h 00 UTC, Wajub génère les copies arrivées à échéance : pour chaque facture marquée comme récurrente, dont la prochaine date est arrivée et qui n'est pas annulée, il vérifie le plan, puis la règle de fin, avant de la copier.

La copie hériteLa copie a en propre
Les lignes, avec leurs quantités, prix et taxesAucun invoice_number avant son envoi, comme tout brouillon
La devise et la remise globale de la factureinvoice_date, définie sur la date du cycle arrivé à échéance
Les notes, les conditions, le pied de page et les instructions de paiementdue_date, trente jours plus tard
Le modèle, la langue et les réglages d'affichageLe bloc client, relu depuis la fiche du client
Les moyens de paiement acceptésis_recurring: false. Une copie est une facture ordinaire et ne génère jamais ses propres copies

La prochaine date de la facture d'origine avance ensuite d'un intervalle, ce qui programme le cycle suivant. Chaque cycle produit exactement une copie.

Trois précisions de calendrier. Une exécution génère tous les cycles arrivés à échéance, pas seulement le dernier. Une série mensuelle, trimestrielle ou annuelle ne saute jamais un mois : un mois après le 31 janvier, c'est le 28 février, et la série continue à partir du 28. Enfin, les dates sont en UTC : un cycle daté du 11 est généré à 02 h 00 UTC le 11.

Deux de ces points méritent votre attention. Le bloc client est repris depuis la fiche actuelle à chaque cycle. Une adresse ou un nom d'entreprise corrigé sur la fiche apparaît donc dans le document suivant sans modifier les précédents. Par ailleurs, due_date est toujours fixée à trente jours après la date de la copie, quelles que soient les conditions de la facture d'origine.

Arrêter une récurrence

Une date de fin, quand le Dashboard en a enregistré une, arrête la série d'elle-même. Sinon, vous l'arrêtez, à tout moment et quel que soit le statut de la facture, payée comprise.

POSThttps://api.wajub.com/invoices/{id}/stop-recurring
Arrêter la série et conserver le document
curl -X POST https://api.wajub.com/invoices/inv_LRQqYvlhrgUOE225KMKU/stop-recurring \
  -H "Authorization: sk.xxxxxxxxxxxxxxxx…"

L'appel ne prend pas de corps. La facture revient avec is_recurring: false et next_invoice_date: null, rien d'autre ne change, et invoice.updated est émis. Aucune copie n'est générée après cet appel, et les copies déjà générées restent telles quelles : chacune est une facture à part entière, à envoyer, annuler ou supprimer comme une autre. Arrêter une série déjà arrêtée répond 200 sans rien changer. Dans le Dashboard, la même action s'appelle Arrêter la récurrence, dans le menu d'actions de la facture.

Appelez-le sur la facture récurrente, pas sur une copie. Une copie n'a pas de série propre : l'appel y répond 400, avec l'identifiant du modèle dans recurring_parent :

Réponse · 400 sur une copie générée
{
"code": 400,
"status": "Bad Request",
"message": "This invoice was generated by a recurring invoice. Stop the series on that one.",
"recurring_parent": "inv_LRQqYvlhrgUOE225KMKU"
}

Deux autres appels touchent la série, et tous deux sont plus restreints. PUT /invoices/{id} avec is_recurring: false l'arrête aussi, mais seulement tant que la facture est un brouillon, puisque seul un brouillon est modifiable. Annuler la facture arrête aussi la génération, et efface next_invoice_date, mais l'annulation est refusée une fois la facture payée.

Coût selon le plan

La récurrence nécessite la fonctionnalité Recurring billing, disponible à partir de Growth.

Le Dashboard refuse d'enregistrer une facture récurrente sans cette fonctionnalité. Sans le plan, la génération est ignorée et le document n'est pas modifié. Après le passage à un plan inférieur, la génération reprend donc automatiquement si le compte revient à un plan supérieur, avec les cycles arrivés à échéance entre-temps. POST /invoices ne vérifie pas le plan. La création d'une facture récurrente par l'API réussit avec tous les plans, mais ne génère simplement rien.

Que pensez-vous de ce contenu ?