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 Polaris 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 PolarisCoreInvoice profile
  2. Three extensions on Invoice: oscarBillingStatus, shadowBill, and serviceLocation (reference to a PolarisCoreLocation 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 PolarisCorePractitioner
  4. Code-system aliases for OHIP Schedule of Benefits, OHIP diagnostic codes, and ICD-9

Project Details

Field Value
Ticket NPD-213 — Jarvis Billing Recommendation with OSCAR context
Product Manager Diana Gaebel
Project Manager TBD
Designer TBD
Technical Lead TBD
FHIR Experts Ramesh Dhanoa (MTG-069 owner)
Operations Polaris Platform Team
Target Date 2026-06-24
Phase 1 Scope Ontario (OHIP) + Oscar Pro only

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 (Polaris 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

  • Oscar to FHIR — field-by-field mapping from Oscar source tables to FHIR Invoice / Condition / Practitioner / Patient / Encounter resources
  • FHIR to Oscar — reverse mapping for write-back (Jarvis → Oscar billing module)
  • Write-Back Design — open questions + decision log for the Jarvis → Oscar round-trip (MTG-076)

Extension URL Provenance

Polaris 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 PolarisCoreLocation 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 Polaris 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(PolarisCoreLocation) 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 for MTG-073: should Polaris 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.

Ticket Owner Purpose
MTG-069 Ramesh Fill Polaris FHIR IG billing gaps (this feature)
MTG-071 Ryan Identify source tables (complete — v2.4)
MTG-072 Formal FHIR mapping artifact (this page supersedes)
MTG-073 Update Polaris FHIR IG (this feature)
MTG-074 Build/extend Oscar pipeline converters
MTG-076 Jarvis → Oscar write-back round-trip design (blocks MTG-074, MTG-075)

Open Questions / Escalations

  • [ ] Rejected-claim handling in Phase 1? — NPD-213 acceptance criteria states "rejection reason and suggested correction" must be surfaced. MTG-071 v2.4 and this feature defer Oscar's raDetail / remittance-advice integration to Phase 2. Escalated to Muhammad 2026-04-21; sign-off needed that Phase 1 ships without the rejection loop, or MTG-074 scope expands significantly (risks 2026-06-24 target).
  • [ ] Invoice.status draft state for provider-review intermediate? — write-back design (MTG-076) 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 MTG-071 v2.4 §Payment-model Detection.

Known Converter Gaps (to be addressed in MTG-074)

All file:line references are absolute paths under /Users/ryanwatson/work/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