# Payment at the clinic

> The patient checks out at reception and pays on the device before leaving.

The visit is over and the patient is at reception. The receptionist checks out in the journal, and the payment appears on the clinic's device: the patient picks from the payment methods the clinic offers — Swish, card or invoice, for example — and pays on the spot.

- Market: Sweden (`se`). Norway differs in currency, payment methods and what happens when nobody pays: https://developers.rivr.io/guides/pay-at-clinic.md?market=no
- Language: English (`en`). Svenska: https://developers.rivr.io/guides/pay-at-clinic.md?lang=sv
- 5 min read · 6 steps
- Page in the portal: https://developers.rivr.io/guides/pay-at-clinic

Every example targets the sandbox (`https://api.test.rivr.io`) and needs test credentials. A platform client's tokens come from `https://auth.test.rivr.io`, an organisation key's from `https://auth.test.rivr.tech`.

## 1. Pick the device

*Journal system → Rivr*

`GET /api/public/devices` lists the clinic's devices with `id`, name and `isOnline`. A device counts as online if it has checked in within the last two minutes.

**What your system does:** Let the clinic tie a device to each reception desk or checkout counter in your system, so the right one is chosen without anyone having to think.

**Request:** `GET /api/public/devices` · Merchant token · [Reference](https://developers.rivr.io/reference/api-public/getDevices.md)

```bash
curl -X GET https://api.test.rivr.io/api/public/devices \
  -H "Authorization: Bearer $MERCHANT_TOKEN"
```

## 2. Create the order — for the device

*Journal system → Rivr*

Create the order with `PUT /api/public/orders/{id}` and add the `device` hint with the device's id. If the device is online, the order goes straight to it.

You choose the order id yourself. Amounts are **in kronor (kroner in Norway), excluding VAT,** per line.

**Why:** Without the hint the order goes to a device only if the clinic's flow has a device step, and then to the only device online or to the default device. That works for a clinic with one reception desk — not for one with three.

**What your system does:** Store the order id on the visit before you call Rivr. If you lose the response, fetch the order with `GET` on the same id. If it already exists you are done — the same id can never become two orders.

> **Note.** In the standard flow the patient **also** gets a text with a payment link at the same moment, so they can pay on their phone if they prefer. If no text should go out, send the `disableNotifications` hint with the value `"true"`. Then no reminder is sent either, but the clinic's invoice step still runs if the order stays unpaid.

**Order status:** `Created` · **The journal shows:** Unpaid

**Request:** `PUT /api/public/orders/7b1e7c3a-2f4d-4a51-9c7e-5d0a6b8e2c14` · Merchant token · [Reference](https://developers.rivr.io/reference/api-public/createOrder.md)

```bash
curl -X PUT https://api.test.rivr.io/api/public/orders/7b1e7c3a-2f4d-4a51-9c7e-5d0a6b8e2c14 \
  -H "Authorization: Bearer $MERCHANT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "id": "7b1e7c3a-2f4d-4a51-9c7e-5d0a6b8e2c14",
  "merchantId": "MERCHANT_ID",
  "reference": "visit-48213",
  "personalNumber": "195001182046",
  "phone": "+46701740605",
  "email": "patient@example.com",
  "currencyCode": "SEK",
  "orderLines": [
    {
      "description": "Samtal 45 min",
      "quantity": 1,
      "unitPriceExclVat": 950,
      "vatPercentage": 0,
      "discountExclVat": 0
    }
  ],
  "checkoutHints": [
    { "type": "device", "value": "DEVICE_ID" }
  ],
  "callbackUrl": "https://journal.example.com/webhooks/rivr",
  "metadata": { "bookingId": "48213" }
}'
```

## 3. Rivr confirms

*Rivr → Journal system*

The `Created` webhook confirms the order exists at Rivr.

**What your system does:** Show the visit as unpaid and waiting for the patient. No bookkeeping yet.

**Order status:** `Created` · **The journal shows:** Unpaid

**Webhook to you** (`Created`)

```http
POST /webhooks/rivr
Content-Type: application/json
Rivr-Signature: t=1789640080,v1=5f2b0c…

{
  "id": "7b1e7c3a-2f4d-4a51-9c7e-5d0a6b8e2c14",
  "type": "Order",
  "merchantId": "MERCHANT_ID",
  "status": "Created",
  "data": {
    "CreatedDate": "2026-09-17T09:12:03Z",
    "Reference": "visit-48213",
    "Metadata": { "bookingId": "48213" }
  }
}
```

## 4. The patient pays on the device

*Patient → Rivr · +1 min*

The patient sees the amount on the device, picks a payment method and pays. Invoice is shown once the patient's identity is verified, and the credit check happens when they choose it.

**In the portal:** [Play the patient on a virtual device](https://developers.rivr.io/device)

## 5. Paid — the Completed webhook

*Rivr → Journal system*

With card or Swish `Completed` arrives within seconds, and with invoice or instalments approved by the financing partner once the approval is done — with `PaymentMethod` set. From now on Rivr carries the receivable.

**What your system does:** Mark the visit as paid and move the receivable from the patient to Rivr in the books.

> **Warning.** Not every payment method is paid on the spot. If it becomes an invoice with recourse, or financing not yet paid out, `Pending` arrives first — and `Completed` later. See the guide on when the patient doesn't pay right away.

**Order status:** `Completed` · **The journal shows:** Paid

**Webhook to you** (`Completed`)

```http
POST /webhooks/rivr
Content-Type: application/json
Rivr-Signature: t=1789640080,v1=5f2b0c…

{
  "id": "7b1e7c3a-2f4d-4a51-9c7e-5d0a6b8e2c14",
  "type": "Order",
  "merchantId": "MERCHANT_ID",
  "status": "Completed",
  "data": {
    "CreatedDate": "2026-09-17T09:12:03Z",
    "Reference": "visit-48213",
    "CompletedDate": "2026-09-17T09:14:40Z",
    "PaymentMethod": "Card",
    "Metadata": { "bookingId": "48213" }
  }
}
```

## 6. Send to the device afterwards

*Journal system → Rivr*

If the order was created before the patient reached reception, send it to the device with `POST /api/public/orders/{id}/send-to-device`. A `202` means it is on its way.

> **Note.** `409` — the device is not online. `400` — the order is no longer unpaid, or the device belongs to another clinic.

**Request:** `POST /api/public/orders/7b1e7c3a-2f4d-4a51-9c7e-5d0a6b8e2c14/send-to-device` · Merchant token · [Reference](https://developers.rivr.io/reference/api-public/sendOrderToDevice.md)

```bash
curl -X POST https://api.test.rivr.io/api/public/orders/7b1e7c3a-2f4d-4a51-9c7e-5d0a6b8e2c14/send-to-device \
  -H "Authorization: Bearer $MERCHANT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "deviceId": "DEVICE_ID" }'
```

## Common pitfalls

- Marking the visit as paid when the call to Rivr succeeds. `201` means the order exists — not that it is paid.
- Creating a new order when the patient wants to try again after an aborted attempt. Send the same order to the device again.
- Assuming the order is done when the patient leaves without paying. It continues along the clinic's flow, with a reminder and an invoice. See the next guide.

## Next guide

- [Payment on the phone](https://developers.rivr.io/guides/pay-by-link.md): The patient gets a payment link by SMS and pays whenever it suits them.
- [Bookkeeping and payouts](https://developers.rivr.io/guides/bookkeeping.md): Two entries per order: when it is paid, and when the money reaches the bank.
