# NPHIES Integration Plan — Moon ERP LIS

> Last updated: 2026-04-02
> Status: Backend tasks sent (#1461-#1467), Frontend tasks (#1468-#1472)
> Simulator: https://moonui.elbaset.com/nphies/

---

## What is NPHIES?

NPHIES (National Platform for Health Information Exchange) is Saudi Arabia's national eClaims platform. It handles insurance eligibility, prior authorization, claims, and payment — NOT clinical data exchange.

- **Protocol**: HL7 FHIR R4.0.1 Messaging (NOT REST)
- **Endpoint**: `POST https://hsb.nphies.sa/$process-message`
- **Auth**: OAuth 2.0 + mTLS (X.509 certificates)
- **Operator**: Council of Health Insurance (CHI)
- **IG**: https://portal.nphies.sa/ig/

---

## Feature Flag

```
Setting: nphies_enabled (boolean, default: false)

OFF (Egypt mode): Zero NPHIES UI, zero NPHIES API, zero Saudi ID fields
ON (Saudi mode):  Everything activates
```

---

## Lab Flow — Before vs After NPHIES

### Current Flow (Egypt — no changes)
```
Patient → Request Wizard → Samples → Collection → Kanban → Results → Release → Invoice → Payment
```

### Saudi Flow (NPHIES enabled)
```
Patient ──────→ Request Wizard ──→ Samples → Collection → Kanban → Results → Release
  │                  │
  │ +Saudi ID        │ Step 3: Billing
  │ +Iqama           │    │
  │                  │    ▼
  │              ┌──────────────────┐
  │              │ NPHIES Eligibility│ ◄── POST /api/nphies/eligibility
  │              │ "مغطى ✓ تعاونية" │
  │              └───────┬──────────┘
  │                      │
  │                      ▼
  │              ┌──────────────────┐
  │              │  Invoice Created  │
  │              │                  │
  │              │ [Request Auth]   │ ◄── POST /api/nphies/preauth
  │              │  PA-123456 ✓     │
  │              │                  │
  │              │ (after release)  │
  │              │ [Submit Claim]   │ ◄── POST /api/nphies/claim
  │              │  132 SAR covered │
  │              │  33 SAR copay    │
  │              └──────────────────┘
```

---

## What Changes Where (Frontend)

### 1. Patient Form — `lis-patients.component.ts`
**Type**: Small modification (3 fields)
**What**:
```
+ID Type dropdown:     National ID | Iqama | Passport | Visa
+ID Number input:      10 digits (validated by type)
+Passport Country:     ISO dropdown (only when type=passport)
```
**Condition**: `@if (nphiesEnabled())` — hidden in Egypt mode
**Validation**: 
- National ID: 10 digits, starts with `1`
- Iqama: 10 digits, starts with `2`
- When NPHIES ON: national_id is **required**

### 2. Request Wizard Step 3 — `request-wizard-v2.component.ts`
**Type**: Medium modification
**What**: When user selects "Insurance" billing type:
```
┌─────────────────────────────────────────┐
│ ⚡ Checking NPHIES eligibility...       │ ← auto-trigger
│                                         │
│ ✓ مغطى — التعاونية | Gold-A | VIP      │ ← green banner
│   Member: MEM-00123                     │
│   Coverage: 500,000 SAR                 │
└─────────────────────────────────────────┘
```
Or:
```
┌─────────────────────────────────────────┐
│ ✗ غير مغطى                             │ ← red banner
│   [متابعة بدون NPHIES]                  │ ← manual override
└─────────────────────────────────────────┘
```
**API**: `POST /api/nphies/eligibility { patient_id, insurer_code, service_date }`
**Condition**: Only when `nphiesEnabled()` AND billing = insurance

### 3. Invoices Page — `lis-invoices.component.ts`
**Type**: Medium modification
**What**: Add buttons + columns to existing invoice table

New buttons per invoice row:
```
[طلب موافقة NPHIES]  → POST /api/nphies/preauth
[إرسال مطالبة]       → POST /api/nphies/claim (only after results released)
[عرض FHIR]           → dialog showing request/response JSON
```

New columns:
```
| ... | NPHIES Status | المغطى  | حصة المريض |
| ... | معتمد PA-123  | 132 SAR | 33 SAR     |
```

Status badges:
- `معلق` (yellow) — waiting
- `معتمد` (blue) — preauth approved + ref number  
- `مرسل` (green) — claim submitted + amounts
- `مرفوض` (red) — rejected + reason

**Condition**: Buttons only show when `nphiesEnabled()` AND invoice has insurance

### 4. Dashboard — `lis-dashboard.component.ts`
**Type**: Small addition
**What**: New card "NPHIES Today"
```
┌─────────────────────────┐
│ NPHIES Today            │
│                         │
│ 15 تحقق تأمين           │
│ 12 موافقة مسبقة         │
│ 8 مطالبة مرسلة          │
│ 4,250 SAR مغطى          │
└─────────────────────────┘
```
**Condition**: `@if (nphiesEnabled())`

### 5. NPHIES Settings — **NEW PAGE**
**Route**: `/lab/settings/nphies`
**Sidebar**: Under existing Settings group (only when `nphiesEnabled()`)

Sections:
1. **Connection**: Provider License, Facility ID, Sandbox toggle, Certificate upload, Test button
2. **Code Mapping**: Table of investigations with SBSCS codes (inline edit)
3. **Transaction Log**: Recent transactions with JSON viewer

### 6. Transaction Log — **NEW PAGE**
**Route**: `/lab/nphies-log`
**Sidebar**: Under Operations group (only when `nphiesEnabled()`)

Content:
- Summary cards (today's totals)
- Full transaction table with FHIR Bundle viewer
- Filters: type, status, date, patient
- Export to Excel

---

## What Changes Where (Backend)

### New Tables
```sql
nphies_config
├── company_id, provider_license, facility_nphies_id
├── sandbox_mode (default: true)
├── certificate_path, key_path

nphies_transactions
├── company_id, type (eligibility/preauth/claim/cancel/poll)
├── bundle_id, request_json, response_json
├── status (sent/success/error/timeout)
├── patient_id, lab_request_id

nphies_preauths
├── company_id, lab_request_id, patient_id
├── preauth_ref, status (pending/approved/denied/expired)
├── valid_from, valid_to, approved_amount
```

### Modified Tables
```sql
lab_patients
├── +national_id VARCHAR(20)
├── +national_id_type ENUM(national-id, iqama, passport, visa, border-number)
├── +passport_country VARCHAR(3)

lab_investigations
├── +sbscs_code VARCHAR(15)

lab_invoices
├── +nphies_claim_status ENUM(pending, authorized, claimed, rejected, paid)
├── +nphies_preauth_ref VARCHAR(100)
├── +nphies_covered_amount DECIMAL(12,3)
├── +nphies_copay_amount DECIMAL(12,3)
```

### New API Endpoints
```
GET    /api/nphies/config
PUT    /api/nphies/config
POST   /api/nphies/config/test-connection
POST   /api/nphies/config/upload-certificate

POST   /api/nphies/eligibility
POST   /api/nphies/preauth
POST   /api/nphies/claim
POST   /api/nphies/cancel
POST   /api/nphies/poll
POST   /api/nphies/submit-document

GET    /api/nphies/transactions
GET    /api/nphies/transactions/{id}
```

### Core Service: NphiesFhirClient
```php
class NphiesFhirClient
{
    // Builds FHIR Bundle (type=message) with MessageHeader
    public function buildBundle(string $eventCode, array $resources): array;
    
    // Sends to $process-message with mTLS
    public function send(array $bundle): array;
    
    // Specific builders
    public function buildEligibilityRequest(Patient $patient, string $insurerCode): array;
    public function buildPreAuthRequest(LabRequest $request, array $investigations): array;
    public function buildClaimRequest(LabInvoice $invoice, string $preAuthRef): array;
    
    // Parsers
    public function parseEligibilityResponse(array $bundle): EligibilityResult;
    public function parseClaimResponse(array $bundle): ClaimResult;
}
```

---

## Coding Systems Required

| Type | System | Example |
|------|--------|---------|
| Lab Tests (billing) | SBSCS v3.0 (9-digit) | `920010101` (CBC) |
| Lab Tests (identification) | LOINC | `57021-8` (CBC) |
| Diagnoses | ICD-10-AM | `Z00.0` (General exam) |
| Patient ID | NPHIES identifier types | `national-id`, `iqama` |
| Currency | SAR | `165.00` |
| Provider | NPHIES provider license | `PR-MOON-001` |
| Insurer | NPHIES payer license | `INS-TWN` |

---

## FHIR Bundle Structure

Every NPHIES message is a `Bundle (type=message)` sent via `POST $process-message`:

```
Bundle
├── MessageHeader (event code, sender, destination)
├── [Main Resource] (CoverageEligibilityRequest / Claim / etc.)
├── Patient (with Saudi identifier)
├── Coverage
├── Organization (Provider)
├── Organization (Insurer)
└── [Optional: Location, Practitioner, DocumentReference]
```

### Message Events
| Request | Response |
|---------|----------|
| `eligibility-request` | `eligibility-response` |
| `priorauthorization-request` | `priorauthorization-response` |
| `claim-request` | `claim-response` |
| `cancel-request` | `cancel-response` |
| `poll-request` | `poll-response` |

---

## Implementation Order

### Phase 1 — Backend Foundation (Ahmed)
1. ✅ #1461: Module setup + config + migrations
2. ✅ #1462: Patient Saudi identifiers
3. ✅ #1463: SBSCS code mapping

### Phase 2 — Backend APIs (Ahmed)
4. ✅ #1464: Eligibility API
5. ✅ #1465: Prior Authorization API
6. ✅ #1466: Claim API
7. ✅ #1467: Polling + Cancel + Documents

### Phase 3 — Frontend (after backend done)
8. #1468: Settings page
9. #1469: Patient Saudi ID fields
10. #1470: Eligibility in wizard
11. #1471: PreAuth + Claim on invoice
12. #1472: Transaction log + dashboard

### Phase 4 — Sandbox Testing
- Register with CHI: `onboarding@chi.gov.sa`
- Complete NPHIES Academy course
- Get sandbox credentials + certificate
- Test full flow against real sandbox

---

## Resources

| Resource | URL |
|----------|-----|
| NPHIES IG (primary) | https://portal.nphies.sa/ig/ |
| NPHIES Academy | https://academy.nphies.sa/ |
| IPSAR Sandbox | https://ipsar.chi.gov.sa/en/sandbox/ |
| Developer Portal | https://devportal.nhic.gov.sa/ |
| CHI Official | https://www.chi.gov.sa/ |
| Onboarding Email | onboarding@chi.gov.sa |
| Phone | 920033808 |
| GitHub Reference | https://github.com/Fadil369/NPHIES |
| PHP FHIR Library | https://github.com/dcarbone/php-fhir |
| **Our Simulator** | https://moonui.elbaset.com/nphies/ |
| **Investigations Seed** | src/assets/data/investigations-seed.json (688 tests, LOINC codes) |

---

## Compliance Checklist

- [ ] CBAHI lab accreditation
- [ ] NPHIES Academy certificate (free, 2 hours)
- [ ] NPHIES onboarding application
- [ ] X.509 certificate obtained
- [ ] SBSCS codes mapped for all investigations
- [ ] LOINC codes mapped (✅ 94% done in seed)
- [ ] ICD-10-AM diagnosis codes added
- [ ] Sandbox conformance testing passed
- [ ] PDPL data privacy compliance
- [ ] Go-live activation
