fepli
API resources

Receipts

A receipt (Beleg) records money for one or more applications of one family: a payment taken at the counter, a payment made online, an invoice that is still open, or a reversal (Storno) of an earlier receipt.

All receipt endpoints need ROLE_PAYMENTS_ADMIN. Amounts are in cents; the items of a reversal are negative.

An invoice is not a separate resource: it's a receipt that hasn't been paid yet. You create a receipt open and pay it when the money comes in, or create it paid if you take the money at the counter right away.

The receipt model

  • Name
    uuid
    Type
    string
    Description

    The receipt's identifier.

  • Name
    receiptNumber
    Type
    string
    Description

    The receipt number: the municipality's prefix followed by a running number. Assigned when the receipt is paid, so an open invoice has none yet.

  • Name
    status
    Type
    string
    Description

    created (open: an invoice, or an online payment that hasn't gone through yet), paid, failed or abandoned. See the receipt workflow.

  • Name
    totalAmount
    Type
    integer
    Description

    The sum of the items, in cents.

  • Name
    createdAt
    Type
    timestamp
    Description

    When the receipt was created.

  • Name
    billingAddress
    Type
    string
    Description

    The billing address as printed on the receipt, one line per line.

  • Name
    billingEmail
    Type
    string
    Description

    The e-mail address the receipt goes to.

  • Name
    paymentMethod
    Type
    string
    Description

    The name of the online payment method for online payments (Online-Zahlung if it isn't known), and Bargeld for every other receipt, including open invoices and reversals.

  • Name
    debtor
    Type
    object
    Description

    The family's ledger: its uuid and current balance.

  • Name
    account
    Type
    reference
    Description

    The family account.

  • Name
    recordedBy
    Type
    reference
    Description

    Who created the receipt: the colleague who recorded it, or for online payments the family's own account. Missing for receipts created by a service account.

  • Name
    items
    Type
    object[]
    Description

    The lines of the receipt. Each has a uuid, a type (attendance for an application, discount for credit used), an amount, and the attendance UUID with its offer and participant as references. On discount lines these three are null.

  • Name
    isReversal
    Type
    boolean
    Description

    Whether the receipt's total is negative, as a reversal's is. A reversal of 0 (withholding 100 %) shows false; use reversalOf to be sure.

  • Name
    reversalOf
    Type
    reference
    Description

    The receipt this one reverses. The reference's name is its receipt number.

  • Name
    reversals
    Type
    reference[]
    Description

    Receipts that reverse this one, fully or in part.

  • Name
    canBeAdjusted
    Type
    boolean
    Description

    Whether this receipt can be adjusted: a paid, unreversed counter receipt.

  • Name
    onlineTransactionId
    Type
    string
    Description

    The payment provider's transaction ID, for online payments.

  • Name
    transitions
    Type
    string[]
    Description

    The workflow transitions you can apply right now: pay and abandon for an open receipt, none otherwise.

The receipt workflow

A receipt starts open (created) and ends paid or abandoned. An open receipt is an invoice: the family owes the money, nothing is marked paid yet, and the receipt has no number. Apply a transition with POST /receipts/{uuid}/transition.

TransitionFromToWhat happens
paycreatedpaidThe money was taken. The receipt gets its number, the applications are marked paid, and the credit it uses is taken from the family's ledger.
abandoncreatedabandonedThe receipt is dropped. The applications stay unpaid.

To take money at the counter in one step, create the receipt with "paid": true.

A receipt the family was sent a payment link for is open as well, and can be paid at the counter too. Once the family starts paying online, the receipt gets an onlineTransactionId and the payment provider moves it on to paid or failed: it has no transitions for you any more.

A paid receipt doesn't change state again. To give money back, reverse it; to correct it, adjust it.


GET/receipts

List all receipts

Returns a page of receipts, newest first.

Optional filters

  • Name
    q
    Type
    string
    Description

    Only receipts whose number, billing address or billing e-mail contains this text.

  • Name
    status
    Type
    string
    Description

    Only receipts in this state: created, paid, failed or abandoned.

  • Name
    account
    Type
    string
    Description

    Only receipts of this family (UUID or e-mail address).

  • Name
    debtor
    Type
    string
    Description

    Only receipts of this debtor (UUID).

  • Name
    participant
    Type
    string
    Description

    Only receipts covering an application of this participant (UUID).

  • Name
    attendance
    Type
    string
    Description

    Only receipts covering this application (UUID).

  • Name
    edition
    Type
    string
    Description

    Only receipts covering applications in this edition (UUID or alias).

  • Name
    reversals
    Type
    boolean
    Description

    true for reversals only, false to leave them out.

  • Name
    createdSince
    Type
    timestamp
    Description

    Only receipts created since this moment.

  • Name
    page, itemsPerPage
    Type
    integer
    Description

    See Pagination.

Request

GET·/receipts
curl -G https://ferienpass-musterstadt.de/api/receipts \
  -H "Authorization: Bearer $FEPLI_TOKEN" \
  --data-urlencode "account=familie.mueller@example.org"

Response

[
  {
    "uuid": "0192e1a0-7b8c-7d9e-a0f1-2b3c4d5e6f08",
    "receiptNumber": "RE-142",
    "status": "paid",
    "totalAmount": 1250,
    "createdAt": "2026-09-10T10:22:31+02:00",
    "billingAddress": "Anna Müller\nLindenallee 12\n12345 Musterstadt",
    "billingEmail": "familie.mueller@example.org",
    "paymentMethod": "Bargeld",
    "debtor": {
      "uuid": "0191c7b4-5a6b-7c8d-9e0f-1a2b3c4d5e09",
      "balance": 0
    },
    "account": {
      "uuid": "0191c7b2-4d5e-7f60-8a1b-2c3d4e5f6a05",
      "name": "Anna Müller"
    },
    "recordedBy": {
      "uuid": "0190a1b2-c3d4-7e5f-8a6b-7c8d9e0f1a22",
      "name": "Sabine Krüger"
    },
    "items": [
      {
        "uuid": "0192e1a0-8c9d-7e0f-a1b2-c3d4e5f6a724",
        "type": "attendance",
        "amount": 750,
        "attendance": "0192d0e8-3a4b-7c5d-9e6f-7a8b9c0d1e07",
        "offer": {
          "uuid": "0192a4f1-6e3b-7c85-b1d2-8f4e6a9c3b03",
          "name": "Fahrradtour durch den Stadtpark",
          "alias": "fahrradtour-durch-den-stadtpark"
        },
        "participant": {
          "uuid": "0191c7b3-1f2a-7c4d-8e5f-6a7b8c9d0e06",
          "name": "Lena Müller"
        }
      },
      {
        "uuid": "0192e1a0-9dae-7f10-b2c3-d4e5f6a7b825",
        "type": "attendance",
        "amount": 500,
        "attendance": "0192d0f1-4b5c-7d6e-8f7a-9b0c1d2e3f23",
        "offer": {
          "uuid": "0193c8a2-5d6e-7f70-9a8b-1c2d3e4f5a14",
          "name": "Töpfern für Anfänger",
          "alias": "toepfern-fuer-anfaenger"
        },
        "participant": {
          "uuid": "0191c7b3-2e3f-7a4b-9c5d-6e7f8a9b0c16",
          "name": "Paul Müller"
        }
      }
    ],
    "isReversal": false,
    "reversals": [],
    "canBeAdjusted": true,
    "transitions": []
  }
]

GET/receipts/{uuid}

Retrieve a receipt

Returns one receipt.

Request

GET·/receipts/{uuid}
curl https://ferienpass-musterstadt.de/api/receipts/0192e1a0-7b8c-7d9e-a0f1-2b3c4d5e6f08 \
  -H "Authorization: Bearer $FEPLI_TOKEN"

POST/receipts

Create a receipt

Creates a receipt for one or more open applications of one family. By default, the receipt is open: an invoice, the Rechnung of the admin. Nothing is marked paid until you apply pay.

With "paid": true, the receipt records money taken at the counter, like Zahlung erfassen in the admin: the applications are marked paid and the receipt gets its number right away.

  • All applications must belong to the same family, be unpaid, and be in an edition that collects fees through fepli.
  • If the family has credit on their ledger, it is used first (as a discount item) unless you send "useBalance": false.
  • If an item's amount is less than the fee, the rest is booked as a claim on the family's ledger when the receipt is paid (for participants with an account).

Required attributes

  • Name
    items
    Type
    object[]
    Description

    The applications on the receipt: objects with attendance (UUID) and optionally amount in cents, from 0 up to the fee. Without amount, the full fee is charged.

Optional attributes

  • Name
    paid
    Type
    boolean
    Description

    The money was taken at the counter: the receipt is paid right away. Defaults to false, an open receipt.

  • Name
    useBalance
    Type
    boolean
    Description

    Use the family's credit. Defaults to true.

  • Name
    billingAddress
    Type
    string
    Description

    The billing address as printed on the receipt. Defaults to the family account's address, or else the participant's.

  • Name
    billingEmail
    Type
    string
    Description

    Where the receipt is sent. Defaults to the family account's e-mail address.

  • Name
    notify
    Type
    boolean
    Description

    E-mail the receipt to the family. Defaults to false. Needs paid.

Request

POST·/receipts
curl -X POST https://ferienpass-musterstadt.de/api/receipts \
  -H "Authorization: Bearer $FEPLI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "attendance": "0192d0e8-3a4b-7c5d-9e6f-7a8b9c0d1e07" },
      { "attendance": "0192d0f1-4b5c-7d6e-8f7a-9b0c1d2e3f23" }
    ]
  }'

