Skip to content

Oscar Pro Billing Integration

This document defines the FHIR mapping and implementation details for integrating Oscar Pro's billing module with the Nexus EMR FHIR IG. The initial driver is the Nexus Jarvis Billing product, which reads Oscar billing context (demographics, historic bills, dx list, provider info) to generate post-encounter OHIP billing code recommendations and writes the accepted codes back to Oscar's billing module.

Overview

Oscar Pro stores Ontario physician billing in two linked tables:

  • billing_on_cheader1 — invoice/claim header (one row per submitted bill)
  • billing_on_item — line items per fee code within a bill (one row per OHIP service code)

The existing ca.kai.fhir.converter.r4.InvoiceConverter already emits a FHIR R4 Invoice resource with inline lineItem[] components mapping from these tables. This integration formalises that mapping via:

  1. The new NexusEmrCoreInvoice profile
  2. Three extensions on Invoice: oscarBillingStatus, shadowBill, and serviceLocation (reference to a NexusEmrCoreLocation carrying the SLI code). Note (1.9.9): Oscar's pay_program now lives on FHIR-native Invoice.type.coding[payProgram] rather than a custom extension — consumers should read Invoice.type.coding in 1.9.9+.
  3. An identifier[ohipBillingNumber] slice on NexusEmrCorePractitioner
  4. Code-system aliases for OHIP Schedule of Benefits, OHIP diagnostic codes, and ICD-9

Scope

Phase 1 covers Ontario (OHIP) on Oscar Pro only. Other provinces and other backends are out of scope for this iteration; nothing on this page should be read as a commitment for them.

Definitions

  • OHIP — Ontario Health Insurance Plan, the provincial single-payer program
  • FHO / FHN — Family Health Organization / Family Health Network — Ontario capitation-based physician payment models (~60% of Ontario FPs)
  • FHG — Family Health Group, a blended FFS model
  • FFS — Fee-for-Service (traditional per-service billing)
  • FHO+ — Enhanced FHO model launching 2026-04 with 30-50% shadow billing rates
  • Shadow Bill — a submission under a capitated model that records service delivery but pays at a fraction of FFS rates (for tracking and utilization-based funding)
  • RMB — Reciprocal Medical Billing (billing OHIP-equivalent for non-Ontario health card holders)
  • WCB — Worker's Compensation Board (Oscar source label — in Ontario this maps to the WSIB, Workplace Safety and Insurance Board)

Use Cases

As an AI billing recommendation module (Jarvis), I need to:

  • Read a provider's recent encounter notes, demographics, dx list, and historic bills to understand context
  • Detect the provider's payment model (FHO/FHN/FHG/FFS/FHO+) from Oscar signals
  • Generate applicable OHIP fee codes based on encounter content
  • Write accepted billing codes back to Oscar's billing module as new billing_on_cheader1 + billing_on_item rows
  • Preserve Oscar's 10-code billing status enum across the FHIR round-trip

Architecture

flowchart LR
    subgraph oscar["Oscar Pro"]
        t1[("billing_on_cheader1<br/>+ billing_on_item")]
        t2[("dxresearch")]
        t3[("casemgmt_issue *")]
        t4[("demographic")]
        t5[("provider")]
    end

    subgraph fhir["FHIR R4 (Nexus EMR IG)"]
        c1[InvoiceConverter<br/>existing]
        c2[ConditionConverter<br/>needs overload]
        c3[PatientConverter<br/>existing]
        c4[PractitionerConverter<br/>existing]
        r1([Invoice<br/>+ 3 extensions])
        r2([Condition<br/>+ category])
        r3([Patient])
        r4([Practitioner<br/>+ ohipBillingNumber])
    end

    subgraph nexus["Nexus / Jarvis"]
        j1[Read historic bills]
        j2[Read dx context]
        j3[Read demographics]
        j4[Read provider info]
        j5[Generate<br/>recommendations]
        j6[Provider review]
        j7[Write accepted codes]
    end

    t1 --> c1 --> r1 --> j1
    t2 --> c2
    t3 -.-> c2
    c2 --> r2 --> j2
    t4 --> c3 --> r3 --> j3
    t5 --> c4 --> r4 --> j4

    j1 & j2 & j3 & j4 --> j5 --> j6 --> j7
    j7 -- Invoice POST --> c1 -- toOscarObject --> t1

* CPP → Condition path is net-new — CaseManagementIssue source not currently converted.

Mapping Documents

Extension URL Provenance

Nexus EMR IG profiled extensions:

  • oscar-billing-status-extension — raw 10-code Oscar billing status enum
  • oscar-billing-shadow-bill-extension — boolean flag for FHO/FHN capitated submissions
  • oscar-service-location-extension(added in 1.9.9) Reference to a NexusEmrCoreLocation carrying the SLI code on identifier[sliCode]; replaces the raw-string apps.health/Invoice/location extension

1.9.9 refactor — pay_program moved off extensions: previously oscar-billing-pay-program-extension; now Invoice.type.coding[payProgram] (native FHIR, bound to OscarPayProgramCS). The extension was removed. Converters emitting against 1.9.9 must use the native type.coding slot.

Additional extension URLs referenced in the mapping YAMLs but NOT authored in this IG:

The existing InvoiceConverter already emits ~15 extension URLs under https://apps.health/Invoice/* and https://apps.health/InvoiceLineItem/* namespaces (see InvoiceExtensionUrls.java + InvoiceLineItemComponentExtensionUrls.java). These are emitted in the wild today but do not yet have corresponding StructureDefinition / Extension profiles in the Nexus EMR IG. They include:

