> ## Documentation Index
> Fetch the complete documentation index at: https://help.clinikehr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Set up a barcode scanner

> Plug in a till scanner, scan with a webcam, put barcodes on your products, and know which device does what.

export const StillStuck = ({topic}) => <div className="ck-callout ck-callout--note" role="note">
    <p className="ck-callout__body">
      <strong>Still stuck{topic ? ` with ${topic}` : ''}?</strong>{' '}
      Check <a href="/platform/help/troubleshooting">Troubleshooting</a> first —
      it covers the failures we see most often. If that does not resolve it,{' '}
      <a href="/platform/help/contact-support">contact support</a> and include
      your workspace name and the time the problem happened, so we can find the
      matching entry in your audit log.
    </p>
  </div>;

export const TaskHeader = ({before, time, after}) => <div className="ck-task">
    {before ? <div className="ck-task__cell">
        <div className="ck-task__title">Before you start</div>
        <p className="ck-task__body">{before}</p>
      </div> : null}

    {time ? <div className="ck-task__cell">
        <div className="ck-task__title">Takes about</div>
        <p className="ck-task__body">{time}</p>
      </div> : null}

    {after ? <div className="ck-task__cell">
        <div className="ck-task__title">When you're done</div>
        <p className="ck-task__body">{after}</p>
      </div> : null}
  </div>;

export const Path = ({steps = []}) => <span className="ck-path">
    {steps.map((s, i) => <span key={i} className="ck-path__step">
        {i > 0 ? <span className="ck-path__sep" aria-hidden="true">
            ›
          </span> : null}
        {s}
      </span>)}
  </span>;

export const Availability = ({editions = ['all'], plans, roles, note}) => {
  const list = editions.includes('all') ? ['clinic', 'pharmacy', 'lims'] : editions;
  return <div className="ck-avail" role="note" aria-label="Feature availability">
      <span className="ck-avail__label">Available in</span>

      {list.map(e => <span key={e} className={`ck-pill ck-pill--${e}`}>
          {EDITION_LABELS[e] || e}
        </span>)}

      {plans ? <span className="ck-avail__label">Plan</span> : null}
      {plans ? <span className="ck-pill ck-pill--plan">{plans}</span> : null}

      {roles ? <span className="ck-avail__label">Who</span> : null}
      {roles ? <span className="ck-pill ck-pill--role">{roles}</span> : null}

      {note ? <span className="ck-avail__note">{note}</span> : null}
    </div>;
};

<Availability editions={['pharmacy']} plans="All plans" roles="Any staff member at the till" />

Two very different devices get called "the barcode scanner", and mixing them up is the reason most of this goes wrong. Decide which one you have before you read any further:

|                    | **Keyboard-wedge scanner**                                      | **Portable count terminal**                                         |
| ------------------ | --------------------------------------------------------------- | ------------------------------------------------------------------- |
| Looks like         | A handheld gun on a cable or dongle, or a fixed counter scanner | A rugged handheld with a screen and keypad, sitting in a USB cradle |
| Used for           | Selling at the till                                             | Counting stock on the shelves                                       |
| Setup in ClinikEHR | **None** — plug it in and scan                                  | Connect, then upload, in a deliberate sequence                      |
| Where it works     | Anywhere in the product                                         | Stock counts only                                                   |

<TaskHeader before="Products with a barcode saved on their catalogue entry" time="Minutes for a till scanner" after="Scanning that adds products to the cart and pulls up past sales" />

## The till scanner: nothing to install

A keyboard-wedge scanner **types what it reads**. To your computer it is a keyboard, so there is no driver to install, no pairing inside ClinikEHR and no setting to switch on.

<Steps>
  <Step title="Plug it in">
    USB or its wireless dongle. If the operating system sees a new keyboard, you are done.
  </Step>

  <Step title="Open the till">
    <Path steps={['Sidebar', 'POS']} />
  </Step>

  <Step title="Scan a product">
    You do **not** have to click into the search box first. The till listens for a scan anywhere on the page, so a cashier can scan while the cursor is nowhere in particular.
  </Step>
</Steps>

On a match you get **"Scanned: \{name}"** and the product is in the cart. On a miss: **"No medication matches that barcode"** — which nearly always means the barcode is not saved against the product yet, not that the scanner failed.

