Skip to Content
APICertifier une facture

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

Paramètres de requête

Identification et statut

ParamètreTypeDescriptionObligatoire
invoice_idstringIdentifiant unique de la facture (ex: INV-2025-12)✅
invoice_typestringType de facture (salesInvoice, creditNote)✅
taxpayer_niustring|nullNIU du contribuable (vendeur) — max 20 caractères. Le vendeur est identifié par la clé API.❌
invoice_subjectstring|nullSujet ou description de la facture❌
invoice_due_datestring|nullDate d’échéance au format ISO 8601❌
reference_invoice_idstring|nullID de la facture de référence (pour avoirs)❌
scietstring|nullNumé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ètreTypeDescriptionObligatoire
recipient_typestringType du destinataire (business, individual, government, foreign)✅
recipient_namestringNom ou raison sociale du destinataireConditionnel
recipient_niustring|nullNuméro d’identification fiscale du destinataireConditionnel
recipient_rccmstring|nullNuméro RCCM du destinataire❌
recipient_addressstring|nullAdresse physique complèteConditionnel
recipient_phonestring|nullNuméro de téléphone du destinataireConditionnel
recipient_emailstring|nullAdresse e-mail du destinataireConditionnel
is_recipient_taxablebooleanIndique 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ètreTypeDescriptionObligatoire
subtotalnumberMontant hors taxe total✅
total_tax_t_amountnumberTVA au taux normal [T] (18%)✅
total_tax_r_amountnumberTVA au taux réduit [R] (5%)✅
total_exempt_amountnumberMontant total exonéré✅
total_tax_amountnumberTotal de la TVA (total_tax_t_amount + total_tax_r_amount)✅
discount_amountnumberEscompte — remise globale de la facture, appliquée uniquement sur amount_due✅
total_line_discount_amountnumberSomme des remises de tous les articles (Σ items[].discount_amount)✅
additional_cent_taxnumberTaxe additionnelle en centimes✅
electronic_stamp_dutynumberTimbre fiscal électronique — doit être défini à 0 (voir note ci-dessous)✅
total_amountnumberMontant global TTC✅
amount_duenumberMontant total à payer✅
total_deboursnumberTotal 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 ou false sur 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_debours

C’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ètreTypeDescriptionObligatoire
additional_taxesarrayListe des taxes additionnelles❌

Chaque élément de additional_taxes contient :

ParamètreTypeDescriptionObligatoire
tax_codestringCode de la taxe (ex: "TAR")✅
tax_labelstring|nullLibellé de la taxe (ex: “Taxe sur les activités rémunérées”)❌
tax_amountnumberMontant de la taxe✅
tax_ratenumber|nullTaux de la taxe (en pourcentage)❌

Paiement

ParamètreTypeDescriptionObligatoire
currencystringCode de devise (XAF, USD)✅
payment_methodstring|nullMéthode de paiement (bank_transfer, card, cash, mobile_money, cheque, credit)❌
payment_referencestring|nullRéférence du paiement❌
payment_datestring|nullDate 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ètreTypeDescriptionObligatoire
designationstringNom du produit ou service✅
classification_codestring|nullCode de classification (C01, S01, etc.)❌
typestringType d’article (product, service)✅
unit_pricenumberPrix unitaire hors taxe✅
quantitynumberQuantité vendue✅
subtotalnumberMontant HT de l’article, remise ligne déjà déduite✅
discount_amountnumberRemise appliquée sur cet article✅
amount_after_discountnumberMontant HT après remise (hors taxe). Si omis, vaut 0 côté serveur — recommandé de le renseigner.❌
net_amountnumberMontant TTC de la ligne, remise et taxe incluses (subtotal + tax_amount)✅
tax_ratestringTaux de TVA applicable (0, 18, etc.)✅
tax_amountnumberMontant de taxe pour cet article✅
total_amountnumberMontant TTC de la ligne✅
is_deboursbooleanMarque 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.

ChampTypeDescription
signaturestringSignature de certification : 64 caractères hexadécimaux minuscules
certification_numberstringValeur identique à signature
short_signaturestringSignature courte : les 20 premiers caractères de la signature, en majuscules
identifierstringValeur identique à short_signature
invoice_numberstringNuméro de facture, repris de l’invoice_id que vous avez transmis
certification_datestringHorodatage de la certification, au format RFC 3339
qr_codestringQR 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 certificationChamp en lecture
signature, certification_numbercertification_signature
short_signature, identifiercertification_short_signature
qr_codecertification_qr_code
certification_datecertification_date
invoice_numberinvoice_number

La facture est immédiatement consultable par son numéro : GET /api/v1/invoices/{invoice_number}.


Codes d’erreur

CodeDescription
400Corps 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
401Clé API absente ou invalide, ou NIU inconnu
404Avoir dont la facture référencée par reference_invoice_id est introuvable
409Numéro de facture déjà utilisé, ou facture référencée disposant déjà d’un avoir
429Quota de requêtes dépassé
500Erreur 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": [] }
ChampDescription
errorToujours Validation failed
errorsListe des erreurs bloquantes, une entrée par champ fautif
warningsAvertissements 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