Response (201 Created, excerpt)

{
  "uuid": "0193d2b4-6c7d-7e8f-9a0b-1c2d3e4f5a26",
  "receiptNumber": null,
  "status": "created",
  "totalAmount": 1250,
  "…": "…",
  "transitions": ["pay", "abandon"]
}

POST/receipts/{uuid}/transition

Apply a transition

Moves an open receipt through its workflow: pay when the money has been taken, abandon when the receipt is no longer needed. The receipt's transitions list the ones possible right now. Anything else is a 409 that names the possible transitions, and so is any transition on an online payment.

Before pay, the receipt is checked against what happened since it was created. If one of its applications was paid in the meantime, or the family no longer has the credit the receipt uses, the answer is 409: abandon the receipt and create a new one.

Required attributes

  • Name
    transition
    Type
    string
    Description

    pay or abandon.

Optional attributes

  • Name
    notify
    Type
    boolean
    Description

    For pay: e-mail the receipt to the family. Defaults to false.

Request

POST·/receipts/{uuid}/transition
curl -X POST https://ferienpass-musterstadt.de/api/receipts/0193d2b4-6c7d-7e8f-9a0b-1c2d3e4f5a26/transition \
  -H "Authorization: Bearer $FEPLI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"transition": "pay", "notify": true}'