<Note>
  Scanning is ignored while you are typing in another field — an amount, a reference, a note. The characters are already landing where you put the cursor, and adding to the cart as well would leave junk in the field. Click out of the field, then scan.
</Note>

## Put barcodes on your products

A product cannot be scanned until its code is saved on its catalogue entry.

<Steps>
  <Step title="Open the item">
    <Path steps={['Sidebar', 'Inventory', 'Add item']} /> — or edit an existing item.
  </Step>

  <Step title="Fill Barcode / UPC (optional)">
    The field's placeholder is **"Scan pack, or Generate…"**. Put the cursor in it and scan the pack — that is the fastest way and it cannot mistype.
  </Step>

  <Step title="Or mint your own code">
    For a product with no barcode on the pack — a repack, a loose line, a service — select **Generate in-house code**. **Camera scan** reads a code with a webcam if you have no scanner to hand.
  </Step>
</Steps>

### Print shelf and pack labels

From an inventory row, **Print barcode label** opens a sheet with a **Copies** field. Print a strip for a shelf edge or one per repacked pack, and everything you have coded becomes scannable at the counter.

## Scan with a webcam

No hardware scanner? There is a camera button at the till and on the sales list. It needs two things a laptop usually already has: a **secure connection** ("Camera access requires HTTPS. Open this page over a secure connection to scan.") and **camera permission** ("Camera permission denied. Allow camera access in your browser settings to scan.").

It is a genuine fallback rather than a counter tool — a phone camera on a crowded shelf is slower than a scanner, and it stops the till while it focuses.

## Scan a receipt to find a sale

On the [sales list](/pharmacy/money/sales), the **Search or scan receipt...** box takes a scan of the barcode printed at the bottom of a customer's receipt and pulls the sale straight up — the fastest route into a return or a query.

Scan something that is not one and you get **"That barcode is not a ClinikEHR receipt."** A receipt printed while the till was offline carries a provisional number and no barcode at all; find those by date and amount instead. See [Print and reprint receipts](/pharmacy/pos/receipts).

## The count terminal is a different job

A portable count terminal — the CipherLab in its USB cradle — is for **stock counts, not selling**. It collects codes and quantities on the shelves, then hands them over in one upload.

It needs Chrome, Edge or the [desktop app](/pharmacy/hardware/desktop-app), and a deliberate connect-then- upload sequence rather than a plug-and-scan. The full procedure is in [Count stock with a CipherLab terminal](/pharmacy/inventory/cipherlab).

Do not try to sell with it, and do not try to count with the till scanner — see [Stock counts](/pharmacy/inventory/stock-counts).

## Check it worked

* Scanning at the till toasts **"Scanned: \{name}"** and adds a cart line.
* It works with the cursor resting nowhere in particular, not only in the search box.
* Scanning a receipt on the sales list opens the sale.

## If something goes wrong

<AccordionGroup>
  <Accordion title="'No medication matches that barcode'">
    The code is not saved against any product. Open the item in **Inventory** and fill **Barcode / UPC (optional)** by scanning the pack into the field. Every pack of the same product must carry the same code.
  </Accordion>

  <Accordion title="The code appears as typed text instead of adding to the cart">
    The cursor is in an editable field, so the characters are going there. Select somewhere neutral on the page and scan again.
  </Accordion>

  <Accordion title="Nothing happens at all when I scan">
    Confirm the scanner types at all: open any text field, scan, and see whether characters appear. If they do not, it is the device or its dongle, not ClinikEHR. If they do but the till does not react, check whether a dialog is open over the page.
  </Accordion>

  <Accordion title="The camera scanner will not start">
    It needs a secure connection and camera permission. Allow the camera in your browser's site settings and reload. On a shared till, a hardware scanner is the better answer.
  </Accordion>

  <Accordion title="'That barcode is not a ClinikEHR receipt.'">
    You scanned a product barcode, another shop's receipt, or a receipt from an offline sale that carries no barcode. Search by date and amount instead.
  </Accordion>

  <Accordion title="Two products scan to the same thing">
    Both catalogue entries carry the same code. Fix the duplicate in **Inventory**, or give the repacked line its own generated in-house code.
  </Accordion>
</AccordionGroup>

<StillStuck topic="a barcode scanner" />
