PHPackages                             quellabs/canvas-shipments-postnl - 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. quellabs/canvas-shipments-postnl

ActiveLibrary

quellabs/canvas-shipments-postnl
================================

PostNL shipping provider integration for the Canvas PHP framework

1.0.0(today)00MITPHPPHP ^8.2

Since Apr 3Pushed todayCompare

[ Source](https://github.com/quellabs/canvas-shipments-postnl)[ Packagist](https://packagist.org/packages/quellabs/canvas-shipments-postnl)[ RSS](/packages/quellabs-canvas-shipments-postnl/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (4)Versions (2)Used By (0)

PostNL Shipping Provider
========================

[](#postnl-shipping-provider)

A PostNL shipping provider for the Canvas framework.

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

[](#installation)

```
composer require quellabs/canvas-shipments-postnl
```

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

[](#configuration)

Publish `config/postnl.php` and fill in your credentials:

```
return [
    'api_key'             => '',
    'api_key_test'        => '',
    'test_mode'           => false,
    'customer_code'       => '',     // from your PostNL contract
    'customer_number'     => '',     // from your PostNL contract
    'collection_location' => '',     // from your PostNL contract
    'webhook_secret'      => '',     // HMAC-SHA256 secret, set in the Developer Portal
    'delivery_options'    => ['Daytime'], // add 'Morning', 'Evening', 'Sunday' if contracted
    'sender_address'      => [
        // 'company'     => 'My Webshop B.V.',
        // 'street'      => 'Keizersgracht',
        // 'houseNumber' => '123',
        // 'postalCode'  => '1015CJ',
        // 'city'        => 'Amsterdam',
        // 'country'     => 'NL',
        // 'email'       => 'logistics@example.com',
        // 'phone'       => '+31201234567',
    ],
];
```

`customer_code`, `customer_number`, and `collection_location` are provided by PostNL when your account is set up. You can find them in your PostNL contract or business portal.

Important behaviours
--------------------

[](#important-behaviours)

**Tracking code is available at creation time.** `ShipmentResult::$trackingCode` and `$trackingUrl`are both populated immediately after `create()`. PostNL assigns the barcode inline in the creation response.

**Labels are returned inline.** The label PDF is included in the creation response as a base64-encoded string and stored as a `data:application/pdf;base64,...` URI in `ShipmentResult::$labelUrl`. Decode and persist it to file or object storage before passing it to end users.

**Cancellation is supported before carrier scan.** `cancel()` calls the PostNL delete endpoint. If the parcel has already been scanned by the carrier, the call returns a `CancelResult` with `$accepted = false` rather than throwing. Any other API failure throws `ShipmentCancellationException`.

**Webhooks are HMAC-signed.** PostNL signs each request with a SHA256 HMAC sent in the `X-PostNL-Signature` header. Set `webhook_secret` in your config to enable verification. Leaving it empty disables verification — do not do this in production.

**Delivery options return one entry per available timeframe slot.** `getDeliveryOptions()` calls the PostNL Timeframe API and returns all available windows across a 5-day window starting tomorrow. The option types requested (Daytime, Morning, Evening, Sunday) are read from `delivery_options` in your config — only list types that are enabled on your PostNL contract. Each slot is a separate `DeliveryOption`; the `methodId` encodes the date, window, and option type (`dd-mm-yyyy|HH:MM:SS|HH:MM:SS|OptionType`) so it can be passed back in `ShipmentRequest::$methodId`at order creation time. A recipient address is required; without it an empty array is returned. Pickup point and locker modules return an empty array — use `getPickupOptions()` instead.

**Pickup options require a recipient address.** Pass a `ShipmentAddress` as the second argument to `getPickupOptions()`. The address is used as the search origin for nearby service points.

**Each product code must be contracted.** Not all modules listed below are available on every PostNL account. Consult your PostNL account manager to enable the products you need.

Supported modules
-----------------

[](#supported-modules)

### Domestic NL — standard home delivery

[](#domestic-nl--standard-home-delivery)

ModuleProduct codeService`postnl_standard`3085Standard shipment`postnl_signature`3087Signature on delivery`postnl_stated_address`3090Delivery to stated address only`postnl_age_check`3094Age check 18+`postnl_sunday`3096Sunday/holiday delivery`postnl_id_check`3189ID check on delivery`postnl_sameday`3385Same-day / Sunday delivery`postnl_sameday_stated_address`3390Same-day + stated address only### Domestic NL — with insurance / COD

[](#domestic-nl--with-insurance--cod)

ModuleProduct codeService`postnl_insured`3086Extra cover / COD`postnl_signature_insured`3091Signature + extra cover`postnl_signature_age_insured`3093Signature + age check 18+ + extra cover`postnl_sunday_insured`3097Sunday/holiday + extra cover`postnl_sameday_insured`3389Same-day + extra cover### Domestic NL — Extra@Home

[](#domestic-nl--extrahome)

ModuleProduct codeService`postnl_extrahome`3089Extra@Home (large/heavy parcels)### Domestic NL — mailbox parcel

[](#domestic-nl--mailbox-parcel)

ModuleProduct codeService`postnl_mailbox`2928Mailbox parcel (brievenbuspakje)### Domestic NL — age &amp; ID check variants

[](#domestic-nl--age--id-check-variants)

ModuleProduct codeService`postnl_age_check_home`3437Age check 18+, home delivery`postnl_age_check_home_insured`3438Age check 18+ + extra cover`postnl_id_check_home`3440ID check, home delivery`postnl_id_age_check_home`3442ID check + age check 18+, home delivery`postnl_id_check_pickup`3444ID check, pickup point`postnl_id_age_check_pickup`3446ID check + age check 18+, pickup point### Domestic NL — pick-up at PostNL location

[](#domestic-nl--pick-up-at-postnl-location)

ModuleProduct codeService`postnl_pickup`3533Standard`postnl_pickup_insured`3534Extra cover`postnl_pickup_cod`3535COD`postnl_pickup_cod_insured`3536COD + extra cover`postnl_pickup_signature`3543Signature`postnl_pickup_signature_insured`3544Signature + extra cover`postnl_pickup_signature_cod`3545Signature + COD`postnl_pickup_signature_cod_insured`3546Signature + COD + extra cover`postnl_pickup_consumer`3571Standard (consumer-facing)`postnl_pickup_consumer_signature`3572Signature (consumer-facing)`postnl_pickup_consumer_id`3573ID check (consumer-facing)`postnl_pickup_consumer_age`3574Age check 18+ (consumer-facing)`postnl_pickup_consumer_insured`3575Extra cover (consumer-facing)`postnl_pickup_consumer_insured_signature`3576Extra cover + signature### Domestic NL — returns

[](#domestic-nl--returns)

ModuleProduct codeService`postnl_return`2828Return label (label-in-the-box / smart return)`postnl_return_international`4910ERS international return label### NL → Belgium

[](#nl--belgium)

ModuleProduct codeService`postnl_be_standard`4946Standard shipment`postnl_be_signature`4912Signature on delivery`postnl_be_insured`4914Extra cover`postnl_be_age_check`4941Age check 18+### Domestic Belgium (BE → BE)

[](#domestic-belgium-be--be)

ModuleProduct codeService`postnl_be_domestic`4960Standard`postnl_be_domestic_signature`4961Signature on delivery`postnl_be_domestic_insured`4962Extra cover`postnl_be_domestic_age_check`4963Age check 18+`postnl_be_domestic_id_check`4965ID check### Belgium — pick-up at PostNL location

[](#belgium--pick-up-at-postnl-location)

ModuleProduct codeService`postnl_be_pickup`4878Standard`postnl_be_pickup_cod`4880COD### EU (EPS / EU Pack Special)

[](#eu-eps--eu-pack-special)

ModuleProduct codeService`postnl_eu`4907EU Pack Special, standard`postnl_eu_be`4936EU Pack Special, BE → EU`postnl_eu_consumer`4952EU Pack Special, consumer (combilabel)`postnl_eu_documents`4999EU Pack Special, documents### GlobalPack (world outside EU)

[](#globalpack-world-outside-eu)

ModuleProduct codeService`postnl_global`4909GlobalPack standard### Miscellaneous

[](#miscellaneous)

ModuleProduct codeService`postnl_locker`6350Parcel dispenser / locker deliveryLicense
-------

[](#license)

MIT

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

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

0d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/57e4ab872b3e37536367f2d26b192df3d3bb6a6a1cebec9a104d14a6d2ffe157?d=identicon)[noescom](/maintainers/noescom)

---

Tags

canvasshippingshipmentpostnlcanvas-shipments

### Embed Badge

![Health badge](/badges/quellabs-canvas-shipments-postnl/health.svg)

```
[![Health](https://phpackages.com/badges/quellabs-canvas-shipments-postnl/health.svg)](https://phpackages.com/packages/quellabs-canvas-shipments-postnl)
```

###  Alternatives

[firstred/postnl-api-php

PostNL REST API PHP Bindings

27610.2k1](/packages/firstred-postnl-api-php)[magepsycho/magento2-custom-shipping

Magento 2 Custom Shipping

697.5k](/packages/magepsycho-magento2-custom-shipping)

PHPackages © 2026

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