Documentation for 4.0 (pre-release). Using 3.x? See the README on main.
Skip to content

Invoice Payments (Zahlungen) ​

API wrapper for invoice payments at /invoice-payments.

Access ​

php
$billomat->invoices->payments

The generic Justpilot\Billomat\Api\PaymentsApi, typed for InvoicePayment, InvoicePaymentCreateOptions and InvoicePaymentFilter.

Endpoints ​

MethodHTTPPath
list($invoiceId?, $filters?)GET/invoice-payments
listPage($invoiceId?, $filters?)GET/invoice-payments (one page with metadata)
iterateAll($invoiceId?, $filters?, $pageSize?)GET/invoice-payments (all pages)
get($id) / getOrFail($id)GET/invoice-payments/{id}
create($invoiceId, $options)POST/invoice-payments
delete($id)DELETE/invoice-payments/{id}

There is no update() method; Billomat doesn't support editing a payment. To correct one, delete it and create a new one.

Methods ​

list(?int $parentId = null, InvoicePaymentFilter|array $filters = []): list<InvoicePayment> ​

$parentId is the invoice ID and is sent as invoice_id; it wins over an invoice_id key in an array filter. Without it, the payments of all invoices are listed. The typed filter InvoicePaymentFilter (generated from the API spec) has these fields:

PropertyBillomat filterTypeDescription
fromfrom?\DateTimeImmutablePayments from this date
toto?\DateTimeImmutablePayments up to this date
typetypelist<PaymentType>Payment types, OR-combined (sent as BANK_TRANSFER,PAYPAL)
userIduser_id?intID of the user who entered the payment
orderByorder_by?OrderBySorting
page / perPagepage / per_page?intPagination
extraarrayFurther query parameters
php
use Justpilot\Billomat\Api\InvoicePaymentFilter;
use Justpilot\Billomat\Api\OrderBy;
use Justpilot\Billomat\Model\Enum\PaymentType;

$payments = $billomat->invoices->payments->list($invoice->id, new InvoicePaymentFilter(
    type: [PaymentType::BANK_TRANSFER, PaymentType::PAYPAL],
    orderBy: OrderBy::desc('date'),
));

A raw array (['from' => '2026-01-01']) still works. A filter of another resource (e.g. CreditNotePaymentFilter) throws an InvalidArgumentException.

listPage(?int $parentId = null, InvoicePaymentFilter|array $filters = []): Page<InvoicePayment> / iterateAll(?int $parentId = null, InvoicePaymentFilter|array $filters = [], int $pageSize = 100): Generator<int, InvoicePayment> ​

Like list(), with pagination metadata or as a lazy iterator over all pages. See Pagination.

get(int $id): ?InvoicePayment / getOrFail(int $id): InvoicePayment ​

get() returns null on 404; getOrFail() throws a NotFoundException instead.

create(int $invoiceId, InvoicePaymentCreateOptions $options): InvoicePayment ​

php
use Justpilot\Billomat\Api\InvoicePaymentCreateOptions;
use Justpilot\Billomat\Model\Enum\PaymentType;
use Justpilot\Billomat\Model\Money;

$opts = new InvoicePaymentCreateOptions(
    amount: Money::of('1190.00'),
    date: new DateTimeImmutable('2026-06-01'),
    type: PaymentType::BANK_TRANSFER,
    comment: 'Bank transfer received on 2026-06-01',
    markInvoiceAsPaid: true,
);

$payment = $billomat->invoices->payments->create($invoice->id, $opts);

The invoice ID is the first argument; the SDK adds it to the payload as invoice_id.

delete(int $id): void ​

According to the Billomat docs, this resets the invoice status to OPEN or OVERDUE if the payment had set it to PAID.

Write model: InvoicePaymentCreateOptions ​

Constructor: new InvoicePaymentCreateOptions(Money $amount, …). amount is required; the other fields are optional named arguments. The object is immutable (final readonly) and has a with*() method per field.