Response (excerpt)

{
  "uuid": "0193d2b4-6c7d-7e8f-9a0b-1c2d3e4f5a26",
  "receiptNumber": "RE-158",
  "status": "paid",
  "totalAmount": 1250,
  "…": "…",
  "canBeAdjusted": true,
  "transitions": []
}

POST/receipts/{uuid}/reverse

Reverse a receipt

Reverses (storniert) a paid receipt, fully or in part, and returns the new reversal receipt. By default, the applications are marked unpaid again and the money is paid out. The reversal receipt is e-mailed to the billing address, as in the admin.

Only paid receipts can be reversed, and a reversal can't be reversed itself (409). An open receipt has nothing to reverse: abandon it instead. Applications that were already reversed and marked unpaid are skipped; if nothing is left to reverse, the answer is 409.

Optional attributes

  • Name
    items
    Type
    string[]
    Description

    The item UUIDs to reverse. Leave it out to reverse every application on the receipt.

  • Name
    partial
    Type
    object
    Description

    Reverse less than the full amount. {"type": "percent", "value": 20} withholds 20 % and reverses the other 80 %, for example to keep a cancellation fee. {"type": "amount", "value": 1250} reverses exactly 1250 cents. Leave it out to reverse the full amount.

  • Name
    payout
    Type
    string
    Description

    Where the money goes: payout (handed back, the default) or balance (credited to the family's ledger for later use).

  • Name
    unpay
    Type
    boolean
    Description

    Mark the applications unpaid again. Defaults to true. Send false if the money was returned for another reason and the applications stay paid.

  • Name
    withdraw
    Type
    boolean
    Description

    Also withdraw the applications. Defaults to false.

Request

POST·/receipts/{uuid}/reverse
curl -X POST https://ferienpass-musterstadt.de/api/receipts/0192e1a0-7b8c-7d9e-a0f1-2b3c4d5e6f08/reverse \
  -H "Authorization: Bearer $FEPLI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": ["0192e1a0-8c9d-7e0f-a1b2-c3d4e5f6a724"],
    "payout": "balance",
    "withdraw": true
  }'

