Affectations et rapprochement
Une affectation (bank_allocation) est un lien entre une opération bancaire et une facture : la part du mouvement qui solde cette facture. Une opération peut en porter plusieurs - un virement de 300,00 qui règle deux factures de 200,00 et 100,00 en porte deux - et c'est ce jeu d'affectations qui décide de ce que l'opération produit en comptabilité.
Deux ressources se partagent le sujet, et la frontière entre les deux est à comprendre avant d'écrire la moindre ligne de code :
bank_allocationsbrouillonne. Créer une affectation ne déplace aucun argent.bank_operations/{id}/reconciliationsolde. C'est la transition qui écrit les paiements et recalcule l'écriture comptable.
Le mouvement dont elles dépendent est décrit dans Opérations bancaires, et ce que le rapprochement produit dans les livres dans Écritures comptables bancaires.
La chose à comprendre avant tout le reste
Créer une affectation est un brouillon, et rien d'autre. POST /api/v1/bank_operations/{id}/allocations écrit une ligne proposed : aucun paiement n'est créé, aucune ligne de grand livre n'est touchée, la facture reste impayée, et les montants de reconciliation sur l'opération ne bougent pas - ils ne comptent que les affectations confirmées. C'est délibérément bon marché : vous pouvez construire une ventilation en plusieurs appels, la relire et la corriger sans qu'aucun de ces appels n'engage quoi que ce soit.
Confirmer est une convergence, pas un ajout. POST /api/v1/bank_operations/{id}/reconciliation prend le jeu d'affectations complet que vous voulez voir confirmé, plus la version de l'opération. Le jeu que vous envoyez est le jeu qui sera confirmé :
- une affectation confirmée aujourd'hui et absente du corps est retirée ;
- une affectation présente à un montant différent est retirée puis reconfirmée au nouveau montant ;
- une affectation déjà confirmée au montant demandé n'est pas touchée - renvoyer deux fois le même corps n'écrit donc rien du tout ;
- une facture nommée dans le corps et qui ne porte encore aucune affectation en reçoit une, créée puis confirmée dans le même appel. Vous n'êtes pas obligé de brouillonner d'abord.
Un corps partiel n'est pas une mise à jour partielle. Si vous n'envoyez qu'une des deux affectations d'une ventilation, l'autre est retirée. Et l'appel est tout ou rien : le premier sous-refus fait échouer la transaction entière, donc une ventilation à moitié appliquée n'est pas un état que ce point d'entrée peut produire.
DELETE /api/v1/bank_allocations/{id} ne supprime aucune ligne. Une affectation est une pièce d'audit : cet appel écrit status: "rejected" et vous rend la ligne telle qu'elle est désormais. C'est ce qui permet de distinguer une facture qui n'a jamais été proposée d'une facture proposée puis refusée.
Les endpoints
| Endpoint | Ce qu'il fait | Scope |
|---|---|---|
GET /api/v1/bank_operations/{bank_operation_id}/allocations | Lister les affectations d'une opération | read |
POST /api/v1/bank_operations/{bank_operation_id}/allocations | Brouillonner une affectation | write |
PATCH /api/v1/bank_allocations/{id} | Changer le montant brouillonné, ou retirer l'affectation | write |
DELETE /api/v1/bank_allocations/{id} | Retirer l'affectation (écrit rejected) | destroy ou write |
POST /api/v1/bank_operations/{bank_operation_id}/reconciliation | Confirmer le jeu complet | write |
DELETE /api/v1/bank_operations/{bank_operation_id}/reconciliation | Annuler des confirmations | destroy ou write |
Comme sur les autres ressources bancaires, aucun de ces chemins ne porte de workspace_id : l'identifiant est résolu sur l'ensemble des workspaces rattachés à votre client OAuth. Une opération ou une affectation hors de vos habilitations répond 404, exactement comme une qui n'existe pas.
Les deux créations - POST sur les affectations et POST sur le rapprochement - exigent l'en-tête Idempotency-Key. Les deux DELETE et le PATCH l'acceptent sans l'exiger.
Les champs d'une affectation
Onze champs, tous présents dans chaque réponse.
| Champ | Ce qu'il porte |
|---|---|
bank_operation_id | L'opération sur laquelle l'affectation tire |
invoice_document_id | La facture qu'elle solde. Il n'existe au plus qu'une affectation active par couple (opération, facture) ; une seconde est refusée |
allocated_amount | Le montant affecté, toujours positif ou nul, publié comme un nombre JSON à quatre décimales. Voir ci-dessous |
status | proposed, confirmed, unconfirmed ou rejected. Voir ci-dessous |
score | La confiance du moteur de rapprochement, de 0 à 1 à quatre décimales. Une affectation que vous créez vous-même porte 1.0 |
rejection_reason | wrong_amount, wrong_counterparty, wrong_period ou other, quand l'affectation a été retirée avec un motif. null sinon |
explanation | Pourquoi cette imputation. Voir ci-dessous |
id, company_id, created_at et updated_at complètent la liste.
allocated_amount : un nombre, à quatre décimales
Le sens du mouvement ne se lit pas ici. allocated_amount est une magnitude : une valeur signée est refusée. Le sens vit sur direction de l'opération, et le publier deux fois serait s'exposer à ce que les deux se contredisent.
Quatre décimales, et ce ne sont pas les deux de bank_operation.reconciliation.allocated_amount. Ce sont deux nombres différents et non deux arrondis d'un même : celui de l'opération est ce que les affectations ont comptabilisé, calculé au quantum comptable de deux décimales, tandis que celui-ci est le montant brut que porte l'affectation, à l'échelle de la colonne. C'est sur celui-ci que se mesure le cumul d'une ventilation.
En écriture, c'est une chaîne ou un entier, jamais un flottant JSON. Un double ne peut pas porter quatre décimales sans les altérer, donc 0.30000000000004 est une forme refusée plutôt qu'un arrondi silencieux. C'est la même règle que sur la révision d'un relevé.
"allocated_amount": 200.0
null est possible en lecture sur une ligne ancienne qui n'a nommé aucun montant. Ce n'est pas une forme que cette API peut produire.
status : quatre valeurs, une seule terminale
| Valeur | Ce qu'elle dit |
|---|---|
proposed | Un brouillon - une suggestion du moteur, ou une affectation que vous avez créée. Aucun argent n'a bougé |
confirmed | L'argent a bougé : un paiement existe et la ligne comptable a été réimputée |
unconfirmed | Une confirmation que vous avez annulée. L'affectation reste là et peut être reconfirmée |
rejected | Terminale. L'affectation a été refusée et ne reviendra pas |
rejected est la seule valeur que la ressource bank_allocations écrit. Une confirmation passe par POST /api/v1/bank_operations/{id}/reconciliation, et une affectation déjà décidée ne redescend jamais vers proposed.
unconfirmed n'est pas rejected, et la distinction est le sens même des deux : annuler une confirmation est une décision réversible, la refuser ne l'est pas.
explanation : pourquoi cette imputation
"explanation": {
"source": "allocation",
"rule_id": null,
"rule_name": null,
"reason": "operator allocation of 200.0000 to invoice 90210"
}
Sur cette ressource, source vaut toujours allocation : une affectation d'opérateur l'emporte sur toute règle dans la chaîne de précédence, donc aucune règle n'est nommée et rule_id comme rule_name sont null.
reason est une phrase destinée à un humain et ne doit pas être analysée par programme. Sa formulation n'est pas un contrat.
Brouillonner une affectation
curl -X POST https://app.scribee.tech/api/v1/bank_operations/30144/allocations \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Idempotency-Key: 6f1d4a0e-6a1e-4f3f-9a7d-2f0c9d5b8c41" \
-H "Content-Type: application/json" \
-d '{
"invoice_document_id": 90210,
"allocated_amount": "200.00"
}'
{
"data": {
"id": 7001,
"company_id": 34,
"bank_operation_id": 30144,
"invoice_document_id": 90210,
"allocated_amount": 200.0,
"status": "proposed",
"score": 1.0,
"rejection_reason": null,
"explanation": {
"source": "allocation",
"rule_id": null,
"rule_name": null,
"reason": "operator allocation of 200.0000 to invoice 90210"
},
"created_at": "2026-08-21T14:00:00+02:00",
"updated_at": "2026-08-21T14:00:00+02:00"
}
}
Les deux champs du corps sont obligatoires. La réponse est 201.
La facture doit appartenir à l'entreprise de l'opération, et les mêmes règles métier que l'application applique valent ici :
- un mouvement entrant ne solde qu'une facture de vente, un mouvement sortant qu'une facture d'achat ;
- les devises de la facture et du mouvement doivent être identiques ;
- la facture doit être encore ouverte et payable ;
- l'opération doit être encore affectable :
unmatched,proposedoupartially_matched. Une opérationmatchedn'a plus rien à affecter.
Deux refus distincts portent sur la facture, tous deux sous details.invoice_document. Un corps sans invoice_document_id reçoit le message est obligatoire. Un invoice_document_id qui ne désigne aucune facture de l'entreprise de l'opération reçoit le message est introuvable dans l'entreprise de cette opération : une facture d'une autre entreprise, un identifiant qui n'existe pas, ou une valeur qui n'est ni un nombre entier ni une chaîne - null, un objet, une liste, un booléen. Tous ces cas reçoivent le même refus, délibérément : la réponse ne permet donc pas de sonder l'existence d'un identifiant de facture.
La somme des affectations actives ne peut pas dépasser le mouvement. Les brouillons comptent dans ce plafond autant que les confirmations - seuls les rejets en sont exclus - et le dépassement est refusé par allocation_exceeds_operation :
{
"error": "unprocessable_entity",
"code": "allocation_exceeds_operation",
"message": "La validation a échoué",
"details": {
"base": ["Les affectations de cette opération bancaire solderaient plus que le montant du mouvement"]
}
}
Le corps est contrôlé dans cet ordre, et seul le premier refus est renvoyé : allocated_amount (details.allocated_amount), puis la facture (details.invoice_document), puis le plafond du mouvement (allocation_exceeds_operation, details.base), puis le couple déjà affecté et les règles métier ci-dessus. Ces deux derniers refus sont des validation_failed qui portent leur raison dans message, sans clé details.
Corriger ou retirer un brouillon
PATCH /api/v1/bank_allocations/{id} accepte allocated_amount, status et rejection_reason. Au moins l'un des deux premiers est requis ; les champs absents gardent leur valeur stockée.
curl -X PATCH https://app.scribee.tech/api/v1/bank_allocations/7001 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"allocated_amount": "150.00"}'
Le plafond du mouvement est revérifié, en excluant la part que cette affectation revendique déjà : porter une affectation à la totalité du mouvement est donc accepté quand rien d'autre ne le revendique.
Seule une affectation proposed ou unconfirmed peut être redimensionnée, et le refus porte sur le champ allocated_amount :
- une affectation
confirmedest refusée. Son montant n'est pas le seul enregistrement de ce qu'elle a soldé : la confirmation a écrit un paiement de facture et réimputé une ligne de grand livre, et aucune écriture sur la colonne ne les suit - vous obtiendriez une affectation qui ne concorde plus ni avec son paiement ni avec sa ligne. Pour changer le montant d'une affectation confirmée, transmettez le jeu complet voulu àPOST /api/v1/bank_operations/{id}/reconciliation, qui annule et reconfirme dans une seule transaction ; - une affectation
rejectedest refusée parce que cet état est terminal : un refus ne se réécrit pas. Créez une nouvelle affectation pour ce couple ; - une affectation
unconfirmedreste redimensionnable.DELETE /api/v1/bank_operations/{id}/reconciliationa déjà détruit son paiement et contrepassé sa ligne, de sorte qu'elle n'affirme plus rien sur l'argent et se retravaille comme un brouillon.
Une opération qui règle une instruction d'un lot de paiement refuse en plus tout redimensionnement de ses affectations, proposed et unconfirmed comprises (Une opération qui règle un lot de paiement).
status n'accepte que rejected. Toute autre valeur - confirmed comprise - est refusée sur le champ status.
DELETE /api/v1/bank_allocations/{id} fait la même chose sans corps de requête, et vous rend l'affectation devenue rejected :
{
"data": {
"id": 7001,
"company_id": 34,
"bank_operation_id": 30144,
"invoice_document_id": 90210,
"allocated_amount": 200.0,
"status": "rejected",
"score": 1.0,
"rejection_reason": "wrong_amount",
"explanation": {
"source": "allocation",
"rule_id": null,
"rule_name": null,
"reason": "operator allocation of 200.0000 to invoice 90210"
},
"created_at": "2026-08-21T14:00:00+02:00",
"updated_at": "2026-08-21T15:30:00+02:00"
}
}
Seules une affectation proposed et une affectation unconfirmed peuvent être retirées ici. Une affectation confirmed est refusée : l'argent doit revenir d'abord, par DELETE /api/v1/bank_operations/{id}/reconciliation. Une affectation rejected l'est aussi - cet état est terminal.
rejection_reason n'accepte que wrong_amount, wrong_counterparty, wrong_period et other. Toute autre valeur est stockée comme null plutôt que refusée : le motif est une aide au lecteur, pas une donnée sur laquelle l'appel se joue.
Confirmer : la convergence
C'est ici que l'argent bouge. Le corps porte expected_version et la liste complète des affectations voulues.
curl -X POST https://app.scribee.tech/api/v1/bank_operations/30144/reconciliation?include=allocations,bank_accounting_entry \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Idempotency-Key: 9c2b7e51-3f44-4a20-8f6e-1d0b7a4c3e92" \
-H "Content-Type: application/json" \
-d '{
"expected_version": 6,
"allocations": [
{ "invoice_document_id": 90210, "allocated_amount": "200.00" },
{ "invoice_document_id": 90211, "allocated_amount": "100.00" }
]
}'
La réponse est l'opération recalculée - la ressource bank_operation entière, décrite dans Opérations bancaires. Avec ?include=allocations,bank_accounting_entry, vous relisez le jeu confirmé et les lignes comptables équilibrées dans le même aller-retour, au lieu de faire confiance au 200 : un mouvement de 300,00 ventilé 200/100 vous revient avec deux affectations et trois lignes, jamais avec une ligne mutée.
Quelques règles de corps :
allocationsdoit être une liste non vide. Pour tout défaire, utilisez leDELETE.- Une facture ne peut être nommée qu'une fois. Deux entrées sur la même facture sont refusées plutôt qu'additionnées : un partenaire qui ventile 200 et 100 sur la même facture veut dire 300, et deviner laquelle des deux lectures il voulait serait pire que de lui dire que son corps est mal formé.
- Une entrée illisible rend la liste entière illisible, elle n'est pas ignorée. C'est un corps tout ou rien.
- Le total du jeu est mesuré contre la valeur absolue du mouvement avant que quoi que ce soit ne soit écrit ; le dépassement est
allocation_exceeds_operation. - Un montant qui ne pourrait être soldé que partiellement refuse l'appel entier, il n'est pas réduit en silence.
Ce dernier point mérite un exemple, parce qu'il se produit sur un corps que le plafond du mouvement accepte. Sur une opération de 300,00 vous demandez A = 200,00 et B = 100,00, mais la facture B ne doit plus que 50,00. Le total demandé vaut 300,00 et tient donc dans le mouvement ; c'est la facture qui ne peut pas recevoir ce qu'on lui affecte. L'appel est refusé et rien n'est écrit, au lieu de confirmer A = 200,00 et B = 50,00 - un jeu que vous n'avez pas demandé et que vous ne découvririez qu'en relisant les affectations. Le message nomme les trois chiffres dont vous avez besoin : la facture, le montant demandé, et le montant qui aurait été soldé à la place. Renvoyez le montant que la facture peut recevoir, ou affectez le reste ailleurs.
Le même refus vaut pour un montant à quatre décimales qui ne solderait rien : les affectations sont comptabilisées au centime sur leur cumul, donc un montant qui, ajouté à ce que l'opération porte déjà, n'atteint pas un centime de plus - 0.0001 sur une opération sans affectation, ou 0.0001 après 33.3333 - ne comptabiliserait aucun paiement. L'appel est refusé de la même façon et rien n'est écrit ; le message donne zéro comme montant qui aurait été soldé. Ici, contrairement au cas habituel qu'il évoque, la facture ne doit pas moins que le montant transmis : c'est le montant qui n'atteint pas le centime.
Idempotency-Key et expected_version répondent à deux questions différentes
C'est le point sur lequel une intégration se trompe le plus facilement, et l'erreur ne se voit qu'au pire moment.
| Contre quoi il protège | Ce qu'il ne fait pas | |
|---|---|---|
Idempotency-Key | La même requête qui arrive deux fois - un réseau qui coupe, un client qui réessaie | Il ne regarde pas l'état de l'opération. Il rejouera votre corps stocké sans jamais vérifier que le jeu d'affectations n'a pas bougé entretemps |
expected_version | Une requête périmée - calculée sur une image du jeu d'affectations que quelqu'un d'autre a déplacée depuis | Il ne déduplique rien. Deux requêtes différentes à la même version passeront toutes les deux, la seconde sur la version que la première a écrite |
Aucun des deux ne remplace l'autre, et la confirmation exige les deux. Un partenaire qui envoie une Idempotency-Key en supposant qu'elle le protège d'une version périmée se trompe exactement au moment où un collègue vient de modifier la ventilation depuis l'écran.
version se lit sur l'opération. Il bouge à chaque changement du jeu d'affectations, y compris ceux qui laissent reconciliation_status là où il était : une seconde affectation sur une opération déjà partially_matched ne déplace pas le statut mais déplace bien la version.
Toute écriture sur les affectations le déplace - brouillonner, redimensionner, retirer. Relisez donc version après chaque appel à POST, PATCH ou DELETE sur les affectations : une confirmation calculée avant cette écriture porte une version désormais périmée et sera refusée par un 409. C'est précisément ce que l'on attend d'elle - sans cela, deux clients qui modifient la même ventilation s'écraseraient en silence - mais il faut le savoir pour ne pas croire à une panne.
expected_version est comparé comme un entier
Il est accepté sous forme de chaîne JSON ou de nombre - "6" et 6 sont lus de la même façon - mais il est comparé comme un entier. Une valeur qui n'est ni un entier ni une chaîne de chiffres décimaux est refusée 422 sur le champ expected_version, et non 409 : ce n'est pas une version périmée, c'est une valeur que nous ne savons pas lire.
La distinction compte pour votre gestion d'erreur : un 409 se réessaie à une version plus fraîche, un 422 sur ce champ ne se réessaiera jamais avec succès tant que la valeur envoyée garde cette forme.
Le 409 porte l'état courant
{
"error": "conflict",
"code": "stale_version",
"message": "Cette opération bancaire a changé depuis sa lecture ; rien n'a été écrit. La version courante et le jeu d'affectations figurent dans details.",
"details": {
"current_version": 8,
"operation": {
"id": 30144,
"amount": "300.0000",
"direction": "incoming",
"reconciliation_status": "partially_matched"
},
"allocations": [
{
"id": 7001,
"invoice_document_id": 90210,
"allocated_amount": 200.0,
"status": "confirmed"
}
]
}
}
Rien n'a été écrit. details porte l'état courant, pas celui que vous avez envoyé : réaffichez depuis lui et réessayez avec details.current_version, sans second aller-retour.
Deux choses à savoir sur ce corps :
details.operation.amountest la chaîne à quatre décimales que la ressourcebank_operationpublie, jamais un nombre. Les deux lectures ne peuvent donc pas diverger.details.allocationsne contient que les affectations actives, triées par identifiant. Les rejets en sont exclus : ils ne font pas partie de l'image contre laquelle vous auriez dû confirmer.
C'est le seul 409 de cette API qui porte un details. idempotency_key_reuse et idempotency_request_in_progress répondent aussi 409 sur ce chemin, sans details.
Deux confirmations portant sur la même facture peuvent être enregistrées au même moment, depuis deux opérations différentes. Lorsque la course laisse l'opération perdante sans aucune affectation active, celle-ci reçoit ce 409 stale_version ; sinon, elle reçoit le refus 422 qu'appelle le nouvel état de la facture - par exemple une facture déjà soldée. Si la collision se reproduit, elle reçoit un 422 operation_failed. Dans les deux cas, rien n'a été écrit : relisez l'opération bancaire, puis renvoyez le rapprochement s'il s'applique toujours.
entry_already_exported est un 422, délibérément
Quand l'écriture comptable de l'opération a quitté les livres - exportée vers un logiciel comptable, ou verrouillée par un export - plus aucun changement d'affectation ne peut la réécrire.
Ce refus est un 422 et non un 409, et ce n'est pas une inadvertance. Un 409 dit que la requête est périmée et qu'un réessai à une version plus fraîche peut réussir ; une écriture exportée rend la requête impossible à toute version. Le remède est une écriture de reclassement, jamais une réécriture.
Le même refus vaut sur le DELETE.
reconfirmation_out_of_order : une affectation plus récente reste confirmée
L'écriture comptable de l'opération répartit les affectations confirmées au centime, sur leur cumul, dans l'ordre de leurs identifiants. Une confirmation, elle, comptabilise son paiement après ceux des affectations déjà confirmées, et ces paiements ne sont jamais recomptabilisés. Quand vous confirmez une affectation alors qu'une affectation plus récente de la même opération - d'identifiant plus grand - reste confirmée, et que les paiements différeraient alors de la répartition de l'écriture, la confirmation est refusée par un 422 reconfirmation_out_of_order. Rien n'a été écrit : le jeu entier est annulé, y compris les retraits que l'appel avait déjà faits.
Ce refus ne peut survenir que sur une opération dont une affectation porte, ou a porté, un montant qui va au-delà du centime - une troisième ou une quatrième décimale. Lorsque tous les montants sont des centimes entiers et que le paiement de chaque affectation confirmée est égal à son montant, il ne survient jamais. Les deux cas typiques :
- renvoyer une affectation retirée plus tôt, alors qu'une affectation plus récente est restée confirmée ;
- renvoyer une affectation à un autre montant à quatre décimales, en conservant une affectation plus récente.
details.allocations nomme, par invoice_document_id, la facture que vous confirmiez et celles des affectations plus récentes.
Scribee ne retire pas ces affectations plus récentes à votre place. Pour procéder, transmettez d'abord le jeu sans elles : elles sont retirées, le reste est confirmé, et la réponse porte la nouvelle version. Transmettez ensuite de nouveau le jeu complet avec cette version : les affectations sont alors confirmées dans l'ordre de leurs identifiants.
Ce refus est lui aussi un 422 et non un 409 : un réessai à une version plus fraîche échouerait de la même façon. Les paiements déjà comptabilisés ne sont jamais recomptabilisés, donc les affectations plus récentes doivent d'abord être retirées.
Annuler une confirmation
curl -X DELETE https://app.scribee.tech/api/v1/bank_operations/30144/reconciliation \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"allocation_ids": [7001]}'
Les paiements des affectations nommées sont détruits, la ligne d'attente de l'écriture comptable est rétablie, et la réponse est l'opération recalculée - avec les mêmes include que la confirmation.
Chaque affectation s'annule indépendamment. Nommez allocation_ids et les autres restent exactement où elles sont ; omettez la clé entièrement et toutes les affectations confirmées sont annulées. Une liste vide est refusée plutôt que lue comme « toutes » : les deux lectures sont opposées, et un partenaire dont le filtre a produit une liste vide voulait dire la première.
Une affectation annulée devient unconfirmed, pas rejected. Si vous vouliez la refuser définitivement, passez ensuite par DELETE /api/v1/bank_allocations/{id}.
expected_version est facultatif ici et obligatoire sur la confirmation. Ce n'est pas un oubli : une confirmation est calculée à partir d'une image du jeu d'affectations et devient fausse si cette image a bougé, tandis qu'une annulation nomme les lignes qu'elle veut par identifiant. Quand vous le fournissez, il est appliqué à l'identique.
Un identifiant qui n'est pas une affectation confirmée de cette opération est refusé, pas silencieusement ignoré - y compris quand il appartient à une autre opération. Un partenaire qui l'a envoyé croyait qu'elle était soldée, et un succès silencieux lui dirait qu'elle a été annulée.
C'est aussi la bonne façon de retirer un paiement de facture issu d'un rapprochement. DELETE sur /api/v1/invoices/{invoice_id}/payments/{id} refuse un paiement portant une opération bancaire : détacher l'argent du rapprochement qui l'a créé laisserait le grand livre décrire un règlement qui n'existe plus. PATCH sur le même chemin n'accepte que note sur un tel paiement ; une requête qui porte un autre champ, même avec sa valeur actuelle, est refusée en entier (Corriger un paiement).
Une opération qui règle un lot de paiement
Quand une opération a été confirmée comme le règlement d'une instruction d'un lot de paiement (Lots de paiement), cette confirmation s'appuie sur ses affectations. Tant que ce lien existe, les affectations de l'opération ne changent que par l'annulation de ce règlement, et les appels suivants sont refusés par un 422 operation_failed :
DELETE /api/v1/bank_operations/{id}/reconciliation, quelle que soit l'affectation nommée ;POST /api/v1/bank_operations/{id}/reconciliationquand le jeu envoyé retirerait une affectation confirmée - en l'omettant, ou en la renvoyant à un autre montant ;POST /api/v1/bank_operations/{id}/reconciliationquand il confirmerait l'opération contre une facture qui n'est pas celle de l'instruction. Une instruction qui ne règle aucune facture n'en admet aucune ;PATCH /api/v1/bank_allocations/{id}qui porteallocated_amount.
details.base le dit et nomme l'étape à suivre. Rien n'a été écrit.
Pour procéder, annulez d'abord le règlement avec POST /api/v1/payment_batches/{id}/settlement/instructions/{payment_instruction_id}/undo (Annuler un règlement confirmé). Cette annulation retire le lien et seulement ce que la confirmation avait enregistré ; les affectations de l'opération se retravaillent ensuite ici comme les autres.
Lister les affectations
curl https://app.scribee.tech/api/v1/bank_operations/30144/allocations \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
La liste est triée par created_at croissante, la plus ancienne d'abord - l'ordre dans lequel la ventilation a été construite - et les ex aequo sont départagés par identifiant croissant.
Aucun filtre de statut n'est appliqué par défaut, et les rejets sont rendus eux aussi. C'est délibéré : sans eux, vous ne pouvez pas distinguer une facture qui n'a jamais été proposée d'une facture proposée puis refusée, et le refus est justement la pièce d'audit.
| Paramètre | Ce qu'il restreint |
|---|---|
status | Un état d'affectation |
invoice_document_id | L'affectation portant sur une facture donnée |
include | invoice_document, bank_operation, séparés par des virgules |
Une valeur non reconnue ne restreint rien et ne provoque pas d'erreur - elle rend une page vide, comme partout ailleurs sur cette surface. Une valeur d'include qui n'est aucune des deux est ignorée, et sans include ces clés sont absentes de la réponse plutôt que publiées à null.
Les embarqués ne s'imbriquent pas : bank_operation vous est rendu sans ses propres include, donc une affectation ne peut pas vous revenir à l'intérieur d'elle-même.
page et per_page paginent comme partout ailleurs (20 par défaut, 100 au maximum).
Les erreurs
| Code | Quand |
|---|---|
400 | page n'est pas un entier supérieur ou égal à 1, ou désigne une page au-delà de la dernière |
401 | Aucun jeton, ou un jeton invalide ou expiré |
403 | Votre jeton ne porte pas le scope attendu par le verbe, ou la fonctionnalité de rapprochement bancaire est désactivée sur le workspace concerné |
404 | Aucune opération - ou aucune affectation - de cet identifiant n'est atteignable par vos habilitations |
409 | stale_version, ou l'un des deux conflits d'Idempotency-Key |
422 | Le corps ou l'état de la ressource refuse l'appel. code dit lequel |
Les valeurs de code que vous rencontrerez ici - les quatre premières ne s'écrivent nulle part ailleurs sur l'API :
code | Sens |
|---|---|
stale_version (409) | La version envoyée n'est plus celle de l'opération. Rien n'a été écrit ; details porte l'état courant |
allocation_exceeds_operation (422) | Le jeu d'affectations solderait plus que le mouvement ne porte |
entry_already_exported (422) | L'écriture comptable de l'opération a quitté les livres et ne peut plus être réécrite |
reconfirmation_out_of_order (422) | La confirmation comptabiliserait le centime d'arrondi dans un autre ordre que l'écriture, parce qu'une affectation plus récente reste confirmée. Rien n'a été écrit ; transmettez d'abord le jeu sans elle, puis le jeu complet |
operation_failed (422) | Un autre rapprochement portant sur les mêmes factures était enregistré au même moment, et la collision s'est reproduite ; ou l'opération règle une instruction d'un lot de paiement, et ce règlement doit être annulé d'abord. Rien n'a été écrit |
validation_failed (422) | Tout le reste : un champ mal formé, une facture introuvable, une règle métier refusée, un état qui ne se retire ni ne se redimensionne, un montant qu'une facture ne peut pas recevoir en entier |
Le scope est vérifié avant l'existence de la ressource. Un jeton sans le scope attendu reçoit 403 sur un identifiant inexistant comme sur un identifiant valide. En revanche, sur les ressources elles-mêmes, l'atteignabilité est tranchée avant la fonctionnalité : une opération que votre jeton ne peut pas lire répond 404, jamais 403. Aucune de ces réponses ne permet donc de sonder l'existence d'un identifiant.