Category Extension URL stem Oscar field
Invoice header apps.health/Invoice/admission-date billing_on_cheader1.admission_date
Invoice header apps.health/Invoice/appointment-no billing_on_cheader1.appointment_no
Invoice header apps.health/Invoice/facility-num billing_on_cheader1.facilty_num (sic)
~~Invoice header~~ ~~apps.health/Invoice/location~~ ~~billing_on_cheader1.location~~ — superseded 1.9.9: now oscar-service-location-extensionReference(NexusEmrCoreLocation) with SLI on identifier[sliCode]
Invoice header apps.health/Invoice/manual-review billing_on_cheader1.man_review
Invoice header apps.health/Invoice/paid billing_on_cheader1.paid
~~Invoice header~~ ~~apps.health/Invoice/pay-program~~ ~~billing_on_cheader1.pay_program~~ — superseded 1.9.9: now Invoice.type.coding[payProgram] with $OscarPayProgramCS
Invoice header apps.health/Invoice/payee billing_on_cheader1.payee
Invoice header apps.health/Invoice/province billing_on_cheader1.province
Invoice header apps.health/Invoice/ref-lab-num billing_on_cheader1.ref_lab_num
Invoice header apps.health/Invoice/total-deleted derived
Invoice header apps.health/Invoice/visit-type billing_on_cheader1.visittype
Line item apps.health/InvoiceLineItem/diagnostic1 billing_on_item.dx
Line item apps.health/InvoiceLineItem/diagnostic2 billing_on_item.dx1
Line item apps.health/InvoiceLineItem/diagnositc3 ⚠️ typo billing_on_item.dx2
Line item apps.health/InvoiceLineItem/header-id billing_on_item.ch1_id
Line item apps.health/InvoiceLineItem/last-updated billing_on_item.timestamp
Line item apps.health/InvoiceLineItem/service-date billing_on_item.service_date
Line item apps.health/InvoiceLineItem/status billing_on_item.status
Line item apps.health/InvoiceLineItem/hin-verion ⚠️ typo

Decision needed: should Nexus EMR IG author StructureDefinition profiles for each of these (aligning the IG with what's already on the wire), or treat them as converter-internal and leave un-profiled? Recommend authoring profiles for the line-item dx extensions (DIAGNOSTIC_1/2/3) at minimum since they carry clinical coding semantics; the header extensions are largely administrative and can remain un-profiled if bandwidth is tight.

Open Questions

  • [ ] Rejected-claim handling in Phase 1? — the requirement is that a rejection reason and a suggested correction are surfaced, but Oscar's raDetail / remittance-advice integration is deferred to Phase 2. Undecided: whether Phase 1 ships without the rejection loop. If it must not, the converter work expands significantly.
  • [ ] Invoice.status draft state for provider-review intermediate? — the write-back design must decide whether Jarvis POSTs in draft status awaiting provider-accept → issued transition, or posts issued only after provider confirms. See write-back-design.md.
  • [ ] Payment-model detection strategy — no single Oscar column identifies FHO/FHN/FHG/FFS/FHO+; must be derived from multiple signals (provider.onMohLastRosterReportDate + demographic_ext.ENROLLMENT_PROVIDER + historical billing_on_cheader1.status distribution). See the payment-model detection notes in the source-table analysis.

Known Converter Gaps

All file:line references are absolute paths under oscar-pro/src/main/java/.

# Gap Source location
1 R4 EncounterResourceProvider missing (only DSTU2 exists — ca/kai/fhir/resource/dstu2/EncounterResourceProvider.java) N/A — net-new R4 file needed
2 Invoice.status emits HAPI InvoiceStatus.NULL sentinel for Oscar H and I; X is incorrectly emitted as ISSUED (should be cancelled) ca/kai/fhir/converter/r4/InvoiceConverter.java:510-540
3 ConditionConverter writes literal "icd9" as Coding.system instead of http://hl7.org/fhir/sid/icd-9-cm ca/kai/fhir/converter/r4/ConditionConverter.java:139-141
4 ConditionConverter doesn't set Condition.category (neither problem-list-item nor encounter-diagnosis) ca/kai/fhir/converter/r4/ConditionConverter.java:81-161
5 ConditionConverter only reads DxResearch; CPP CaseManagementIssue source not converted ca/kai/fhir/converter/r4/ConditionConverter.java:81
6 InvoiceLineItemComponentExtensionUrls.DIAGNOSTIC_3 URL misspelled (diagnositc3) ca/kai/fhir/converter/r4/extension/InvoiceLineItemComponentExtensionUrls.java:8
7 InvoiceLineItemComponentExtensionUrls.HIN_VERSION URL misspelled (hin-verion) ca/kai/fhir/converter/r4/extension/InvoiceLineItemComponentExtensionUrls.java:13
8 Copy-paste bug: IDENTIFIER_APPTPROVIDER_NO + IDENTIFIER_ASSTPROVIDER_NO both set to "provider_ohip_no" ca/kai/fhir/converter/r4/InvoiceConverter.java:57-60
9 APPS_HEALTH_CODE_SYSTEM_URL placeholder on chargeItemCodeableConcept + dx extensions — needs real OHIP SoB + ICD-9 URIs ca/kai/fhir/converter/r4/InvoiceConverter.java:356,370-383
10 Encounter.length unpopulated; duration lives on casemgmt_note.hourOfEncounterTime + minuteOfEncounterTime ca/kai/fhir/converter/r4/EncounterConverter.java + ca/kai/caseManagementNote/CaseManagementNote.java:112-117
11 InvoiceConverter.getInvoiceStatus default: branch throws InvalidRequestException on unknown Oscar status (fragile for new billing status codes) ca/kai/fhir/converter/r4/InvoiceConverter.java:535-539