Response (excerpt)

{
  "uuid": "0193d3c5-7d8e-7f90-8a1b-2c3d4e5f6a27",
  "receiptNumber": "RE-157",
  "status": "paid",
  "totalAmount": -750,
  "isReversal": true,
  "reversalOf": {
    "uuid": "0192e1a0-7b8c-7d9e-a0f1-2b3c4d5e6f08",
    "name": "RE-142"
  },
  "items": [
    {
      "uuid": "0193d3c5-8e9f-7a01-9b2c-3d4e5f6a7b28",
      "type": "attendance",
      "amount": -750,
      "attendance": "0192d0e8-3a4b-7c5d-9e6f-7a8b9c0d1e07",
      "…": "…"
    }
  ],
  "…": "…"
}

POST/receipts/{uuid}/adjust

Adjust a receipt

Corrects a counter receipt, for example when the wrong amount was entered. The original receipt is reversed in full and a new one is issued with the items, address and e-mail you send. Returns the new receipt.

Only paid, unreversed counter receipts can be adjusted: check canBeAdjusted. Otherwise the answer is 409.

Required attributes

  • Name
    items
    Type
    object[]
    Description

    The items of the new receipt: objects with attendance (UUID, one of the original receipt's applications) and amount in cents.

Optional attributes

  • Name
    billingAddress
    Type
    string
    Description

    The billing address. Defaults to the original receipt's.

  • Name
    billingEmail
    Type
    string
    Description

    The e-mail address. Defaults to the original receipt's.

  • Name
    paid
    Type
    boolean
    Description

    Mark the new receipt paid. Defaults to true. With false, the new receipt stays open until you pay it.

  • Name
    notify
    Type
    boolean
    Description

    E-mail the new receipt. Defaults to false. Needs paid and a billingEmail in the request.

Request

POST·/receipts/{uuid}/adjust
curl -X POST https://ferienpass-musterstadt.de/api/receipts/0192e1a0-7b8c-7d9e-a0f1-2b3c4d5e6f08/adjust \
  -H "Authorization: Bearer $FEPLI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "attendance": "0192d0e8-3a4b-7c5d-9e6f-7a8b9c0d1e07", "amount": 750 },
      { "attendance": "0192d0f1-4b5c-7d6e-8f7a-9b0c1d2e3f23", "amount": 250 }
    ]
  }'

Was this page helpful?