PropertyBillomat fieldTypeNotes
amountamountMoneyRequired (constructor)
datedate?\DateTimeImmutableDefault: today
commentcomment?stringFree text
transactionPurposetransaction_purpose?stringPayment reference
typetype?PaymentTypeSee the enum below
markInvoiceAsPaidmark_invoice_as_paidboolDefault false. With true, Billomat marks the invoice as PAID even if the amount doesn't exactly cover the open amount.

The invoice ID isn't part of the options; create() takes it as an argument. toArray() drops null values but always keeps amount (as a string) and mark_invoice_as_paid (always sent as 1/0).

Read model: InvoicePayment ​

final readonly class InvoicePayment.

PropertyType
idint
invoiceIdint
created?\DateTimeImmutable
date?\DateTimeImmutable
amountMoney
type?PaymentType
comment?string
userId?int
transactionPurpose?string
currencyCode?string
quote?float
paymentGroup?string
finapiTransactionId?string (finAPI bank reconciliation)
finapiTransactionAmount?Money (finAPI bank reconciliation)
documentTitle?string
customfield?string (free extra field, see custom meta attributes)
extraarray<string, mixed>: fields the SDK doesn't map (yet), raw; see models

Enums ​

PaymentType maps the payment types, with German labels via label():

CaseWire valueLabel
INVOICE_CORRECTIONINVOICE_CORRECTIONKorrekturrechnung (correction invoice)
CREDIT_NOTECREDIT_NOTEGutschrift (credit note)
BANK_CARDBANK_CARDBankkarte (bank card)
BANK_TRANSFERBANK_TRANSFERÜberweisung (bank transfer)
DEBITDEBITLastschrift (direct debit)
CASHCASHBarzahlung (cash)
CHECKCHECKScheck (check)
PAYPALPAYPALPayPal
CREDIT_CARDCREDIT_CARDKreditkarte (credit card)
COUPONCOUPONGutschein (voucher)
MISCMISCSonstiges (other)

The same enum is used for the accepted payment types of documents (paymentTypes, list<PaymentType>).

Pitfalls ​

  • No updates. A payment can't be changed, only deleted and created again.
  • markInvoiceAsPaid overrides the open amount. Only set the flag if you really want the invoice to switch to PAID, even for a partial payment.
  • Invoice status changes. After create(), the invoice becomes PAID (if amount covers the open amount) or stays OPEN/OVERDUE (partial payment). After delete() it switches back.
  • Type filter. When listing, type is a comma-separated field on the API side; InvoicePaymentFilter::$type takes a list of PaymentType cases and joins them.

End-to-end example ​

php
<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use Justpilot\Billomat\Api\InvoicePaymentCreateOptions;
use Justpilot\Billomat\Api\InvoicePaymentFilter;
use Justpilot\Billomat\Api\OrderBy;
use Justpilot\Billomat\BillomatClient;
use Justpilot\Billomat\Model\Enum\PaymentType;
use Justpilot\Billomat\Model\InvoicePayment;
use Justpilot\Billomat\Model\Money;

$billomat = BillomatClient::create(
    billomatId: 'mycompany',
    apiKey: getenv('BILLOMAT_API_KEY'),
);

$invoiceId = 98765;

// Record a payment
$opts = new InvoicePaymentCreateOptions(
    amount: Money::of('590.00'),
    type: PaymentType::BANK_TRANSFER,
    date: new DateTimeImmutable('today'),
    transactionPurpose: 'Invoice RE-2026-0042',
);

$payment = $billomat->invoices->payments->create($invoiceId, $opts);
printf("Payment #%d recorded: %s EUR via %s\n", $payment->id, $payment->amount->format(2), $payment->type?->value);

// List all payments for the invoice
$paymentsForInvoice = $billomat->invoices->payments->list($invoiceId, new InvoicePaymentFilter(
    orderBy: OrderBy::asc('date'),
));

$sum = Money::sum(...array_map(static fn (InvoicePayment $p): Money => $p->amount, $paymentsForInvoice));
printf("Recorded so far: %s EUR from %d payments\n", $sum->format(2), count($paymentsForInvoice));

// Remove the last payment again
$billomat->invoices->payments->delete($payment->id);

Unofficial SDK, not affiliated with Billomat GmbH. Released under the Apache License 2.0.