PHPackages                             woweb/laravel-openproduct - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. woweb/laravel-openproduct

ActiveLibrary

woweb/laravel-openproduct
=========================

Laravel wrapper for Open Product

v1.0.0(1mo ago)00EUPL-1.2PHPPHP ^8.2CI passing

Since Mar 24Pushed 1mo agoCompare

[ Source](https://github.com/WowebNL/laravel-openproduct)[ Packagist](https://packagist.org/packages/woweb/laravel-openproduct)[ Docs](https://github.com/WowebNL/laravel-openproduct)[ RSS](/packages/woweb-laravel-openproduct/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (6)Versions (3)Used By (0)

laravel-openproduct
===================

[](#laravel-openproduct)

[![Tests](https://github.com/WowebNL/laravel-openproduct/actions/workflows/tests.yml/badge.svg)](https://github.com/WowebNL/laravel-openproduct/actions/workflows/tests.yml)[![Latest Version on Packagist](https://camo.githubusercontent.com/226471f106c29cdac35bbca66ad38c00c26225f422508028ca4ae1ea8a8119ae/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f776f7765622f6c61726176656c2d6f70656e70726f647563742e737667)](https://packagist.org/packages/woweb/laravel-openproduct)[![PHP Version](https://camo.githubusercontent.com/8184369ee9407965f20eea96dae3c87edcdbcd0f394e3b29f59d320ef737f6ab/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f776f7765622f6c61726176656c2d6f70656e70726f647563742e737667)](https://packagist.org/packages/woweb/laravel-openproduct)

Laravel wrapper for the Product API and Producttypes API based on [Open Product](https://github.com/maykinmedia/open-product).

Supported API versions
----------------------

[](#supported-api-versions)

APIVersionProducten APIv1.4.0Producttypen APIv1.4.0Requirements
------------

[](#requirements)

- PHP 8.2 or higher
- Laravel 10, 11, or 12

Installation
------------

[](#installation)

```
composer require woweb/laravel-openproduct
```

The service provider is registered automatically via Laravel's package auto-discovery.

Publish the configuration:

```
php artisan vendor:publish --provider="Woweb\Openproduct\OpenProductServiceProvider"
```

Configuration
-------------

[](#configuration)

Add the following variables to your `.env`:

```
OPENPRODUCT_URL=https://your-openproduct-instance.nl/open-product/
OPENPRODUCT_AUTH_TOKEN=your-api-token
OPENPRODUCT_LANGUAGE=nl
```

`OPENPRODUCT_LANGUAGE` sets the `Accept-Language` header on every API request. Defaults to `nl`.

Upgrading from v1.x
-------------------

[](#upgrading-from-v1x)

Method names were changed in v2 to be consistent across all classes. Update your call sites:

Old (v1)New (v2)`Producten::getAllProducten()``Producten::list()``Producten::getSingleProduct($uuid)``Producten::get($uuid)``Producten::createProduct($data)``Producten::create($data)``Producten::updateProduct($uuid, $data)``Producten::patch($uuid, $data)``ProductTypen::getAllProducttypes()``ProductTypen::list()``ProductTypen::getSingleProducttype($uuid)``ProductTypen::get($uuid)``ProductTypen::updateProducttype($uuid, $data)``ProductTypen::patch($uuid, $data)`Usage
-----

[](#usage)

All classes throw `OpenProductValidationException` for invalid input before the API call is made, and `OpenProductException` for HTTP errors returned by the API.

### Error handling

[](#error-handling)

```
use Woweb\Openproduct\Exceptions\OpenProductException;
use Woweb\Openproduct\Exceptions\OpenProductValidationException;

try {
    $product = Producten::create($data);
} catch (OpenProductValidationException $e) {
    // Validation error in the provided data (before the API call)
    logger()->error($e->getMessage());
} catch (OpenProductException $e) {
    // HTTP error from the API (e.g. 404, 500)
    logger()->error('API error ' . $e->getCode() . ': ' . $e->getMessage());
}
```

### Producten

[](#producten)

Endpoint: `producten/api/v1/producten`

```
use Woweb\Openproduct\Api\Producten;

// List products (optional filters)
$producten = Producten::list(['status' => 'actief', 'page' => 1]);

// Get a single product
$product = Producten::get('550e8400-e29b-41d4-a716-446655440000');

// Create a product
$product = Producten::create([
    'producttype_uuid' => '550e8400-e29b-41d4-a716-446655440001',
    'eigenaren'        => [['bsn' => '123456789']],
    'naam'             => 'Parking permit',
    'start_datum'      => '2026-01-01',
    'status'           => 'actief',
    'frequentie'       => 'eenmalig',
]);

// Full update (PUT)
$product = Producten::update('550e8400-...', [
    'producttype_uuid' => '550e8400-...',
    'eigenaren'        => [['bsn' => '123456789']],
]);

// Partial update (PATCH)
$product = Producten::patch('550e8400-...', ['status' => 'ingetrokken']);

// Delete
Producten::delete('550e8400-...');
```

Valid values for `status`: `initieel`, `in_aanvraag`, `gereed`, `actief`, `ingetrokken`, `geweigerd`, `verlopen`. Valid values for `frequentie`: `eenmalig`, `maandelijks`, `jaarlijks`.

### ProductTypen

[](#producttypen)

Endpoint: `producttypen/api/v1/producttypen`

```
use Woweb\Openproduct\Api\ProductTypen;

// List product types (optional filters)
$typen = ProductTypen::list(['doelgroep' => 'burgers']);

// Get a single product type
$type = ProductTypen::get('550e8400-...');

// Create
$type = ProductTypen::create([
    'doelgroep'    => 'burgers',
    'thema_uuids'  => ['497f6eca-...'],
    'naam'         => 'Parkeervergunning',
    'samenvatting' => 'Vergunning voor parkeren in de stad.',
    'code'         => 'PT-PARKEER',
]);

// Full update (PUT)
$type = ProductTypen::update('550e8400-...', [...]);

// Partial update (PATCH)
$type = ProductTypen::patch('550e8400-...', ['naam' => 'Updated name']);

// Delete
ProductTypen::delete('550e8400-...');

// Get the current/active price for a product type
$prijs = ProductTypen::getActuelePrijs('550e8400-...');

// Get current prices for all product types
$prijzen = ProductTypen::getAllActuelePrijzen();

// Get content blocks linked to a product type
$content = ProductTypen::getContent('550e8400-...', ['taal' => 'nl']);

// Create or replace a translation (PUT)
$vertaling = ProductTypen::updateVertaling('550e8400-...', 'en', [
    'naam'         => 'Parking permit',
    'samenvatting' => 'Permit for parking in the city.',
]);

// Partial translation update (PATCH)
$vertaling = ProductTypen::patchVertaling('550e8400-...', 'en', ['naam' => 'Parking permit']);

// Delete a translation
ProductTypen::deleteVertaling('550e8400-...', 'en');
```

Valid values for `doelgroep`: `burgers`, `bedrijven`, `burgers_en_bedrijven`. `code` must match the pattern `^[A-Z0-9-]+$`.

### Themas

[](#themas)

Endpoint: `producttypen/api/v1/themas`

```
use Woweb\Openproduct\Api\Themas;

$themas = Themas::list();
$thema  = Themas::get('550e8400-...');
$thema  = Themas::create(['naam' => 'Wonen & Leven', 'producttype_uuids' => []]);
$thema  = Themas::update('550e8400-...', ['naam' => 'Updated', 'producttype_uuids' => []]);
$thema  = Themas::patch('550e8400-...', ['naam' => 'Patched']);
Themas::delete('550e8400-...');
```

### Content

[](#content)

Endpoint: `producttypen/api/v1/content`

```
use Woweb\Openproduct\Api\Content;

$content = Content::get('550e8400-...');
$content = Content::create(['content' => 'Beschrijving', 'producttype_uuid' => '550e8400-...']);
$content = Content::update('550e8400-...', ['content' => 'Updated', 'producttype_uuid' => '550e8400-...']);
$content = Content::patch('550e8400-...', ['content' => 'Patched']);
Content::delete('550e8400-...');

// Translations
$vertaling = Content::updateVertaling('550e8400-...', 'en', ['content' => 'Description']);
Content::deleteVertaling('550e8400-...', 'en');
```

### ContentLabels

[](#contentlabels)

Endpoint: `producttypen/api/v1/contentlabels` (read-only)

```
use Woweb\Openproduct\Api\ContentLabels;

$labels = ContentLabels::list(['page' => 1]);
```

### Prijzen

[](#prijzen)

Endpoint: `producttypen/api/v1/prijzen`

```
use Woweb\Openproduct\Api\Prijzen;

$prijzen = Prijzen::list(['producttype_uuid' => '550e8400-...']);
$prijs   = Prijzen::get('550e8400-...');
$prijs   = Prijzen::create(['producttype_uuid' => '550e8400-...', 'actief_vanaf' => '2026-01-01']);
$prijs   = Prijzen::update('550e8400-...', ['producttype_uuid' => '550e8400-...', 'actief_vanaf' => '2026-01-01']);
$prijs   = Prijzen::patch('550e8400-...', ['actief_vanaf' => '2026-06-01']);
Prijzen::delete('550e8400-...');
```

### Schemas

[](#schemas)

Endpoint: `producttypen/api/v1/schemas`

Note: schemas use an integer `$id`, not a UUID.

```
use Woweb\Openproduct\Api\Schemas;

$schemas = Schemas::list();
$schema  = Schemas::get(42);
$schema  = Schemas::create(['naam' => 'Aanvraagschema', 'schema' => ['type' => 'object']]);
$schema  = Schemas::update(42, ['naam' => 'Updated', 'schema' => ['type' => 'object']]);
$schema  = Schemas::patch(42, ['naam' => 'Patched']);
Schemas::delete(42);
```

### Links

[](#links)

Endpoint: `producttypen/api/v1/links`

```
use Woweb\Openproduct\Api\Links;

$links = Links::list(['producttype_uuid' => '550e8400-...']);
$link  = Links::get('550e8400-...');
$link  = Links::create([
    'naam'             => 'Meer informatie',
    'url'              => 'https://example.com/info',
    'producttype_uuid' => '550e8400-...',
]);
$link  = Links::update('550e8400-...', ['naam' => 'Updated', 'url' => 'https://example.com', 'producttype_uuid' => '550e8400-...']);
$link  = Links::patch('550e8400-...', ['naam' => 'Patched']);
Links::delete('550e8400-...');
```

### Bestanden

[](#bestanden)

Endpoint: `producttypen/api/v1/bestanden`

File uploads use multipart form data automatically.

```
use Woweb\Openproduct\Api\Bestanden;

$bestanden = Bestanden::list(['producttype_uuid' => '550e8400-...']);
$bestand   = Bestanden::get('550e8400-...');

// Upload a file
$bestand = Bestanden::create('/path/to/file.pdf', '550e8400-...');

// Replace a file (PUT)
$bestand = Bestanden::update('550e8400-...', '/path/to/new-file.pdf', '550e8400-...');

// Partially update (PATCH, file and/or producttype_uuid optional)
$bestand = Bestanden::patch('550e8400-...', '/path/to/file.pdf');

Bestanden::delete('550e8400-...');
```

### Acties

[](#acties)

Endpoint: `producttypen/api/v1/acties`

```
use Woweb\Openproduct\Api\Acties;

$acties = Acties::list(['producttype_uuid' => '550e8400-...']);
$actie  = Acties::get('550e8400-...');
$actie  = Acties::create([
    'naam'             => 'Indienen aanvraag',
    'tabel_endpoint'   => 'https://beslistabellen.example.com/pt-001',
    'dmn_tabel_id'     => 'pt-001-aanvraag',
    'producttype_uuid' => '550e8400-...',
]);
$actie  = Acties::update('550e8400-...', [...]);
$actie  = Acties::patch('550e8400-...', ['naam' => 'Patched']);
Acties::delete('550e8400-...');
```

### Locaties

[](#locaties)

Endpoint: `producttypen/api/v1/locaties`

```
use Woweb\Openproduct\Api\Locaties;

$locaties = Locaties::list(['stad' => 'Nijmegen']);
$locatie  = Locaties::get('550e8400-...');
$locatie  = Locaties::create([
    'naam'       => 'Stadskantoor Nijmegen',
    'straat'     => 'Mariënburg',
    'huisnummer' => '75',
    'postcode'   => '6511 PS',
    'stad'       => 'Nijmegen',
]);
$locatie  = Locaties::update('550e8400-...', [...]);
$locatie  = Locaties::patch('550e8400-...', ['stad' => 'Arnhem']);
Locaties::delete('550e8400-...');
```

`postcode` must match the Dutch format `^[1-9][0-9]{3}\s?[A-Za-z]{2}$` (e.g. `6511 PS` or `6511PS`).

### Organisaties

[](#organisaties)

Endpoint: `producttypen/api/v1/organisaties`

```
use Woweb\Openproduct\Api\Organisaties;

$organisaties = Organisaties::list(['naam' => 'Gemeente']);
$organisatie  = Organisaties::get('550e8400-...');
$organisatie  = Organisaties::create(['naam' => 'Gemeente Nijmegen', 'code' => 'GEM-NIJMEGEN']);
$organisatie  = Organisaties::update('550e8400-...', ['naam' => 'Updated', 'code' => 'GEM-NMG']);
$organisatie  = Organisaties::patch('550e8400-...', ['naam' => 'Patched']);
Organisaties::delete('550e8400-...');
```

### Contacten

[](#contacten)

Endpoint: `producttypen/api/v1/contacten`

```
use Woweb\Openproduct\Api\Contacten;

$contacten = Contacten::list(['naam' => 'Jan']);
$contact   = Contacten::get('550e8400-...');
$contact   = Contacten::create([
    'naam'             => 'Jan de Vries',
    'email'            => 'jan@example.com',       // optional
    'telefoonnummer'   => '0612345678',             // optional
    'rol'              => 'Contactpersoon',          // optional
    'organisatie_uuid' => '550e8400-...',           // optional
]);
$contact = Contacten::update('550e8400-...', ['naam' => 'Updated']);
$contact = Contacten::patch('550e8400-...', ['email' => 'nieuw@example.com']);
Contacten::delete('550e8400-...');
```

Testing
-------

[](#testing)

```
composer install
vendor/bin/phpunit
```

License
-------

[](#license)

EUPL-1.2. See [LICENSE](LICENSE.md) for details.

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance90

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

49d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3f3708e4d7c1972fea6c1c72b4a06a995a4e44069a2917b5dbec00fc3709e9b1?d=identicon)[woweb](/maintainers/woweb)

---

Top Contributors

[![Michel-Verhoeven](https://avatars.githubusercontent.com/u/79970817?v=4)](https://github.com/Michel-Verhoeven "Michel-Verhoeven (10 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/woweb-laravel-openproduct/health.svg)

```
[![Health](https://phpackages.com/badges/woweb-laravel-openproduct/health.svg)](https://phpackages.com/packages/woweb-laravel-openproduct)
```

###  Alternatives

[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[spatie/laravel-honeypot

Preventing spam submitted through forms

1.6k6.0M60](/packages/spatie-laravel-honeypot)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)[spatie/laravel-export

Create a static site bundle from a Laravel app

646127.9k5](/packages/spatie-laravel-export)[rahul900day/laravel-captcha

Different types of Captcha implementation for Laravel Application.

10715.9k](/packages/rahul900day-laravel-captcha)[erag/laravel-disposable-email

A Laravel package to detect and block disposable email addresses.

226102.4k](/packages/erag-laravel-disposable-email)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
