---
title: "Undo a recorded payment"
method: POST
path: "/expenses/{id}/unpay"
tags: ["Expenses"]
---

# Undo a recorded payment

`POST /expenses/{id}/unpay`

## Request

- Base URL: `https://api.lumabill.ch/v1`
- URL: `https://api.lumabill.ch/v1/expenses/{id}/unpay`
- Auth: HTTP bearer

Undoes one payment (by `paymentId`, else the most recent). The payment journal entry is reversed with a Storno on the payment date (nothing is deleted, the Buchungsnummer series stays gap-free), bank matches are released and the payment status is recomputed. Rejected with 400 `FISCAL_YEAR_CLOSED` when the payment date lies in a closed fiscal year.

## Request body

- UnpayRequest
  - `paymentId` string, uuid: Payment to undo (from the payments list); omit to undo the most recent payment

## Response `200`

Payment undone

- PaymentResult
  - `paymentStatus` 'UNPAID' | 'PARTIALLY_PAID' | 'PAID', required
  - `amountPaid` number, double, required
  - `remaining` number, double
  - `paymentJournalEntryId` string, uuid, nullable
  - `fx` PaymentFx, nullable: Present when a payment of a foreign-currency document was converted (absent for base-currency documents and without bookkeeping). The open item is released at its current CHF book value (after any year-end revaluation, pro rata on partial payments); the difference to the CHF actually moved is the realized Kursdifferenz, booked on the FX result account with `fxKind: realized`.
    - `currency` 'CHF' | 'EUR' | 'USD' | 'GBP' | 'JPY' | 'CAD' | 'AUD' | 'SEK' | 'NOK' | 'DKK' | 'HUF': ISO 4217 code of a currency the API converts (ESTV/BAZG rates). The same list applies to every currency field of the API.
    - `fwAmount` number, double: Settled amount in the document currency
    - `exchangeRate` number, double, nullable: CHF per 1 unit of the document currency on the money leg
    - `rateSource` 'ACTUAL' | 'MANUAL' | 'BAZG'
    - `baseAmount` number, double: CHF actually moved through the payment account
    - `releasedBookValue` number, double: CHF book value released from the open item
    - `realizedFx` number, double: Realized exchange difference in CHF (positive = gain)
  - `zeroSaldoSkipped` 'PRIOR_YEAR_NOT_CLOSED' | 'FX_ACCOUNT_MISSING': Present when the payment emptied a foreign-currency account in FW but the residual CHF book value was not realized (zero-saldo rule): `PRIOR_YEAR_NOT_CLOSED` (the previous fiscal year is open, so the account has no Saldovortrag yet; close it and the residual is realized then), `FX_ACCOUNT_MISSING` (no FX result account: set one in the FX settings). The payment itself is booked.
  - `message` string

## Other responses

- `400`: Validation error
- `401`: Invalid or missing API key
- `403`: Subscription required or read-only key on a write endpoint
- `404`: Resource not found
- `429`: Rate limit exceeded
- `500`: Internal server error

---

[API](https://skmtc.dev/lumabill/apis/lumabill-api.md) · [All operations](https://skmtc.dev/lumabill/apis/lumabill-api/llms.txt) · [OpenAPI document](https://skmtc.dev/lumabill/apis/lumabill-api/revisions/e48e7099b545?raw)
