Authentification, signature et portées
Envoyez du JSON à POST /api/integrations/commerce/v1/events/ avec Authorization: Bearer <your scoped API key>. schemaVersion 1 accepte les anciens montants décimaux ; 2 utilise des unités mineures entières et est recommandé. Séparez clés par connexion et environnement ; aucun identifiant dans une URL.
Pour une livraison signée, utilisez POST /api/integrations/commerce/webhooks/{connectionId}/, x-meshdex-timestamp en secondes Unix et x-meshdex-signature avec v1= suivi du HMAC-SHA256 hexadécimal de timestamp, point et corps JSON brut, avec le secret de connexion. Tolérance de cinq minutes. Signez les octets exacts envoyés sans reformater ensuite.
Connexion active et portée correspondante requises : commerce.events:write pour écrire, commerce.events:read pour le statut, commerce.orders:read, commerce.catalog:read, commerce.availability:read et commerce.reconciliation:read. Minimisez les portées. Correspondances et application historique exigent une administration autorisée.
202 signifie mis en file, pas comptabilisé. Conservez l’identifiant. GET /api/integrations/commerce/v1/events/{eventId}/ renvoie statut, erreur et résultat ; l’identifiant source est aussi accepté. GET /api/integrations/commerce/v1/orders/?orderId=your-source-invoice-id renvoie les liens comptables et stock. GET /api/integrations/commerce/v1/reconciliation/ est paginé : passez nextCursor dans after.
Configuration automatique des services SaaS
GET /api/integrations/commerce/v1/connector-setup/ découvre devise Ledger et taux approuvés avec commerce.catalog:read. La réponse indique routages manquants et portées nécessaires.
Avec commerce.catalog:write, envoyez en POST les définitions existantes à la même adresse avec externalProductId et name. La synchronisation crée les correspondances de services sur le compte de produits approuvé, préserve l’existant et soumet les conflits à examen. Prix et devises restent définis par la source pour chaque facture.
Une clé valide peut configurer le catalogue d’une connexion SaaS Brouillon ou Suspendue avant activation. Les événements financiers exigent une connexion Active. Test ne comptabilise ni facture ni paiement.
Pour valoriser une devise, ajoutez currency et date, par exemple ?currency=USD&date=2026-01-01. La réponse donne une référence datée d’une unité de transaction vers la devise réelle Ledger. Approuvez explicitement cette politique, figez les éléments avant la première livraison et réutilisez-les à l’identique. La conversion de règlement reste séparée.
{
"services": [
{
"externalProductId": "example-starter-monthly",
"name": "Example Starter monthly"
},
{
"externalProductId": "example-starter-yearly",
"name": "Example Starter yearly"
}
]
}Montants version 2, taxes et change
Chaque événement fournit externalEventId, eventType, schemaVersion: 2, occurredAt et sourceRevision entier croissant encodé en chaîne. Les identifiants stables distinguent clients, factures, captures, avoirs, remboursements, règlements et retours par connexion. Conservez identité et contenu lors des réessais ; un nouvel événement ne doit pas modifier une capture, un remboursement ou un règlement existant.
Utilisez des unités mineures entières : 100 pour INR/USD/EUR/GBP/AUD/CAD/NZD/SGD/HKD/AED/SAR/CHF et une pour JPY. Autres devises et quantités fractionnaires sont refusées en comptabilité automatique. Quantités entières positives, 200 lignes maximum ; montant et total au plus 2147483647. Le transport est une ligne associée explicite, les remises sont par ligne.
Chaque ligne contient unitPriceMinor, quantity, discountMinor et tax : treatment EXCLUSIVE, INCLUSIVE, EXEMPT ou ZERO_RATED, amountMinor et components avec name, rate et amountMinor. Arrondissez à l’unité mineure, demi vers le haut, et rapprochez exactement. totalMinor égale les lignes remisées taxes incluses. Les prix inclusifs contiennent déjà la taxe. Une taxe positive exige taxRateId approuvé. Une ligne totalement remisée est permise si la facture reste positive.
La GST exige tax.countryCode: IN, HSN/SAC, placeOfSupply et soit IGST, soit CGST et SGST ensemble, sans mélange. Taux et comptes de taxe doivent être actifs et propres à l’espace. La devise ne détermine pas la taxe. Avoirs et remboursements indiquent taxMinor et taxPayableAccountId pour la contrepassation.
Les événements en devise fournissent baseCurrency, exchangeRate positif, exchangeRateSource et exchangeRateDate. Le taux convertit une unité de transaction ou règlement en devise de base Ledger. La trésorerie utilise le taux réel ; les extournes de créance et avoir gardent le taux de facture. Les montants partiels répartissent le solde comptable sans reliquat final. Les écarts exigent des comptes de change ; aucune substitution silencieuse de devise ou taux.
Une source calculant la GST indienne globalement peut déclarer un écart d’une unité CGST/SGST : tax.roundingMethod: AGGREGATE et roundingAdjustmentMinor: 1 ou -1 sur un seul composant. Il faut taux égaux, rapprochement global initial et détails GST normaux. Tout écart supérieur ou sans lien est refusé. Taxe et total de facture restent inchangés.
Exemples physiques, numériques et SaaS
Ces exemples fictifs sont exonérés pour la lisibilité. Remplacez identifiants et prix par vos valeurs et approuvez product-1, service-1 et plan-pro. Choisissez l’autorité Source. Le stock physique exige une correspondance Supply stock approuvée ; numérique et SaaS utilisent des services Ledger seuls.
{
"externalEventId": "example-physical",
"eventType": "invoice.created",
"schemaVersion": 2,
"sourceRevision": "1",
"occurredAt": "2026-10-14T10:00:00Z",
"data": {
"invoiceId": "invoice-physical",
"invoiceNumber": "SOURCE-PHYSICAL",
"invoiceAuthority": "SOURCE",
"documentReference": "https://billing.example.com/invoices/invoice-physical",
"currency": "INR",
"customer": {
"id": "customer-1",
"name": "Example Customer",
"email": "[email protected]",
"billingAddress": {
"countryCode": "IN",
"regionCode": "KA"
}
},
"issueDate": "2026-10-14",
"dueDate": "2026-10-14",
"lines": [
{
"productId": "product-1",
"description": "Example physical product",
"quantity": 2,
"unitPriceMinor": 5000,
"discountMinor": 0,
"tax": {
"treatment": "EXEMPT",
"amountMinor": 0,
"components": []
}
}
],
"totalMinor": 10000
}
}{
"externalEventId": "example-digital",
"eventType": "invoice.created",
"schemaVersion": 2,
"sourceRevision": "1",
"occurredAt": "2026-10-14T10:00:00Z",
"data": {
"invoiceId": "invoice-digital",
"invoiceNumber": "SOURCE-DIGITAL",
"invoiceAuthority": "SOURCE",
"documentReference": "https://billing.example.com/invoices/invoice-digital",
"currency": "INR",
"customer": {
"id": "customer-1",
"name": "Example Customer",
"email": "[email protected]",
"billingAddress": {
"countryCode": "IN",
"regionCode": "KA"
}
},
"issueDate": "2026-10-14",
"dueDate": "2026-10-14",
"lines": [
{
"productId": "service-1",
"description": "Digital service",
"quantity": 1,
"unitPriceMinor": 10000,
"discountMinor": 0,
"tax": {
"treatment": "EXEMPT",
"amountMinor": 0,
"components": []
}
}
],
"totalMinor": 10000
}
}{
"externalEventId": "example-saas",
"eventType": "subscription.renewed",
"schemaVersion": 2,
"sourceRevision": "1",
"occurredAt": "2026-10-14T10:00:00Z",
"data": {
"invoiceId": "invoice-saas",
"invoiceNumber": "SOURCE-SAAS",
"invoiceAuthority": "SOURCE",
"documentReference": "https://billing.example.com/invoices/invoice-saas",
"currency": "INR",
"customer": {
"id": "customer-1",
"name": "Example Customer",
"email": "[email protected]",
"billingAddress": {
"countryCode": "IN",
"regionCode": "KA"
}
},
"issueDate": "2026-10-14",
"dueDate": "2026-10-14",
"lines": [
{
"productId": "plan-pro",
"description": "Monthly SaaS renewal",
"quantity": 1,
"unitPriceMinor": 10000,
"discountMinor": 0,
"tax": {
"treatment": "EXEMPT",
"amountMinor": 0,
"components": []
}
}
],
"totalMinor": 10000,
"subscriptionId": "subscription-1",
"billingPeriod": {
"cycle": "monthly",
"start": "2026-10-14",
"end": "2026-11-14"
}
}
}{
"externalEventId": "example-yearly",
"eventType": "subscription.renewed",
"schemaVersion": 2,
"sourceRevision": "1",
"occurredAt": "2026-10-14T10:00:00Z",
"data": {
"invoiceId": "invoice-yearly",
"invoiceNumber": "SOURCE-YEARLY",
"invoiceAuthority": "SOURCE",
"documentReference": "https://billing.example.com/invoices/invoice-yearly",
"currency": "INR",
"customer": {
"id": "customer-1",
"name": "Example Customer",
"email": "[email protected]",
"billingAddress": {
"countryCode": "IN",
"regionCode": "KA"
}
},
"issueDate": "2026-10-14",
"dueDate": "2026-10-14",
"lines": [
{
"productId": "plan-pro",
"description": "Yearly SaaS renewal",
"quantity": 1,
"unitPriceMinor": 10000,
"discountMinor": 0,
"tax": {
"treatment": "EXEMPT",
"amountMinor": 0,
"components": []
}
}
],
"totalMinor": 10000,
"subscriptionId": "subscription-1",
"billingPeriod": {
"cycle": "yearly",
"start": "2026-10-14",
"end": "2027-10-14"
}
}
}Cycle des factures, abonnements et remboursements
- customer.upserted crée ou synchronise un client propre à la connexion par révisions : nom de facturation, coordonnées, adresse et identité fiscale. Aucun rapprochement automatique avec des clients manuels ou sans lien.
- invoice.created, order.created et subscription.renewed créent des factures. invoice.updated et order.updated appliquent les révisions de brouillon prises en charge. Les anciennes sont ignorées, les conflits examinés. Les factures comptabilisées se corrigent par avoir explicite ou ajustement Ledger contrôlé, jamais par écrasement.
- Envoyez un identifiant de facture distinct par période mensuelle ou annuelle. Transmettez proratas et changements avec montants réels et période ; MeshDex ne calcule ni échéanciers ni droits. Les événements de création, modification et résiliation d’abonnement actualisent les références avec accountingEffect: NONE. Annuler un renouvellement futur ne rembourse ni n’annule une période payée.
- invoice.cancelled et order.cancelled annulent les brouillons impayés et libèrent les réservations non exécutées. Les dossiers comptabilisés, payés ou exécutés nécessitent un avoir, remboursement ou retour explicite.
- payment.captured comprend invoiceId, paymentId, currency, amountMinor et paidAt facultatif. Il enregistre l’encaissement confirmé en banque ou transit. Autorisations et échecs restent des références.
- credit.issued comprend invoiceId, creditId, currency, amountMinor, taxMinor, reason et creditedAt facultatif. Il réduit produits ou créance sans rendre de trésorerie.
- refund.completed comprend invoiceId, refundId, currency, amountMinor, taxMinor, reason et completedAt ; il enregistre remboursement confirmé et avoir associé. Fournissez creditId pour réutiliser un avoir correspondant, utilisable par un seul remboursement identique. Sinon un avoir distinct est créé. Des identifiants répétés ne dupliquent pas les effets. Création et échec de remboursement restent des références.
- Plusieurs remboursements partiels sont possibles dans les limites de trésorerie, avoir et taxe restantes. Les retours utilisent return.received avec orderId, returnId, lines et qualityApproved. Un remboursement ne réintègre pas le stock. Les retours attendent l’inspection ; l’approbation source ne vaut qu’après choix administratif d’une politique de confiance.
Statuts, erreurs et récupération sûre
RECEIVED et PROCESSING indiquent la file ; WAITING_DEPENDENCY un dossier antérieur manquant. COMPLETED signifie traitement terminé ; vérifiez result.accountingEffect car tests et références peuvent terminer avec NONE. REVIEW_REQUIRED demande correction, RETRYABLE_FAILED est temporaire, DEAD_LETTER exige récupération.
400 refuse données, taxes ou événements invalides ; 401 identifiants invalides, expirés ou révoqués ; 403 portée absente ; 409 identité réutilisée avec contenu différent ; 402 capacité ; 429 débit. Réessayez les erreurs temporaires avec temporisation et corps inchangé. Ne répétez pas aveuglément les erreurs de validation.
Une révocation après réception bloque la suite. Signature et notifications ne prouvent aucun mouvement de passerelle : seuls les événements source confirmés le font. Le rapprochement affiche la page courante des factures et les 25 derniers règlements ou litiges ; utilisez les filtres de journaux Ledger pour l’historique.
La configuration gérée exige une vérification administrative avant usage réel. Le produit différé facultatif nécessite approbation comptable et ne planifie ni renouvellement ni remboursement. L’application source reste responsable du calendrier, des droits et de l’exécution de trésorerie.
Guides associés
Demandez les accès à votre administrateur ou contactez le support en précisant la page et un message d’erreur expurgé des données sensibles.