Taxes
Activez la collecte des taxes, calculez-les et gérez vos immatriculations.
Taxes utilise un tableau de taux et vos immatriculations pour calculer un montant sur chaque
paiement : après son activation, chaque transaction est taxée et enregistrée, avec un objet tax
dans les réponses des paiements et des remboursements. Avant l'activation, ces endpoints permettent
de consulter les taux et d'essayer des calculs.
Mode live uniquement, avec une clé privée
Chaque endpoint /tax exige une clé privée (sk.) ou une clé restreinte avec tax.read ou
tax.write. Une clé de la sandbox est refusée avec
403 This feature is only available in live mode.
Paramètres
https://api.wajub.com/tax/settingscurl https://api.wajub.com/tax/settings \
-H "Authorization: $WAJUB_API_KEY"La configuration est renvoyée dans tax :
enabledbooleanfacultatifinclusivebooleanfacultatiftrue signifie que le montant envoyé contient déjà la taxe. Avec false, la taxe est ajoutée au montant.default_countrystringfacultatiftax_id_typestringfacultatiftax_registration_numberstringfacultatifL'activation des taxes utilise un appel PUT sur le même chemin. Avec enabled: true,
tax_id_type et registration_number deviennent obligatoires dans la même requête. Le format du
numéro est vérifié selon son type.
curl -X PUT https://api.wajub.com/tax/settings \
-H "Authorization: $WAJUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"inclusive": true,
"default_country": "CM",
"tax_id_type": "vat",
"registration_number": "M071812345678A"
}'Le champ de la requête est `registration_number`
Vous écrivez registration_number et lisez tax_registration_number. Les deux noms désignent la
même valeur. Seule la direction change.
Calculer avant de débiter
POST /tax/calculate calcule le coût avec les taxes sans créer de ressource. Utilisez-le pour
afficher le total dans le checkout.
https://api.wajub.com/tax/calculateamountnumberobligatoirecountrystringobligatoire422 : une faute de frappe n'est jamais taxée à 0 %.currencystringfacultatifdéfaut : XAFtax_inclusivebooleanfacultatifdéfaut : falseamount contient déjà la taxe.customer_idstringfacultatifid d'un client. Son exonération et son statut d'autoliquidation sont alors appliqués. Un client qui n'est pas le vôtre répond 404 Customer not found.tax_codestringfacultatifcurl https://api.wajub.com/tax/calculate \
-H "Authorization: $WAJUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 25000,
"currency": "XAF",
"country": "CM",
"customer_id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3"
}'total est le montant à afficher au client et à transmettre dans amount lors de la création du
paiement :
Le XAF n'a pas de décimale : 19,25 % de 25 000 est arrondi à 4 813. La taxe est arrondie à la précision de sa devise : à l'unité pour le XAF, le XOF et les autres devises sans décimale, à trois décimales pour le KWD, le BHD, l'OMR, le JOD et le TND, à deux pour toutes les autres.
L'exonération et l'autoliquidation sont des résultats, pas des erreurs
Lorsque customer_exempt ou reverse_charge vaut true, tax_amount vaut zéro et total est
égal à amount. Ce calcul est correct pour un client professionnel doté d'un identifiant fiscal
vérifié, qui paie depuis un autre pays que votre default_country. Il ne s'agit pas d'un échec de
calcul.
Données de référence
Ces listes en lecture seule sont identiques pour tous les marchands. Aucune n'accepte de cursor.
Les deux listes paginées prennent page, à partir de 1, et per_page, avec 50 par défaut et 100 au
maximum, et ajoutent un objet meta.
| Endpoint | Champ renvoyé | Filtres | Pagination |
|---|---|---|---|
GET /tax/rates | rates | country | Non |
GET /tax/codes | tax_codes | category | Oui |
GET /tax/codes/{code} | tax_code | Sans objet | |
GET /tax/jurisdictions | jurisdictions | country, state, type | Oui |
GET /tax/thresholds | thresholds | country | Non |
GET /tax/rates est la liste la plus courte, avec un taux normal par pays :
Les deux listes paginées portent meta à côté de leur tableau :
{
"code": 200,
"status": "OK",
"tax_codes": [ … ],
"meta": { "total": 124, "per_page": 50, "current_page": 2, "last_page": 3 }
}Le champ jurisdiction_type d'une juridiction vaut country, state, county, city ou
district. is_compound indique si son taux s'ajoute à celui de sa juridiction parente au lieu de
le remplacer.
GET /tax/codes/{code} renvoie un code et tous les taux nationaux associés dans rates. Un seul
appel indique ainsi comment une catégorie de produits est taxée sur tous vos marchés.
Immatriculations
Les pays où vous êtes immatriculé pour collecter les taxes. Ces cinq endpoints suivent la structure habituelle et sont tous limités à votre compte.
| Méthode | Endpoint | Renvoie |
|---|---|---|
GET | /tax/registrations | registrations |
POST | /tax/registrations | registration, 201 |
GET | /tax/registrations/{id} | registration |
PUT | /tax/registrations/{id} | registration |
DELETE | /tax/registrations/{id} | confirmation |
country_codestringobligatoirestate_codestringfacultatiftypestringfacultatifstandard, simplified, ioss, oss.registration_numberstringfacultatifregistered_atdatefacultatifexpires_atdatefacultatifregistered_at.Une nouvelle immatriculation est créée avec status: "active". Il en existe une par pays et par
État : un second POST pour le même country_code et le même state_code, révoquée comprise,
répond 422 sur country_code. Modifiez l'existante avec PUT.
PUT accepte les champs ci-dessus sauf le pays et l'État, plus status, parmi active, expired,
pending ou revoked. Passer active sur une immatriculation révoquée la réactive. DELETE la
passe à revoked ; l'immatriculation reste listée. Un {id} qui n'est pas l'une de vos immatriculations, ou
qui n'est pas un identifiant du tout, répond 404.
Seuils et alertes
De nombreuses juridictions exigent une immatriculation uniquement après le dépassement d'un seuil
de chiffre d'affaires. GET /tax/thresholds les répertorie. GET /tax/thresholds/alerts les compare
à votre propre volume et renvoie les pays où vous approchez ou dépassez déjà le seuil. Un seuil doté
d'un state_code est répertorié, mais jamais signalé comme alerte.
Chaque seuil est mesuré sur sa propre period (calendar_year, rolling_12m ou quarter). Votre
chiffre d'affaires est converti dans la devise du seuil aux taux de la plateforme avant la
comparaison, et le seuil EU additionne vos ventes dans tous les États membres.
curl https://api.wajub.com/tax/thresholds/alerts \
-H "Authorization: $WAJUB_API_KEY"Chaque alerte, sous alerts avec leur nombre dans total, contient :
country_codestringfacultatifEU pour le seuil européen.state_codestringfacultatifnull dans une alerte : un seuil d'État ne peut pas être mesuré.threshold_typestringfacultatifrevenue, ou transaction_count pour un seuil compté en ventes.threshold_amountnumberfacultatifthreshold_currency (un nombre de ventes pour transaction_count).threshold_currencystringfacultatifcurrent_amountnumberfacultatifthreshold_currency, ou votre nombre de ventes taxées.percentagenumberfacultatifcurrent_amount rapporté à threshold_amount, arrondi à une décimale.periodstringfacultatifmeasurablebooleanfacultatiftrue dans une alerte. Sur un seuil pour lequel votre chiffre d'affaires ne peut pas être converti, il vaut false et aucune alerte n'est levée.approachingbooleanfacultatiftrue de 80 % à 100 %.exceededbooleanfacultatiftrue à partir de 100 %.descriptionstringfacultatifIdentifiants fiscaux des clients
Les identifiants fiscaux d'un client se trouvent sous le client, pas sous /tax. Leur ajout lance
une vérification asynchrone. L'identifiant est donc renvoyé avec
verification_status: "pending" et son statut évolue plus tard. Ces routes sont elles aussi réservées
au live, et l'id d'un identifiant fiscal est un UUID.
Des permissions client, pas fiscales
Ces routes se trouvent sous /customers : une clé restreinte a besoin de customer.read pour
lister et de customer.write pour ajouter ou supprimer. Une clé qui ne détient que tax.read ou
tax.write reçoit 403.
| Méthode | Endpoint | Renvoie |
|---|---|---|
GET | /customers/{customer_id}/tax_ids | tax_ids |
POST | /customers/{customer_id}/tax_ids | tax_id, 201 |
DELETE | /customers/{customer_id}/tax_ids/{id} | confirmation |
typestringobligatoirevaluestringobligatoirecountry_codestringobligatoireLa valeur est vérifiée selon le format de son type dans la liste qui sert aussi à vérifier votre
propre numéro d'immatriculation (Configuration les donne).
Ajouter de nouveau le même type et le même numéro ne crée pas de copie : l'appel répond 200 avec
l'entrée existante, repassée à pending le temps d'une nouvelle vérification. C'est ainsi que l'on
relance une vérification unavailable. DELETE répond 404 pour un {id} qui n'est pas l'un des
identifiants fiscaux du client, y compris un identifiant mal formé.
Les identifiants fiscaux modifient le calcul
Un identifiant fiscal vérifié permet à reverse_charge de renvoyer true depuis
POST /tax/calculate, pour un client professionnel qui paie depuis un autre pays que votre
default_country. Il ne rend jamais un client exonéré. Ajoutez l'identifiant avant le calcul, pas
après.
Rapports
GET /tax/reports agrège les taxes collectées sur une période. Il accepte period, avec une valeur
parmi 7d, 30d, 90d, month, year ou custom. Pour custom, ajoutez start_date et
end_date. Les filtres currency et country sont facultatifs. Le résultat est renvoyé dans
report.