Devis et ententes préalables
En dentaire, en optique ou en audioprothèse, la facture est souvent précédée d’un devis, et certains actes d’un accord de la caisse. Un devis (Quote, qt_…) porte les soins proposés au patient, avec les mêmes champs qu’une facture, et leurs parts estimées. Une demande d’entente préalable (PriorAgreement, pag_…) suit l’accord de la caisse. Accepté, un devis devient une facture en un appel.
Droits de clé : quotes:read et quotes:write. Facturer un devis demande en plus claims:write.
Cycle de vie d’un devis
| État | Sens |
|---|---|
draft | En préparation : ses parts se réestiment à chaque modification. Seul état modifiable |
open | Remis au patient : ses parts sont arrêtées, il ne se modifie plus |
accepted | Le patient l’a accepté |
declined | Le patient l’a refusé |
expired | Remis, il a passé valid_until sans être accepté |
invoiced | Devenu une facture : claim la nomme |
canceled | Annulé, possible jusqu’à la facture |
Une transition impossible répond 409 conflict.
Je veux…
| Je veux… | Appel |
|---|---|
| Ouvrir un devis | POST /v1/quotes |
| Changer ses lignes ou sa validité | PATCH /v1/quotes/{id} |
| Le remettre au patient | POST /v1/quotes/{id}/finalize |
| Dire que le patient accepte | POST /v1/quotes/{id}/accept |
| Dire que le patient refuse | POST /v1/quotes/{id}/decline |
| En faire une facture | POST /v1/quotes/{id}/invoice |
| Lister les devis d’un patient | GET /v1/quotes?patient=pat_… |
| Demander l’entente préalable d’un devis | POST /v1/prior-agreements |
| Dire que la demande est partie | POST /v1/prior-agreements/{id}/send |
| Enregistrer la réponse de la caisse | POST /v1/prior-agreements/{id}/answer |
| Simuler la réponse de la caisse | POST /v1/test-helpers/prior-agreements/{id}/response |
Les parts estimées
Un devis prend les champs d’une facture : praticien, patient, contexte, complémentaire, et des lignes qui sont des prestations. service_date est la date prévue des soins, celle du jour par défaut : elle donne le tarif. Les parts viennent des mêmes règles que celles d’une facture, appliquées à la dernière lecture de droits du patient : amount_cents, amo_amount_cents, amc_amount_cents, patient_amount_cents, et pricing_steps sur chaque ligne. Voir Montants.
curl https://api.ophelix.fr/v1/quotes \
-H "Authorization: Bearer sk_test_…" \
-H "Content-Type: application/json" \
-d '{
"practitioner": "prac_…",
"patient": "pat_…",
"valid_until": "2027-02-01",
"lines": [{"nomenclature": "ccam", "code": "HBLD036", "service_date": "2026-12-01"}]
}'Sans valid_until, un devis vaut 90 jours.
De l’acceptation à la facture
finalize arrête le devis : ses parts s’estiment une dernière fois, et il ne bouge plus. Le patient répond par accept ou decline. Passé valid_until, accept répond 409 et le devis passe à expired ; chaque nuit, Ophelix fait expirer les devis remis dont la validité est passée.
invoice ouvre la facture en brouillon, sans ressaisie : mêmes lignes, même contexte, même complémentaire. service_date remplace la date prévue sur chaque ligne, aujourd’hui par défaut, et la facture prend la dernière lecture de droits du patient, ou celle que nomme coverage : les droits se lisent le jour du soin. Les montants de la facture se recalculent donc à cette date. La facture porte quote, le devis porte claim. Elle suit ensuite le cycle d’une facture.
Entente préalable
| État | Sens |
|---|---|
draft | Préparée, pas encore partie |
sent | Partie vers la caisse : sent_on en garde la date |
approved | Accordée. response dit par quoi : favorable, la caisse a répondu ; no_answer, elle n’a pas répondu dans le délai |
refused | La caisse a refusé |
canceled | Annulée avant la réponse |
Sur un devis, la demande en reprend le praticien, le patient et toutes les lignes. Sans devis, elle nomme practitioner, patient et ses lines.
send dit comment elle part. channel: "paper" : le praticien a posté le formulaire, et sent_on dit quand. channel: "online" : le téléservice de l’Assurance Maladie. En mode test, le simulateur la reçoit ; en production, Ophelix ne l’a pas encore raccordé, et send répond 503 engine_unavailable.
La réponse papier s’enregistre par answer, avec decision (approved ou refused) et l’identifier qu’elle porte. Sans réponse de la caisse 15 jours après l’envoi, Ophelix accorde la demande d’elle-même, avec response: "no_answer".
urgent: true dit que les soins n’attendent pas la réponse : dès l’envoi, la facture peut partir avec le code d’urgence.
claim_line_agreement dit ce qu’une ligne de facture doit porter de l’entente, ou null tant qu’elle ne permet pas de facturer. Un devis facturé le recopie seul sur chacune de ses lignes, depuis sa demande la plus récente qui n’est pas annulée. Pour une facture sans devis, recopiez-le dans lines[].prior_agreement.
Événements
quote.created, puis quote.finalized, quote.accepted ou quote.declined, quote.expired, quote.invoiced, quote.canceled. Pour l’entente : prior_agreement.created, prior_agreement.sent, prior_agreement.approved, prior_agreement.refused, prior_agreement.canceled. Comme pour une facture, un événement ne porte ni acte ni date de soins : des identifiants, l’état et le total. Écoutez prior_agreement.approved pour savoir qu’un devis peut devenir une facture.
En mode test
Le simulateur reçoit les demandes en ligne et répond à la demande : approved, refused, ou no_answer, le silence jusqu’au bout du délai sans l’attendre. Voir Cartes et scénarios de test.
Pièges
- Une estimation n’est pas une facture. Les parts d’un devis valent à la date prévue, avec les droits lus ce jour-là. La facture les recalcule à la date des soins.
nulln’est pas zéro, sur un devis comme sur une facture : une part complémentaire inconnue restenull, etamc_pricingdit pourquoi.- Un devis remis ne se modifie plus. Pour changer les soins, annulez-le et ouvrez-en un autre.
- Une demande sans réponse arrête la facture.
invoicerépond 409 tant que l’entente du devis estdraftousent, sauf en urgence, et quand elle estrefused. - Le téléservice d’entente préalable n’est pas raccordé en production : envoyez le formulaire papier et dites-le par
channel: "paper".