Skip to main content

Medication Cart

Beta

The ScriptSure integration is in beta. Features and APIs may change.

The MedCart flow lets a clinician stage several prescriptions during one encounter and approve them all in a single signing session—instead of opening a separate widget per drug. The flow is:

  1. Add draft MedicationRequests to the cart one at a time as the clinician selects drugs.
  2. Checkout—stage all drafts on ScriptSure's MedCart and get back a single widget URL.
  3. Prescriber opens the widget, reviews every drug, and signs them all at once.
  4. Remove or clear if the clinician changes their mind before signing.

The patient must be synced before calling checkout. See Sync a Patient.

React hook: useScriptSureCart

Package: @medplum/scriptsure-react · GitHub Source Code

A thin wrapper around useMedicationCart from @medplum/react-hooks that exposes all cart operations in a single hook.

import { useState } from 'react';
import { useScriptSureCart } from '@medplum/scriptsure-react';
import type { MedicationRequest } from '@medplum/fhirtypes';

function CartPanel({ patientId }: { patientId: string }) {
const { addToCart, adding, checkout, removeFromCart, clearCart } = useScriptSureCart();
const [approvalUrl, setApprovalUrl] = useState<string>();
const [draftIds, setDraftIds] = useState<string[]>([]);

async function handleAdd(medicationRequest: MedicationRequest) {
const created = await addToCart(medicationRequest);
setDraftIds((prev) => [...prev, created.id!]);
}

async function handleCheckout() {
const result = await checkout({ patientId, medicationRequestIds: draftIds });
const queued = result.items.filter((i) => i.status === 'queued');
if (queued.length > 0) {
setApprovalUrl(result.approvalUrl);
}
}

if (approvalUrl) {
return <iframe src={approvalUrl} width="100%" height="800px" />;
}

return (
<div>
<button onClick={handleCheckout} disabled={adding || draftIds.length === 0}>
Review &amp; sign all ({draftIds.length})
</button>
<button onClick={() => clearCart({ patientId })}>Clear cart</button>
</div>
);
}

addToCart

Creates a draft MedicationRequest in Medplum via plain FHIR createResource—no custom operation is called. Vendor staging (ScriptSure MedCart) happens later at checkout. The adding flag is true while any addToCart call is in flight; checkout refuses to proceed while adding is true.

Parameters:

ParameterTypeDescription
medicationRequestMedicationRequestThe draft MedicationRequest to persist. Should have status: 'draft' and intent: 'order'.

Returns: Promise<MedicationRequest>—the created resource with its Medplum-assigned id.

checkout

Calls POST /fhir/R4/MedicationRequest/$checkout-medications. Stages each draft on ScriptSure's MedCart and returns a single widget URL where the prescriber reviews and signs all medications at once.

Per-line failures are returned in items rather than thrown—check items[].status before opening the widget. Each successfully staged draft is stamped with a medcart-rx-id identifier and pending-order-status: in-cart. When the prescriber sends from the widget, the prescription webhook bot reconciles each draft to active.

Request fields:

FieldTypeRequiredDescription
patientIdstringyesMedplum Patient resource id
medicationRequestIdsstring[]yesDraft MedicationRequest ids to stage
appIdstringOptional MedCart widget template id

Response fields:

FieldTypeDescription
approvalUrlstringMedCart widget URL—embed as an iframe for the prescriber to review and sign all staged items
vendorPatientIdnumberVendor-side patient id
itemsMedicationCheckoutItemResult[]Per-line result (see below). Always returned even when some lines failed.

Each items entry:

FieldTypeDescription
medicationRequestIdstringMedplum MedicationRequest id
vendorLineIdstringMedCart rxId for the staged item
status'queued' | 'failed'queued = successfully staged; failed = see error
duplicatebooleantrue when the drug was already in the MedCart; the existing item is reused
errorstringPresent when status === 'failed'
note

Do not open the approvalUrl if every item has status: 'failed'.

removeFromCart

Calls POST /fhir/R4/MedicationRequest/$remove-cart-medication. Removes one item from the MedCart and deletes the corresponding draft MedicationRequest from Medplum.

Request fields:

FieldTypeRequiredDescription
patientIdstringyesMedplum Patient resource id
medicationRequestIdstringyesDraft MedicationRequest id to remove

Response fields:

FieldTypeDescription
vendorPatientIdnumberVendor-side patient id
removedCountnumberNumber of items successfully removed (0 or 1)
itemsMedicationCartItemResult[]Single-item array with status: 'removed' or status: 'failed'

clearCart

Calls POST /fhir/R4/MedicationRequest/$clear-cart. Removes every item from the MedCart and deletes all draft MedicationRequests for the patient. Per-line failures are returned in items rather than thrown—failed drafts are kept so the caller can retry.

Request fields:

FieldTypeRequiredDescription
patientIdstringyesMedplum Patient resource id

Response fields:

FieldTypeDescription
vendorPatientIdnumberVendor-side patient id
removedCountnumberNumber of items successfully removed
itemsMedicationCartItemResult[]Per-line result with status: 'removed' or status: 'failed'