Skip to main content

Service Request Lifecycle

Service Requests (FHIR ServiceRequest) are the core workflow resource in CareLaunch. They represent requests for healthcare services — referrals, service orders, and registration workflows that may require scheduling, payment, or both.

This document describes every status a ServiceRequest can hold, what triggers each transition, and what side effects occur.

Statuses

CareLaunch uses the standard FHIR R4 RequestStatus values:

StatusDisplay NameDescription
draftDraftCreated but not yet submitted. Used during registration workflows while the patient completes scheduling and/or payment steps.
activeActive (Open)Open and awaiting fulfillment by a provider. The request has been submitted and is ready to be acted upon.
on-holdOn HoldTemporarily paused by an administrator. The request is not being actively worked but has not been cancelled.
completedCompletedThe requested service has been fulfilled. This is a terminal state — no further status changes are allowed from the UI.
revokedCancelledThe request has been cancelled or withdrawn by the patient or system. Associated appointments are automatically cancelled.
entered-in-errorErrorRecorded by mistake. This is a terminal state — no further status changes are allowed from the UI.

Status Flow Diagram

stateDiagram-v2
[*] --> draft : Patient starts registration/workflow
[*] --> active : Direct creation (no workflow steps)

draft --> active : Payment completed (auto)\nOR workflow completed\nOR admin manual update
draft --> revoked : Patient dismisses workflow\nOR workflow expires

active --> on_hold : Admin pauses request
active --> completed : Admin marks fulfilled
active --> revoked : Admin cancels request
active --> entered_in_error : Admin marks as error

on_hold --> active : Admin resumes request

completed --> [*]
revoked --> [*]
entered_in_error --> [*]

state "draft" as draft
state "active" as active
state "on-hold" as on_hold
state "completed" as completed
state "revoked" as revoked
state "entered-in-error" as entered_in_error

Transition Details

Creation → draft

Trigger: Patient initiates a registration workflow (portal or microsite) that includes scheduling and/or payment steps.

  • A ServiceRequest is created with status: draft and intent: order.
  • A workflow-metadata FHIR extension is attached containing:
    • requiresScheduling — whether the patient must book an appointment
    • requiresPayment — whether the patient must complete payment
    • workflowCreatedAt — timestamp of workflow initiation
    • workflowExpiresAt — expiration timestamp (auto-dismissed after this time)
    • workflowType — type of workflow (e.g., service_request)
    • paymentProductId, healthcareServiceId, healthcareServiceName — context for resumption
  • The patient's managing organization is set as the requester for automation filtering.

Creation → active

Trigger: Direct creation via the admin UI or API without workflow steps, or when requiresScheduling and requiresPayment are both false.

  • Default status is active when created through the POST /api/ServiceRequest endpoint without an explicit status.
  • The intent defaults to order and authoredOn is set to the current UTC time.

draftactive

Triggers:

  1. Payment completed (automatic): When a Stripe checkout session completes and the linked ServiceRequest has status: draft, the payment status extension is set to paid and the status is automatically promoted to active.
  2. Workflow completed: When a patient finishes all required workflow steps (scheduling + payment), the registration controller sets status to active.
  3. Admin manual update: An administrator can change status to active via the admin UI (PUT endpoint, requires admin role).

Side effects:

  • Automation triggers configured for "Resource Update" on ServiceRequest will fire.

draftrevoked

Triggers:

  1. Patient dismisses workflow: The patient clicks "Dismiss" on an incomplete workflow in the portal or during registration. Calls POST /api/ServiceRequest/{id}/dismiss or POST /api/Registration/workflow/{id}/dismiss.
  2. Workflow expires: When a patient returns to the portal and the workflowExpiresAt timestamp has passed, the system automatically sets the status to revoked during the incomplete-workflow check.

Side effects:

  • All non-terminal appointments linked via based-on reference are cancelled with reason service-request-dismissed.
  • Scheduled reminders and late/no-show checks for those appointments are cancelled.
  • Automation triggers for "Resource Update" on ServiceRequest will fire.

activeon-hold

Trigger: Administrator manually changes status via the admin UI.

Side effects: None beyond the status change. The request remains visible but is not actively being worked.

activecompleted

Trigger: Administrator marks the service request as fulfilled via the admin UI.

Side effects:

  • Status becomes terminal — no further changes allowed from the UI.
  • Automation triggers for "Resource Update" on ServiceRequest will fire.

activerevoked

Trigger: Administrator cancels the request via the admin UI.

Side effects:

  • Automation triggers for "Resource Update" on ServiceRequest will fire.

activeentered-in-error

Trigger: Administrator marks the request as entered in error via the admin UI.

