References/Payment Reconciliation: Difference between revisions
More languages
More actions
OHC identity seed |
Automated edit (via update-page on MediaWiki MCP Server) |
||
| Line 280: | Line 280: | ||
* Send <code>tendered_amount</code> and <code>returned_amount</code> (both required); the server derives <code>amount</code>, so any value you send for it is ignored. |
* Send <code>tendered_amount</code> and <code>returned_amount</code> (both required); the server derives <code>amount</code>, so any value you send for it is ignored. |
||
* <code>extensions</code> holds custom key-value data without a schema migration, validated against registered handlers. |
* <code>extensions</code> holds custom key-value data without a schema migration, validated against registered handlers. |
||
{{Navbox billing}} |
|||
{{Related}} |
{{Related}} |
||
Wiki: ohcnwiki.tellmey.fyi |
|||
Latest revision as of 09:42, 6 July 2026
A PaymentReconciliation is a single payment recorded against an Account, and optionally allocated to one Invoice. It captures how much was paid, by what method, when, and by whom — mirroring the FHIR [https://build.fhir.org/paymentreconciliation.html PaymentReconciliation] resource. Reach for it whenever you post a payment, refund, credit note, or adjustment to a patient or insurer account.
Source:
- Model: [https://github.com/ohcnetwork/care/blob/develop/care/emr/models/payment_reconciliation.py
care/emr/models/payment_reconciliation.py] - Resource spec: [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/payment_reconciliation/spec.py
care/emr/resources/payment_reconciliation/spec.py]
The model is thin storage: enum-constrained fields are plain CharFields and extensions is an opaque JSONField. The behaviour you integrate against — enum constraints, amount computation, validation, and the read/write schema split — lives in the Pydantic resource specs (care/emr/resources/payment_reconciliation/spec.py), built on EMRResource.
Models
| Model | Purpose |
|---|---|
PaymentReconciliation
|
A single payment (or credit note / adjustment) recorded against an account or invoice |
The model extends EMRBaseModel, the shared Care EMR base supplying external_id, audit fields, and soft-delete semantics — see Base model.
PaymentReconciliation fields
Relationships
| Field | Type | Notes |
|---|---|---|
facility |
FK → Facility (PROTECT) |
Facility where the payment is recorded |
target_invoice |
FK → Invoice (PROTECT) |
The invoice this payment is allocated to. Nullable (default=None); one allocation per record. On write, pass the invoice external_id (UUID)
|
account |
FK → Account (PROTECT) |
The account being paid. Required even when target_invoice is set. On write, pass the account external_id (UUID)
|
location |
FK → FacilityLocation (PROTECT) |
Physical location (e.g. the counter) where payment was taken. Nullable. On write, pass the location external_id (UUID)
|
Classification
Six columns map to fixed enums defined in the resource spec. Each is stored as a free-form CharField(100); the enum is enforced at the schema/API layer, not by the database. Full value lists are under enum values.
| Field | Type | Spec enum | Notes |
|---|---|---|---|
reconciliation_type |
CharField(100) |
PaymentReconciliationTypeOptions
| |
status |
CharField(100) |
PaymentReconciliationStatusOptions
| |
kind |
CharField(100) |
PaymentReconciliationKindOptions
| |
issuer_type |
CharField(100) |
PaymentReconciliationIssuerTypeOptions
| |
outcome |
CharField(100) |
PaymentReconciliationOutcomeOptions
| |
method |
CharField(100) |
PaymentReconciliationPaymentMethodOptions
|
Payment details
| Field | Type | Notes |
|---|---|---|
payment_datetime |
DateTimeField → datetime |
When the payment was issued. Optional (default None)
|
reference_number |
CharField(1024) → str |
Cheque number or payment reference. Optional |
authorization |
CharField(1024) → str |
Authorization number. Optional |
disposition |
TextField → str |
Message describing the outcome. Optional |
note |
TextField → str |
Free-text note. Optional |
Amounts
Every amount is a DecimalField(max_digits=20, decimal_places=6). Six decimal places allow sub-currency precision.
| Field | Type | Notes |
|---|---|---|
tendered_amount |
Decimal(20, 6) |
Required on write. Amount offered by the issuer |
returned_amount |
Decimal(20, 6) |
Required on write. Amount returned to the issuer (e.g. change). Must be strictly less than tendered_amount, or the write is rejected
|
amount |
Decimal(20, 6) |
Net payment, computed server-side as tendered_amount - returned_amount. A client-supplied value is always overwritten
|
Flags & extensions
| Field | Type | Notes |
|---|---|---|
is_credit_note |
BooleanField → bool |
Default False. Marks the record as a credit note rather than an inbound payment
|
extensions |
JSONField → dict |
Default {}. Open extension bag. On write, each key is validated against the registered handler for resource type payment_reconciliation — unknown keys are currently dropped. On retrieve, rendered through those handlers
|
Enum values
All enums are str, Enum classes in [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/payment_reconciliation/spec.py spec.py].
PaymentReconciliationTypeOptions (reconciliation_type)
| Value |
|---|
payment
|
adjustment
|
advance
|
PaymentReconciliationStatusOptions (status)
| Value |
|---|
active
|
cancelled
|
draft
|
entered_in_error
|
PaymentReconciliationKindOptions (kind)
| Value |
|---|
deposit
|
periodic_payment
|
online
|
kiosk
|
PaymentReconciliationIssuerTypeOptions (issuer_type)
| Value |
|---|
patient
|
insurer
|
PaymentReconciliationOutcomeOptions (outcome)
| Value |
|---|
queued
|
complete
|
error
|
partial
|
PaymentReconciliationPaymentMethodOptions (method)
HL7 v2-0570 payment-method codes.
| Value | HL7 meaning |
|---|---|
cash
|
Cash |
ccca
|
Credit card |
cchk
|
Cashier's check |
cdac
|
Credit/debit account |
chck
|
Check |
ddpo
|
Direct deposit |
debc
|
Debit card |
Resource specs (API schema)
Defined in [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/payment_reconciliation/spec.py care/emr/resources/payment_reconciliation/spec.py]. All extend EMRResource (serialize / de_serialize, with perform_extra_serialization / perform_extra_deserialization hooks). See Base model.
| Spec class | Role | Notes |
|---|---|---|
BasePaymentReconciliationSpec
|
shared base | Holds id, the six enum fields, disposition, payment_datetime, method, reference_number, authorization, note. __exclude__ = ["target_invoice", "account"] (FKs handled in hooks). ___extension_resource_type__ = payment_reconciliation
|
PaymentReconciliationWriteSpec
|
write · create & update | Adds target_invoice (UUID, optional), account (UUID, required), tendered_amount, returned_amount, amount (optional), is_credit_note (default False), location (UUID, optional). Mixes in ExtensionValidator
|
PaymentReconciliationMinimalReadSpec
|
read · list | Adds amount, tendered_amount, returned_amount, is_credit_note, created_date, modified_date
|
PaymentReconciliationReadSpec
|
read · detail (nested) | None (serialized via InvoiceReadSpec)
|
PaymentReconciliationRetrieveSpec
|
read · full retrieve | None (via FacilityLocationListSpec), extensions: dict, created_by / updated_by. Also injects account.patient via PatientRetrieveSpec
|
Write validation & side effects
PaymentReconciliationWriteSpec runs three steps:
- The amount validator (
model_validator(mode="after"),check_amount_or_factor) raises"Returned amount cannot be greater than tendered amount"whenreturned_amount >= tendered_amount, then setsamount = tendered_amount - returned_amount. The spec'samountfield is advisory and always recomputed. perform_extra_deserialization(is_update, obj)resolves the FK UUIDs to model instances:target_invoice(if provided) →Invoice.objects.get(external_id=...)account(required) →Account.objects.get(external_id=...)location(if provided) →FacilityLocation.objects.get(external_id=...)
ExtensionValidator.validate_extensionschecksextensionsagainst thepayment_reconciliationextension registry before save.
Read serialization side effects
PaymentReconciliationMinimalReadSpec.perform_extra_serializationmapsid←obj.external_id.PaymentReconciliationReadSpecserializes the relatedaccount(AccountReadSpec) and, when present,target_invoice(InvoiceReadSpec) into nested objects.PaymentReconciliationRetrieveSpecadditionally nests the account'spatient(PatientRetrieveSpec, scoped to the account's facility), thelocation(FacilityLocationListSpec), the rawextensions, and audit users (created_by/updated_byviaserialize_audit_users).
Related models
PaymentReconciliation is self-contained; its foreign keys reach into the billing and facility domains:
facility → FK Facility (PROTECT)
target_invoice → FK Invoice (PROTECT, nullable)
account → FK Account (PROTECT)
location → FK FacilityLocation (PROTECT, nullable)
Each foreign key uses on_delete=PROTECT, so a payment record blocks deletion of the facility, invoice, account, or location it references.
Methods & save behaviour
PaymentReconciliation defines no custom save(); it inherits EMRBaseModel behaviour (audit fields, external_id, soft delete). Everything below happens in the write spec, not the model:
amountis derived, not stored as sent. On every create and update the write spec computesamount = tendered_amount - returned_amountand rejectsreturned_amount >= tendered_amount.- FK resolution happens in
perform_extra_deserialization:external_idUUIDs foraccount,target_invoice, andlocationresolve to instances at de-serialization time. extensionsare validated against thepayment_reconciliationregistry on write and rendered through registered handlers on retrieve.
API integration notes
- Create and update use
PaymentReconciliationWriteSpec; list responses usePaymentReconciliationMinimalReadSpec; detail and retrieve responses usePaymentReconciliationReadSpec/PaymentReconciliationRetrieveSpec. accountis always required;target_invoiceis optional and allocates the payment to one invoice. Passaccount,target_invoice, andlocationasexternal_idUUIDs.- The Pydantic schema constrains the six classification fields (
reconciliation_type,status,kind,issuer_type,outcome,method) to the enums above and rejects invalid values, even though each column is a plainCharField. - Send
tendered_amountandreturned_amount(both required); the server derivesamount, so any value you send for it is ignored. extensionsholds custom key-value data without a schema migration, validated against registered handlers.
Related
Pages that link here:
- Reference: References/Base models & conventions
Wiki: ohcnwiki.tellmey.fyi