Certifier une facture
Cet endpoint certifie une facture en temps réel via l’API ERP. Le SFEC génère la signature, le numéro de certification et le QR code, puis les renvoie dans la réponse.
Authentification : X-API-Key - voir Authentification
OpenAPI / Swagger
Explorateur OpenAPI interactif
Endpoint
URL : POST /api/v1/invoices
Authentification : X-API-Key
POST https://api.sfec.gouv.cg/api/v1/invoices
X-API-Key: YOUR_API_KEY
Content-Type: application/json
Accept: application/jsonParamètres de requête
Identification et statut
| Paramètre | Type | Description | Obligatoire |
|---|---|---|---|
invoice_id | string | Identifiant unique de la facture (ex: INV-2025-12) | ✅ |
invoice_type | string | Type de facture (salesInvoice, creditNote) | ✅ |
taxpayer_niu | string|null | NIU du contribuable (vendeur) — max 20 caractères. Le vendeur est identifié par la clé API. | ❌ |
invoice_subject | string|null | Sujet ou description de la facture | ❌ |
invoice_due_date | string|null | Date d’échéance au format ISO 8601 | ❌ |
reference_invoice_id | string|null | ID de la facture de référence (pour avoirs) | ❌ |
sciet | string|null | Numéro SCiET (identifiant interne SFEC) | ❌ |
Pour créer une facture d’avoir : - Définissez invoice_type à creditNote - Définissez
reference_invoice_id avec le numéro de la facture de vente originale
Informations destinataire
| Paramètre | Type | Description | Obligatoire |
|---|---|---|---|
recipient_type | string | Type du destinataire (business, individual, government, foreign) | ✅ |
recipient_name | string | Nom ou raison sociale du destinataire | Conditionnel |
recipient_niu | string|null | Numéro d’identification fiscale du destinataire | Conditionnel |
recipient_rccm | string|null | Numéro RCCM du destinataire | ❌ |
recipient_address | string|null | Adresse physique complète | Conditionnel |
recipient_phone | string|null | Numéro de téléphone du destinataire | Conditionnel |
recipient_email | string|null | Adresse e-mail du destinataire | Conditionnel |
is_recipient_taxable | boolean | Indique si le destinataire est assujetti à la TVA | ✅ |
Champs conditionnels selon recipient_type : recipient_name est requis pour business,
government et foreign ; recipient_niu pour business et government (16 ou 17 caractères)
; recipient_phone, recipient_email et recipient_address pour government et foreign. Pour
individual, ces champs sont optionnels.
Montants et totaux
Tous les montants sont exprimés en valeur numérique simple, sans devise.
| Paramètre | Type | Description | Obligatoire |
|---|---|---|---|
subtotal | number | Montant hors taxe total | ✅ |
total_tax_t_amount | number | TVA au taux normal [T] (18%) | ✅ |
total_tax_r_amount | number | TVA au taux réduit [R] (5%) | ✅ |
total_exempt_amount | number | Montant total exonéré | ✅ |
total_tax_amount | number | Total de la TVA (total_tax_t_amount + total_tax_r_amount) | ✅ |
discount_amount | number | Escompte — remise globale de la facture, appliquée uniquement sur amount_due | ✅ |
total_line_discount_amount | number | Somme des remises de tous les articles (Σ items[].discount_amount) | ✅ |
additional_cent_tax | number | Taxe additionnelle en centimes | ✅ |
electronic_stamp_duty | number | Timbre fiscal électronique — doit être défini à 0 (voir note ci-dessous) | ✅ |
total_amount | number | Montant global TTC | ✅ |
amount_due | number | Montant total à payer | ✅ |
total_debours | number | Total des débours — voir Débours ci-dessous | ❌ |
Timbre électronique : Après signature du décret, le champ electronic_stamp_duty doit être
défini à 0. Le timbre électronique n’est plus calculé par le contribuable.
discount_amount (Escompte) et total_line_discount_amount (Total Remises) sont deux remises
distinctes, affichées sur deux lignes séparées de la facture. total_line_discount_amount doit
être la somme des remises de tous les articles (Σ items[].discount_amount), pas celle d’un seul
article.
Débours
Un débours est une somme avancée par le vendeur au nom et pour le compte du client, puis refacturée à l’identique (droits d’enregistrement, frais de greffe, etc.). Il est hors champ de TVA — pas exonéré à 0 %, réellement hors assiette — et n’est pas du chiffre d’affaires.
Deux champs portent cette information :
total_debours(number, optionnel) — le cumul, au niveau de la facture, de toutes les lignes de débours.items[].is_debours(boolean, optionnel) — marque une ligne comme débours. Absent oufalsesur une ligne commerciale ordinaire.
total_debours n’est jamais inclus dans amount_due. amount_due reste strictement le montant commercial — biens et services, taxes comprises — quel que soit le montant des débours transmis. Le montant réellement dû par le client est :
net_à_payer = amount_due + total_deboursC’est à votre intégration de calculer cette somme pour l’afficher : elle n’est stockée nulle part telle quelle, et total_debours n’entre pas dans le calcul de la signature de certification.
Taxes additionnelles
Le champ additional_taxes permet de spécifier des taxes additionnelles applicables à la facture. Ce champ est optionnel.
| Paramètre | Type | Description | Obligatoire |
|---|---|---|---|
additional_taxes | array | Liste des taxes additionnelles | ❌ |
Chaque élément de additional_taxes contient :
| Paramètre | Type | Description | Obligatoire |
|---|---|---|---|
tax_code | string | Code de la taxe (ex: "TAR") | ✅ |
tax_label | string|null | Libellé de la taxe (ex: “Taxe sur les activités rémunérées”) | ❌ |
tax_amount | number | Montant de la taxe | ✅ |
tax_rate | number|null | Taux de la taxe (en pourcentage) | ❌ |
Paiement
| Paramètre | Type | Description | Obligatoire |
|---|---|---|---|
currency | string | Code de devise (XAF, USD) | ✅ |
payment_method | string|null | Méthode de paiement (bank_transfer, card, cash, mobile_money, cheque, credit) | ❌ |
payment_reference | string|null | Référence du paiement | ❌ |
payment_date | string|null | Date du paiement au format ISO 8601 | ❌ |
Autres champs optionnels : notes (texte libre).
Champs générés par le SFEC (ne pas envoyer)
Les champs de certification — certification_number, signature, short_signature, identifier, qr_code, certification_date, invoice_number — sont générés automatiquement par le SFEC et renvoyés dans la réponse. Ne les incluez pas dans votre requête.
Articles (items)
Chaque article de la facture doit contenir :
| Paramètre | Type | Description | Obligatoire |
|---|---|---|---|
designation | string | Nom du produit ou service | ✅ |
classification_code | string|null | Code de classification (C01, S01, etc.) | ❌ |
type | string | Type d’article (product, service) | ✅ |
unit_price | number | Prix unitaire hors taxe | ✅ |
quantity | number | Quantité vendue | ✅ |
subtotal | number | Montant HT de l’article, remise ligne déjà déduite | ✅ |
discount_amount | number | Remise appliquée sur cet article | ✅ |
amount_after_discount | number | Montant HT après remise (hors taxe). Si omis, vaut 0 côté serveur — recommandé de le renseigner. | ❌ |
net_amount | number | Montant TTC de la ligne, remise et taxe incluses (subtotal + tax_amount) | ✅ |
tax_rate | string | Taux de TVA applicable (0, 18, etc.) | ✅ |
tax_amount | number | Montant de taxe pour cet article | ✅ |
total_amount | number | Montant TTC de la ligne | ✅ |
is_debours | boolean | Marque la ligne comme débours — voir Débours | ❌ |
Exemple de requête
{
"invoice_id": "INV-2025-12",
"taxpayer_niu": "M25000000561080T",
"invoice_type": "salesInvoice",
"invoice_subject": "Vente matériel informatique",
"invoice_due_date": "2025-02-15T00:00:00Z",
"reference_invoice_id": null,
"sciet": "SFEC-API-001",
"subtotal": 11280,
"total_tax_t_amount": 2030.4,
"total_tax_r_amount": 0,
"total_exempt_amount": 0,
"total_tax_amount": 2030.4,
"discount_amount": 0,
"amount_due": 13310.4,
"total_line_discount_amount": 2000,
"additional_cent_tax": 0,
"electronic_stamp_duty": 0,
"total_amount": 13310.4,
"currency": "XAF",
"recipient_type": "business",
"recipient_name": "Test Buyer Company",
"recipient_niu": "BUYER123456789",
"recipient_rccm": "CG-BZV-2025-B-001",
"recipient_address": "123 Buyer Street, Brazzaville",
"recipient_phone": "+237123456789",
"recipient_email": "contact@buyer.com",
"is_recipient_taxable": true,
"payment_method": "bank_transfer",
"payment_reference": "PAY-2025-001",
"payment_date": "2025-01-15T14:30:00Z",
"notes": "Facture API pour test d'intégration",
"additional_taxes": [
{
"tax_code": "TAR",
"tax_label": "Taxe sur les activités rémunérées",
"tax_amount": 500,
"tax_rate": 2.5
}
],
"items": [
{
"designation": "iPhone 16 Pro",
"classification_code": "C01",
"discount_amount": 1000,
"amount_after_discount": 3320,
"net_amount": 3917.6,
"quantity": 6,
"subtotal": 3320,
"tax_amount": 597.6,
"tax_rate": "18",
"total_amount": 3917.6,
"type": "product",
"unit_price": 720
},
{
"designation": "MacBook Pro M3",
"classification_code": "C01",
"discount_amount": 1000,
"amount_after_discount": 7960,
"net_amount": 9392.8,
"quantity": 6,
"subtotal": 7960,
"tax_amount": 1432.8,
"tax_rate": "18",
"total_amount": 9392.8,
"type": "product",
"unit_price": 1493.33
}
]
}Réponse
Réponse de succès (201 Created)
La réponse contient exactement sept champs, tous des chaînes de caractères, tous systématiquement renseignés.
| Champ | Type | Description |
|---|---|---|
signature | string | Signature de certification : 64 caractères hexadécimaux minuscules |
certification_number | string | Valeur identique à signature |
short_signature | string | Signature courte : les 20 premiers caractères de la signature, en majuscules |
identifier | string | Valeur identique à short_signature |
invoice_number | string | Numéro de facture, repris de l’invoice_id que vous avez transmis |
certification_date | string | Horodatage de la certification, au format RFC 3339 |
qr_code | string | QR code de la facture, en data URI PNG encodé en base64 |
certification_number et identifier ne sont pas des identifiants distincts : ce sont des
alias, respectivement de signature et de short_signature. Il n’existe pas de numéro de
certification au format SFEC-… séparé de la signature. Un seul des deux champs suffit à votre
intégration.
Exemple de réponse
{
"certification_number": "a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90",
"signature": "a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90",
"short_signature": "A1B2C3D4E5F60718293A",
"identifier": "A1B2C3D4E5F60718293A",
"invoice_number": "AV-2026-000042",
"certification_date": "2026-07-28T14:33:35Z",
"qr_code": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAABlBMVEX…"
}Relire la facture ensuite
Les mêmes données sont accessibles ensuite via la consultation des factures, mais sous d’autres noms :
| Réponse de certification | Champ en lecture |
|---|---|
signature, certification_number | certification_signature |
short_signature, identifier | certification_short_signature |
qr_code | certification_qr_code |
certification_date | certification_date |
invoice_number | invoice_number |
La facture est immédiatement consultable par son numéro : GET /api/v1/invoices/{invoice_number}.
Codes d’erreur
| Code | Description |
|---|---|
400 | Corps de requête illisible, échec de validation, ou avoir portant sur une facture qui est elle-même un avoir ou qui n’est pas certifiée |
401 | Clé API absente ou invalide, ou NIU inconnu |
404 | Avoir dont la facture référencée par reference_invoice_id est introuvable |
409 | Numéro de facture déjà utilisé, ou facture référencée disposant déjà d’un avoir |
429 | Quota de requêtes dépassé |
500 | Erreur interne |
Le code 422 n’est pas utilisé par cette API. Les erreurs de validation métier remontent en
400.
Erreurs de validation (400)
Elles ont un corps spécifique, distinct des autres erreurs :
{
"error": "Validation failed",
"errors": [
{
"field": "recipient_name",
"code": "REQUIRED",
"message": "recipient_name is required"
}
],
"warnings": []
}| Champ | Description |
|---|---|
error | Toujours Validation failed |
errors | Liste des erreurs bloquantes, une entrée par champ fautif |
warnings | Avertissements non bloquants, même structure que errors |
Chaque entrée porte un code parmi REQUIRED, INVALID_VALUE, INVALID_FORMAT et INVALID_LENGTH.
Autres erreurs
Toutes les autres erreurs — 401, 404, 409, 429, 500 — utilisent la forme courte, avec la seule clé message :
{
"message": "invoice with the same invoice number already exists"
}Assurez-vous que tous les montants sont cohérents et que les totaux correspondent à la somme des articles avant soumission.
Étape suivante → Consulter les factures