Side effects:

  • Status becomes terminal — no further changes allowed from the UI.

on-holdactive

Trigger: Administrator resumes a paused request via the admin UI.

Deletion

Trigger: Administrator deletes a ServiceRequest via DELETE /api/ServiceRequest/{id} (requires admin role).

  • The resource is permanently removed from the FHIR data store.
  • Automation triggers for "Resource Delete" on ServiceRequest will fire.

Payment Status (Extension)

In addition to the FHIR status, ServiceRequests that involve payment carry a custom extension tracking payment progress:

Extension URL: http://orbital.health/fhir/extension/payment-status

Payment StatusDescription
paidPayment successfully completed via Stripe. Automatically promotes draftactive.
unpaidPayment has not yet been made (default when payment is required).
pendingPayment is being processed.
refundedPayment was refunded via Stripe. Set automatically on charge.refunded or charge.dispute.created webhook events.
failedPayment attempt failed. Set on checkout.session.async_payment_failed or payment_intent.payment_failed webhook events.
expiredCheckout session expired before payment was completed. Set on checkout.session.expired webhook event.
not-requiredThe service does not require payment (determined by requiresPayment: false in workflow metadata).

Payment Status Transitions

stateDiagram-v2
[*] --> unpaid : ServiceRequest created with payment required
[*] --> not_required : ServiceRequest created without payment

unpaid --> paid : checkout.session.completed
unpaid --> expired : checkout.session.expired
unpaid --> failed : payment_intent.payment_failed

paid --> refunded : charge.refunded / charge.dispute.created

expired --> paid : Patient retries and succeeds
failed --> paid : Patient retries and succeeds

state "unpaid" as unpaid
state "paid" as paid
state "refunded" as refunded
state "failed" as failed
state "expired" as expired
state "not-required" as not_required

Payment Side Effects

When payment status changes to paid:

  • The ServiceRequest status is promoted from draft to active (if currently draft).
  • If the ServiceRequest has a linked appointment with a stored appointmentStatusAfterPayment value, the appointment status is updated accordingly.
  • Post-payment appointment notifications are sent.

When payment status changes to refunded:

  • The related Invoice status is updated.
  • No automatic change to the ServiceRequest FHIR status.

When payment status changes to failed or expired:

  • No automatic change to the ServiceRequest FHIR status.
  • The patient can retry payment from the portal.

Automation Integration

ServiceRequests participate in the CareLaunch automation engine:

  • Resource Creation trigger: Fires when a new ServiceRequest is created. Can be configured to create follow-up resources (tasks, communications, observations) automatically.
  • Resource Update trigger: Fires when a ServiceRequest is updated (including status changes). Useful for notifications when requests move to active or completed.
  • Resource Delete trigger: Fires when a ServiceRequest is deleted.

Automations can filter on the ServiceRequest's requester field (populated with the patient's managing organization) for organization-scoped automation rules.

Workflow Recovery

When a patient abandons a registration workflow mid-process, the draft ServiceRequest persists with its workflow metadata. When the patient returns:

  1. The portal checks for incomplete workflows via GET /api/ServiceRequest/incomplete or GET /api/Registration/workflow.
  2. Draft ServiceRequests with workflow-metadata extensions are returned, along with completion status for each step (scheduling, payment).
  3. Expired workflows (past workflowExpiresAt) are automatically dismissed (status set to revoked).
  4. The patient can resume from where they left off or dismiss the workflow.

Access Control

ActionWho Can Perform
CreateAny authenticated user (patient or admin)
Read (own)Patient who is the subject, or proxy via RelatedPerson
Read (any)Platform Admin, Organization Admin, Instance Admin
Update statusPlatform Admin, Organization Admin, Instance Admin, Base Admin
Update subject (draft only)Patient who is the current subject (for dependent scheduling)
Dismiss workflowPatient who is the subject (or proxy)
Complete workflowPatient who is the subject (or proxy)
DeletePlatform Admin, Organization Admin, Instance Admin, Base Admin

Edge Cases

State-Based Service Restrictions

When a HealthcareService has coverageStates configured, ServiceRequest creation is blocked if the patient's home address state is not in the allowed list.

Unpaid Invoice Enforcement

When the requirePaidInvoices query parameter is set to true during creation, the system checks for outstanding invoices (status draft or issued) and blocks creation if any exist.

Race Conditions

The payment processing system handles race conditions between checkout session completion and expiration events. If a ServiceRequest already has payment status paid or refunded, expiration updates are skipped to prevent incorrect status regression.

Subject Updates

Only draft ServiceRequests can have their subject (patient) updated. This supports dependent scheduling workflows where a parent starts the workflow and then selects a dependent as the actual patient.