L’API donne accès à tout le paramétrage de l’écran Calcul des taxes : les taxes et leur mode de calcul, les frais et leurs montants par région, les régions fiscales, la région de chaque pays, les exceptions territoriales, la proposition automatique et le testeur d’adresse. Les contrôles sont ceux de l’écran : ce qu’il refuse, l’API le refuse avec le même motif.
Les trois opérations utilisent la session de l’API REST et sont réservées aux comptes administrateurs.
| Opération | Méthode | Résultat |
|---|---|---|
tax_region_configuration |
GET | Paramétrage complet et contrôles de cohérence |
tax_region_preview |
GET | Région d’une adresse, et proposition pour un nouveau document, sans rien enregistrer |
tax_region_configure |
POST | Une modification, validée puis enregistrée en une seule fois |
Le paramètre input est un objet JSON. Les cases à cocher (enabled, active, taxable, documentTest, intravatApproved) attendent un vrai booléen JSON : la chaîne "false" est refusée.
1. Lire le paramétrage #
tax_region_configuration ne prend aucun paramètre.
curl 'https://apps.kafinea.com/YourKafinea/webservice.php?operation=tax_region_configuration&sessionName=YOUR_SESSION_ID'
Clé de result.configuration |
Contenu |
|---|---|
regions |
Identifiant numérique et nom de chaque région fiscale |
taxes |
Chaque taxe des articles (appliesTo: product) et des frais (shipping), inactives comprises : taxId, nom, active, mode de calcul method, type, compoundOn, taux par défaut defaultRate et taux par région ratesByRegionId |
charges |
Chaque frais de l’onglet Frais (& leurs taxes) : chargeId, nom, format, type, montant par défaut defaultValue, montants par région valuesByRegionId, taxable et taxes appliquées taxIds |
countries |
Chaque pays : identifiant, code ISO, région de base, régions professionnelle et particulier, condition professionnelle |
rules |
Les exceptions territoriales, actives ou non, avec leur critère et leur priorité |
enabled, departure_country, operation_kind, organization_ids |
La proposition automatique et son périmètre |
diagnostics |
configurationIssues (pays en double, exceptions qui se chevauchent, région supprimée) et missingRates (taux absents pour une région utilisée) |
Les identifiants de cette réponse sont ceux à renvoyer dans les modifications. Ils diffèrent d’une instance à l’autre : lisez-les sur l’instance visée.
2. Tester une adresse ou un nouveau document #
tax_region_preview reçoit l’adresse dans input : country (code ISO, nom français ou anglais), postcode et state.
curl -G 'https://apps.kafinea.com/YourKafinea/webservice.php' \
--data-urlencode 'operation=tax_region_preview' \
--data-urlencode 'sessionName=YOUR_SESSION_ID' \
--data-urlencode 'input={"country":"France","postcode":"97300"}'
La réponse indique le pays reconnu, la région géographique (geography) et la règle ou le pays qui l’a choisie. Avec documentTest: true, ajoutez les faits du client et de l’opération (partyNature, intravatApproved, vatNumber, organizationId, operation, goodsOrServices, departureCountry, partyRegionId) : la réponse contient alors la région qu’un nouveau document recevrait (document). Aucun fait n’est deviné. vatNumber est le numéro de TVA du client, une chaîne JSON ; un autre type est refusé.
organizationId accepte l’identifiant de la société ou son nom exact (également via organizationName). Une société absente, inconnue ou dont le nom est porté par plusieurs sociétés est signalée dans inputIssues, avec les sociétés configurées.
Quand le contexte de l’opération ne permet pas de proposer une région, document.advisories contient UNSUPPORTED_TAX_CONTEXT et document.advisory_details en précise la cause :
cause |
Signification |
|---|---|
ORGANIZATION_NOT_CONFIGURED |
La société ne fait pas partie des sociétés retenues pour la sélection automatique |
OPERATION_KIND_NOT_SUPPORTED |
L’opération ne porte pas sur des biens |
DEPARTURE_COUNTRY_NOT_CONFIGURED |
Le pays de départ du paramétrage est absent ou non reconnu |
DEPARTURE_COUNTRY_UNKNOWN |
Le pays de départ fourni est absent ou non reconnu |
DEPARTURE_COUNTRY_MISMATCH |
Le pays de départ fourni diffère de celui du paramétrage |
MODULE_NOT_SUPPORTED |
Le document n’est pas un document de vente |
OPERATION_NOT_SALE |
L’opération n’est pas une vente |
Chaque entrée donne aussi la valeur reçue (actual), la valeur attendue (expected) et un message lisible, par exemple : « La société 0 ne fait pas partie des sociétés configurées pour la sélection automatique de la région : 530 (Ma société). »
Pour essayer une modification avant de l’enregistrer, ajoutez configurationPreview : le même objet que celui de tax_region_configure, complété par configurationKind (settings, country ou rule).
3. Modifier le paramétrage #
tax_region_configure reçoit kind et l’objet input complet de la modification.
kind |
Effet | input |
|---|---|---|
region |
Crée, renomme ou supprime une région | {"action":"save","name":"…"} pour créer ; ajoutez region_id pour renommer ; {"action":"delete","region_id":12} pour supprimer |
tax_grid |
Remplace le taux par défaut et les taux par région d’une taxe existante | appliesTo, taxId, defaultRate, ratesByRegionId complet, par exemple {"3":0,"5":20} |
tax |
Crée une taxe, ou redéfinit une taxe existante | appliesTo, name, active, method (Simple, Compound ou Deducted), type (Fixed ou Variable), defaultRate, ratesByRegionId, compoundOn ; taxId pour modifier |
tax_status |
Active ou désactive une taxe | appliesTo, taxId, active |
charge |
Crée un frais, ou redéfinit un frais existant avec ses montants par région | name, format (Flat ou Percent), type, defaultValue, valuesByRegionId, taxable, taxIds ; chargeId pour modifier |
charge_delete |
Supprime un frais | chargeId |
country |
Change la région d’un pays, ou de plusieurs pays à la fois | country_id, mdstaxregionid, mdsprofessionaltaxregionid, mdsindividualtaxregionid, mdsprofessionaltaxcondition (nature_only, qualified_customer ou vat_number) ; ou isocodes avec seulement les champs à changer (voir plus bas) |
rule |
Crée ou modifie une exception territoriale | label, country, criterion_type (postcode_prefix, postcode_range, subdivision), criterion_value, criterion_end pour une plage, priority, active, les trois régions et la condition ; ruleid pour modifier |
settings |
Active ou règle la proposition automatique | enabled, departure_country, operation_kind (goods pour activer), organization_ids |
french_baseline |
Exécute Générer le paramétrage fiscal France | {} |
curl -X POST 'https://apps.kafinea.com/YourKafinea/webservice.php' \
-d 'operation=tax_region_configure' \
-d 'sessionName=YOUR_SESSION_ID' \
-d 'kind=rule' \
--data-urlencode 'input={"label":"Canaries – Las Palmas","country":"ES","criterion_type":"postcode_prefix","criterion_value":"35","priority":50,"active":true,"mdstaxregionid":5,"mdsprofessionaltaxregionid":0,"mdsindividualtaxregionid":0,"mdsprofessionaltaxcondition":"nature_only"}'
Dans cet exemple, 5 est l’identifiant de la région « Hors UE » lu sur l’instance. Une région vaut 0 quand elle n’est pas renseignée. La réponse {"saved":true,"result":{…}} donne l’identifiant créé ou modifié (region_id, ruleid, taxId, chargeId). Relisez ensuite le paramétrage avec tax_region_configuration, puis testez quelques adresses.
Les garanties sont celles de l’écran :
- une modification est enregistrée en entier ou pas du tout ; la création d’une taxe et
french_baselinesont entièrement contrôlées avant d’écrire ; - une région encore utilisée par un pays, une exception, une grille de taux, un article ou un document enregistré est conservée ;
- deux exceptions actives de même priorité qui peuvent viser la même adresse sont refusées ;
- la proposition automatique ne s’active qu’avec un paramétrage sans incohérence ;
- un taux nul est un taux configuré, et une taxe fixe garde une grille vide ;
french_baselinene complète que ce qui manque et ne remplace jamais une région, un taux ou un pays déjà paramétré. Sa réponse liste ce qui a été créé ; rejouée, elle ne crée rien.
Un refus commence par un code stable, par exemple LBL_TAX_REGION_INVALID_RULE, suivi de l’explication affichée par l’écran et, pour un objet incomplet, du champ manquant. Testez le code dans vos programmes et affichez l’explication.
Les régions sont aussi lisibles et modifiables par les opérations CRUD sur le module ci-dessous, avec les mêmes contrôles :
elementType=MdsTaxRegion champ : name
La condition vat_number accorde la région professionnelle à un client professionnel dont la fiche porte un numéro de TVA d’un autre pays que le pays de départ : seuls la présence d’un chiffre et le préfixe de deux lettres comptent, EL désigne la Grèce, un numéro sans préfixe est accepté. La case Exonération intracommunautaire autorisée cochée sur la fiche (mdsintravatapproved) remplit aussi la condition. Sinon, la région de base s’applique avec l’avis VAT_NUMBER_MISSING.
Plusieurs pays à la fois. Avec isocodes (de 1 à 300 codes ISO de la liste des pays) au lieu de country_id, seuls les champs envoyés sont écrits, sur chaque pays de la liste : chaque pays garde ses autres champs, si bien qu’un pays réglé à part n’est pas aligné sur ses voisins au-delà de ces champs. La région professionnelle s’envoie toujours avec sa condition. Tous les pays sont écrits, ou aucun ; la réponse les liste dans result.isocodes et l’historique garde une ligne par pays. Placé dans configurationPreview, le même objet se teste avec tax_region_preview avant d’être enregistré.
curl -X POST 'https://apps.kafinea.com/YourKafinea/webservice.php' \
-d 'operation=tax_region_configure' \
-d 'sessionName=YOUR_SESSION_ID' \
-d 'kind=country' \
--data-urlencode 'input={"isocodes":["BE","DE","IT"],"mdsprofessionaltaxregionid":6,"mdsprofessionaltaxcondition":"vat_number"}'
La région d’un pays se modifie de préférence avec kind: "country" : seule cette opération règle aussi les régions professionnelle et particulier. Les opérations génériques sur le module des pays appliquent les mêmes garanties :
elementType=MdsTaxCountry champs : countryname, isocode, mdstaxregionid, taxzone
updateetrevisepeuvent changermdstaxregionid: la région choisie est contrôlée comme sur l’écran, et les régions professionnelle et particulier déjà réglées sont conservées ;- le code ISO d’un pays ne change pas (
LBL_TAX_COUNTRY_ISO_IMMUTABLE) ; la casse et les espaces sont tolérés ; createn’accepte qu’un code ISO existant et absent de la liste (LBL_TAX_COUNTRY_ISO_UNKNOWN,LBL_TAX_COUNTRY_ISO_DUPLICATE) ;deleteest refusé (LBL_TAX_COUNTRY_DELETE_REFUSED) : videz plutôt la correspondance du pays.
Les taxes (Tax) et les taxes des articles (ProductTaxes) restent lisibles par retrieve et query, mais leurs opérations génériques d’écriture sont refusées (LBL_TAX_GENERIC_WRITE_REFUSED, LBL_PRODUCT_TAXES_GENERIC_WRITE_REFUSED) : une taxe se crée et se modifie avec kind: "tax", tax_grid ou tax_status. La mise à jour d’un produit ou d’un service par l’API ne touche à ses catégories de taxe que si elle envoie des champs de taxe (tax1, tax2…) : les champs envoyés avec une valeur deviennent alors l’ensemble de ses catégories, et un champ envoyé vide retire la catégorie correspondante. Sans champ de taxe, les catégories restent telles quelles.
Créer une taxe #
Une taxe se crée avec kind: "tax" sans taxId. Ses règles sont celles du formulaire Ajouter une taxe :
- le nom est unique parmi les taxes de même portée, inactives comprises ;
- le mode de calcul se choisit à la création et ne change plus ; pour en changer, créez une autre taxe et désactivez l’ancienne ;
- une taxe composée (
Compound) s’applique sur d’autres taxes simples actives, listées danscompoundOn; - une taxe déduite (
Deducted) ne concerne que les articles et reste fixe ; - seule une taxe variable (
Variable) reçoit des taux par région.
curl -X POST 'https://apps.kafinea.com/YourKafinea/webservice.php' \
-d 'operation=tax_region_configure' \
-d 'sessionName=YOUR_SESSION_ID' \
-d 'kind=tax' \
--data-urlencode 'input={"appliesTo":"product","name":"Éco-participation","active":true,"method":"Simple","type":"Fixed","defaultRate":0.5,"ratesByRegionId":{},"compoundOn":[]}'
La création ajoute une colonne aux lignes des documents : une taxe ne se supprime pas, elle se désactive avec kind: "tax_status". Tous les contrôles ont lieu avant cette création. Cochez ensuite la nouvelle taxe sur les produits et services concernés.
Régler les frais par région #
Un frais variable reçoit un montant par région dans valuesByRegionId, par exemple {"3":15,"5":0}. Le montant Flat est exprimé dans la devise de base ; un frais Percent reste compris entre 0 et 100. Un frais taxable liste les taxes de frais actives dans taxIds.
Comme dans l’écran, kind: "charge_delete" retire un frais des nouveaux documents ; les documents enregistrés gardent leurs montants. Donnez un autre nom à un nouveau frais. Rejouée, la suppression répond alreadyDeleted: true.
4. Avec le serveur MCP et l’Assistant #
Le serveur MCP et l’Assistant Kafinea utilisent ces mêmes opérations, sous leurs contrôles de modification des données. Une modification du paramétrage ne recalcule pas les documents déjà enregistrés.
5. Région fiscale d’un document enregistré par l’API #
Les opérations create, update et revise des devis, commandes, factures et avoirs lisent le champ region_id ainsi :
region_id envoyé |
Création | Modification avec LineItems |
Modification sans LineItems |
|---|---|---|---|
| absent | région proposée, ou région par défaut du client, sinon aucune | inchangée | inchangée |
null |
comme absent | région retirée | refusée si elle diffère de la région enregistrée |
"" ou 0 |
absence explicite de région | absence explicite | refusée si elle diffère de la région enregistrée |
| identifiant de région | cette région | cette région | refusée si elle diffère de la région enregistrée |
| autre valeur | refusée (INVALID_ID_ATTRIBUTE), rien n’est enregistré |
refusée | refusée |
Le taux de chaque ligne dépend de la région : une région ne change qu’avec les lignes. Une modification sans LineItems qui change la région est refusée (MANDATORY_FIELDS_MISSING). Renvoyer la région déjà enregistrée, par exemple après un retrieve, reste accepté ; null et 0 y sont équivalents.
Chaque document garde sa propre région : la région d’un document n’est jamais reprise par le document enregistré juste après dans le même traitement.