Filters¶
Pennylane\Sdk\Filter builds one filter condition for the filter query parameter accepted by list methods. Build conditions with the static helpers and pass them as an array to filter:.
$client->customerInvoices->list(filter: [
Filter::gte('date', '2026-01-01'),
Filter::eq('status', 'upcoming'),
]);
Operator availability varies per field and endpoint; each list method documents its reference URL where the filterable fields are described.
Builders and wire operators¶
| Builder | Value type | Wire operator | Notes |
|---|---|---|---|
Filter::eq($field, $value) |
string\|int\|bool\|\DateTimeInterface\|null |
eq |
Equality. |
Filter::notEq($field, $value) |
string\|int\|bool\|\DateTimeInterface\|null |
not_eq |
Inequality. |
Filter::lt($field, $value) |
string\|int\|\DateTimeInterface |
lt |
Strictly less than. |
Filter::lte($field, $value) |
string\|int\|\DateTimeInterface |
lteq |
Less than or equal. The method name is lte, but it encodes to the wire operator lteq. |
Filter::gt($field, $value) |
string\|int\|\DateTimeInterface |
gt |
Strictly greater than. |
Filter::gte($field, $value) |
string\|int\|\DateTimeInterface |
gteq |
Greater than or equal. The method name is gte, but it encodes to the wire operator gteq. |
Filter::in($field, $values) |
list<string\|int\|bool\|\DateTimeInterface\|null> |
in |
Value is one of the list. |
Filter::notIn($field, $values) |
list<string\|int\|bool\|\DateTimeInterface\|null> |
not_in |
Value is none of the list. |
Filter::where($field, $operator, $value) |
mixed |
verbatim | Escape hatch for operators the API may add later; the operator string is sent exactly as given. |
Every builder is a static factory on Filter; the constructor itself is private. A built Filter exposes three readonly properties: field, operator and value. Filter::toArray() returns ['field' => ..., 'operator' => ..., 'value' => ...], which is the shape also accepted directly instead of a Filter instance.
\DateTimeInterface values are encoded to ATOM format (Y-m-d\TH:i:sP) on the wire.
FiltersInput: accepted forms¶
List methods that accept a filter parameter type it as Filter|array|string|null. Pennylane\Sdk\Internal\FilterEncoder accepts, and normalizes to the same wire JSON, all of the following:
| Form | Example |
|---|---|
A single Filter |
Filter::eq('status', 'paid') |
| A single condition array | ['field' => 'status', 'operator' => 'eq', 'value' => 'paid'] |
A list mixing Filter objects and condition arrays |
[Filter::eq('status', 'paid'), ['field' => 'date', 'operator' => 'gteq', 'value' => '2026-01-01']] |
| An already encoded JSON string | passed through unchanged |
Anything else in a list (not a Filter and not an array) throws InvalidRequestBodyException.
Float rejection¶
Filter values are encoded defensively: a PHP float anywhere in a filter condition, including nested inside an array value, throws InvalidRequestBodyException before any request is sent. Pass monetary amounts and quantities as numeric strings instead, for example "12.50", never 12.50 as a float. This matches the API's own string based representation of money and avoids floating point rounding on accounting data.
use Pennylane\Sdk\Filter;
use Pennylane\Sdk\Exception\InvalidRequestBodyException;
try {
$client->customerInvoices->list(filter: [
Filter::gte('amount', 100.50), // float: rejected
]);
} catch (InvalidRequestBodyException $e) {
echo $e->getMessage() . "\n";
}
// Correct: numeric string
$client->customerInvoices->list(filter: [
Filter::gte('amount', '100.50'),
]);