├── docs
├── README.md
├── get-started
│ ├── installation.md
│ └── core-concepts.md
├── carriers
│ ├── post-nl.md
│ ├── colissimo.md
│ ├── fastway.md
│ ├── interparcel.md
│ ├── ups.md
│ ├── tnt-australia.md
│ ├── sendle.md
│ ├── bring.md
│ ├── fedex.md
│ ├── royal-mail.md
│ ├── usps.md
│ ├── dhl-express.md
│ ├── canada-post.md
│ ├── new-zealand-post.md
│ └── australia-post.md
├── models
│ ├── http-client.md
│ ├── tracking-detail.md
│ ├── rate-response.md
│ ├── label-response.md
│ ├── tracking-response.md
│ ├── request.md
│ ├── label.md
│ ├── shipment.md
│ ├── rate.md
│ ├── tracking.md
│ ├── address.md
│ └── package.md
├── api
│ ├── logging.md
│ └── events.md
└── .sidebar.json
├── src
├── carriers
│ ├── CarrierInterface.php
│ ├── PostNL.php
│ └── Colissimo.php
├── exceptions
│ ├── ShippyException.php
│ └── InvalidRequestException.php
├── Shippy.php
├── rates
│ ├── postnl
│ │ ├── InternationalBetaalservice.php
│ │ ├── InternationalBrievenbuspakje.php
│ │ ├── DomesticPakketNoTrackAndTrace.php
│ │ ├── DomesticBrievenbuspakje.php
│ │ ├── InternationalPakketNoTrackAndTrace.php
│ │ ├── DomesticBrief.php
│ │ ├── DomesticPakket.php
│ │ ├── DomesticAangetekend.php
│ │ ├── DomesticBetaalservice.php
│ │ ├── DomesticVerzekerservice.php
│ │ ├── InternationalBrief.php
│ │ ├── InternationalPakket.php
│ │ ├── InternationalAangetekend.php
│ │ └── InternationalVerzekerservice.php
│ ├── royalmail
│ │ ├── postoffice
│ │ │ ├── ParcelforceExpress10.php
│ │ │ ├── ParcelforceExpress24.php
│ │ │ ├── ParcelforceExpress48.php
│ │ │ ├── ParcelforceExpressAm.php
│ │ │ ├── ParcelforceExpress48Large.php
│ │ │ ├── ParcelforceExpress9.php
│ │ │ ├── InternationalEconomy.php
│ │ │ ├── InternationalStandard.php
│ │ │ ├── InternationalTrackedSigned.php
│ │ │ ├── ParcelforceIrelandexpress.php
│ │ │ ├── SpecialDelivery9am.php
│ │ │ ├── SpecialDelivery1pm.php
│ │ │ ├── Tracked24.php
│ │ │ ├── Tracked48.php
│ │ │ ├── InternationalTracked.php
│ │ │ ├── FirstClass.php
│ │ │ ├── SecondClass.php
│ │ │ └── InternationalSigned.php
│ │ └── online
│ │ │ ├── InternationalEconomy.php
│ │ │ ├── InternationalStandard.php
│ │ │ ├── SpecialDelivery1pm.php
│ │ │ ├── Tracked24.php
│ │ │ ├── Tracked48.php
│ │ │ ├── FirstClass.php
│ │ │ ├── InternationalSigned.php
│ │ │ └── SecondClass.php
│ └── colissimo
│ │ ├── DomOutremer.php
│ │ ├── TomOutremer.php
│ │ ├── TomEconomiqueOutremer.php
│ │ ├── Europe.php
│ │ ├── DomEconomiqueOutremer.php
│ │ ├── International.php
│ │ ├── EmballageInternational.php
│ │ ├── FrFrance.php
│ │ └── FrEmballageFrance.php
├── events
│ ├── ModelEvent.php
│ ├── RateEvent.php
│ ├── LabelEvent.php
│ └── TrackingEvent.php
├── models
│ ├── RateResponse.php
│ ├── LabelResponse.php
│ ├── TrackingResponse.php
│ ├── HttpClient.php
│ ├── ResourceResponse.php
│ ├── Request.php
│ ├── Response.php
│ ├── TrackingDetail.php
│ ├── Label.php
│ ├── PackageItem.php
│ ├── Model.php
│ ├── StaticRates.php
│ ├── Rate.php
│ └── PackageBox.php
├── helpers
│ ├── DateTimeHelper.php
│ ├── Xml.php
│ ├── Json.php
│ └── StringHelper.php
└── LogTrait.php
├── .gitignore
├── LICENSE.md
└── composer.json
/docs/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/carriers/CarrierInterface.php:
--------------------------------------------------------------------------------
1 | $value) {
15 | $this->$name = $value;
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # CRAFT ENVIRONMENT
2 | .env.php
3 | .env.sh
4 | .env
5 |
6 | # COMPOSER
7 | /vendor
8 | composer.lock
9 |
10 | # BUILD FILES
11 | /bower_components/*
12 | /node_modules/*
13 | /build/*
14 | /yarn-error.log
15 |
16 | # MISC FILES
17 | .cache
18 | .DS_Store
19 | .idea
20 | .project
21 | .settings
22 | .map
23 | *.esproj
24 | *.sublime-workspace
25 | *.sublime-project
26 | *.tmproj
27 | *.tmproject
28 | .vscode/*
29 | !.vscode/settings.json
30 | !.vscode/tasks.json
31 | !.vscode/launch.json
32 | !.vscode/extensions.json
33 |
--------------------------------------------------------------------------------
/docs/carriers/fastway.md:
--------------------------------------------------------------------------------
1 | # Fastway
2 | Shippy provides the following feature support for Fastway.
3 |
4 | - Rates
5 | - Tracking
6 |
7 | ## API Credentials
8 | To use Fastway, you'll need to connect to their API.
9 |
10 | 1. Go to Fastway Developers Centre and register for API access.
11 | 1. Copy the **API Key** from Fastway as the `apiKey` with the Shippy carrier.
12 |
13 | ```php
14 | use verbb\shippy\carriers\Fastway;
15 |
16 | new Fastway([
17 | 'isProduction' => false,
18 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
19 | ]);
20 | ```
21 |
--------------------------------------------------------------------------------
/src/models/RateResponse.php:
--------------------------------------------------------------------------------
1 | rates;
18 | }
19 |
20 | public function setRates(array $rates): RateResponse
21 | {
22 | $this->rates = $rates;
23 | return $this;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/models/LabelResponse.php:
--------------------------------------------------------------------------------
1 | labels;
18 | }
19 |
20 | public function setLabels(array $labels): LabelResponse
21 | {
22 | $this->labels = $labels;
23 | return $this;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/helpers/DateTimeHelper.php:
--------------------------------------------------------------------------------
1 | tracking;
18 | }
19 |
20 | public function setTracking(array $tracking): TrackingResponse
21 | {
22 | $this->tracking = $tracking;
23 | return $this;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/docs/carriers/interparcel.md:
--------------------------------------------------------------------------------
1 | # Interparcel
2 | Shippy provides the following feature support for Interparcel.
3 |
4 | - Rates
5 | - Tracking
6 |
7 | ## API Credentials
8 | To use Interparcel, you'll need to connect to their API.
9 |
10 | 1. Go to Interparcel and request Developer API access.
11 | 1. Once approved, you'll receive an email from the Interparcel support team.
12 | 1. Copy the **API Key** from Interparcel as the `apiKey` with the Shippy carrier.
13 |
14 | ```php
15 | use verbb\shippy\carriers\Interparcel;
16 |
17 | new Interparcel([
18 | 'isProduction' => false,
19 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
20 | ]);
21 | ```
22 |
--------------------------------------------------------------------------------
/src/rates/postnl/DomesticBrievenbuspakje.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 380,
16 | 'width' => 265,
17 | 'height' => 32,
18 | 'weight' => 2000,
19 | 'price' => [
20 | self::ZONE_NL => 425,
21 | ],
22 | ],
23 | ];
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/models/HttpClient.php:
--------------------------------------------------------------------------------
1 | push(Middleware::httpErrors(new BodySummarizer(99999)), 'http_errors');
18 | $config['handler'] = $stack;
19 | }
20 |
21 | parent::__construct($config);
22 | }
23 | }
--------------------------------------------------------------------------------
/docs/api/logging.md:
--------------------------------------------------------------------------------
1 | # Logging
2 | Shippy includes [PSR-3](https://www.php-fig.org/psr/psr-3/) logging throughout the various requests to APIs. You can use the interface to add your own application's logging to Shippy, to have logging routed through there.
3 |
4 | For example, we might like to use the popular [Monolog](https://github.com/Seldaek/monolog) package for logging. Maybe our application already uses it.
5 |
6 | ```php
7 | use Monolog\Logger;
8 | use Monolog\Handler\StreamHandler;
9 | use verbb\shippy\Shippy;
10 |
11 | $logger = new Logger('Shippy');
12 | $logger->pushHandler(new StreamHandler('shippy.log'));
13 |
14 | Shippy::setLogger($logger);
15 | ```
16 |
17 | With this in place, all logging that Shippy does will be routed through your Monolog logger, and into a `shippy.log` file within your application. This will include debug and error logging, which is configurable through your Monolog `Logger` instance.
18 |
19 |
--------------------------------------------------------------------------------
/docs/carriers/ups.md:
--------------------------------------------------------------------------------
1 | # UPS
2 | Shippy provides the following feature support for UPS.
3 |
4 | - Rates
5 | - Tracking
6 | - Labels
7 |
8 | ## API Credentials
9 | To use UPS, you'll need to connect to their API.
10 |
11 | 1. Go to UPS and login to your account.
12 | 1. From the **Apps** section, follow the prompts to create a new app.
13 | 1. Copy the **Client ID** from UPS as the `username` with the Shippy carrier.
14 | 1. Copy the **Client Secret** from UPS as the `apiKey` with the Shippy carrier.
15 |
16 | To create labels, you'll be required to supply a few more details.
17 |
18 | ```php
19 | use verbb\shippy\carriers\UPS;
20 |
21 | new UPS([
22 | 'isProduction' => false,
23 | 'clientId' => '••••••••••••••••',
24 | 'clientSecret' => '••••••••••••••••',
25 |
26 | // Required for labels
27 | 'accountNumber' => '••••••••••••••••',
28 | ]);
29 | ```
30 |
--------------------------------------------------------------------------------
/docs/models/tracking-detail.md:
--------------------------------------------------------------------------------
1 | # Tracking Detail
2 | A Tracking Detail model provides further detail on an individual [Tracking](docs:models/tracking) update.
3 |
4 | ## Properties
5 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
6 |
7 | | Property | Type | Description
8 | | --------------------- | ----------------- | --------------------------------- |
9 | | `description` | `?string` | The description of the tracking update.
10 | | `date` | `?DateTime` | The date for this tracking update.
11 | | `location` | `?string` | The location marked for this tracking update.
12 | | `status` | `?string` | The status code for this tracking update.
13 | | `statusDetail` | `?string` | The status in detail for this tracking update.
14 |
--------------------------------------------------------------------------------
/docs/models/rate-response.md:
--------------------------------------------------------------------------------
1 | # Rate Response
2 | The Rate Response model represents the response from a shipment-creation request.
3 |
4 | ## Properties
5 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
6 |
7 | | Property | Type | Description
8 | | --------------------- | ------------- | --------------------------------- |
9 | | `content` | `string` | The body content of the response. Typically a JSON string, but this depends entirely on the carriers API.
10 | | `response` | `mixed` | The raw response from the carrier API.
11 | | `statusCode` | `?int` | The HTTP status code for the response.
12 | | `errorMessage` | `string` | The error message for the response, if applicable.
13 | | `rates` | `array` | A collection of [Rate](docs:models/rate) models.
14 |
--------------------------------------------------------------------------------
/docs/models/label-response.md:
--------------------------------------------------------------------------------
1 | # Label Response
2 | The Label Response model represents the response from a shipment-creation request.
3 |
4 | ## Properties
5 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
6 |
7 | | Property | Type | Description
8 | | --------------------- | ------------- | --------------------------------- |
9 | | `content` | `string` | The body content of the response. Typically a JSON string, but this depends entirely on the carriers API.
10 | | `response` | `mixed` | The raw response from the carrier API.
11 | | `statusCode` | `?int` | The HTTP status code for the response.
12 | | `errorMessage` | `string` | The error message for the response, if applicable.
13 | | `labels` | `array` | A collection of [Label](docs:models/label) models.
14 |
--------------------------------------------------------------------------------
/docs/carriers/tnt-australia.md:
--------------------------------------------------------------------------------
1 | # TNT Australia
2 | Shippy provides the following feature support for TNT Australia.
3 |
4 | - Rates
5 |
6 | ## API Credentials
7 | To use TNT Australia, you'll need to connect to their API.
8 |
9 | 1. Go to TNT Australia Shipping Tools and register for API access.
10 | 1. Copy the **Account Number** from TNT Australia as the `accountNumber` with the Shippy carrier.
11 | 1. Copy the **Username** from TNT Australia as the `username` with the Shippy carrier.
12 | 1. Copy the **Password** from TNT Australia as the `password` with the Shippy carrier.
13 |
14 | ```php
15 | use verbb\shippy\carriers\TNTAustralia;
16 |
17 | new TNTAustralia([
18 | 'isProduction' => false,
19 | 'accountNumber' => '•••••••••••••••••••••••••••••••••••',
20 | 'username' => '••••••••••••••••',
21 | 'password' => '••••••••••••••••',
22 | ]);
23 | ```
24 |
--------------------------------------------------------------------------------
/src/rates/postnl/InternationalPakketNoTrackAndTrace.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 2000,
19 | 'price' => [
20 | self::ZONE_NL => false,
21 | self::ZONE_EU1 => 980,
22 | self::ZONE_EU2 => 1260,
23 | self::ZONE_EU3 => false,
24 | self::ZONE_WORLD => 1820,
25 | ],
26 | ],
27 | ];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/docs/models/tracking-response.md:
--------------------------------------------------------------------------------
1 | # Tracking Response
2 | The Tracking Response model represents the response from a shipment-creation request.
3 |
4 | ## Properties
5 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
6 |
7 | | Property | Type | Description
8 | | --------------------- | ------------- | --------------------------------- |
9 | | `content` | `string` | The body content of the response. Typically a JSON string, but this depends entirely on the carriers API.
10 | | `response` | `mixed` | The raw response from the carrier API.
11 | | `statusCode` | `?int` | The HTTP status code for the response.
12 | | `errorMessage` | `string` | The error message for the response, if applicable.
13 | | `tracking` | `array` | A collection of [Tracking](docs:models/tracking) models.
14 |
--------------------------------------------------------------------------------
/docs/carriers/sendle.md:
--------------------------------------------------------------------------------
1 | # Sendle
2 | Shippy provides the following feature support for Sendle.
3 |
4 | - Rates
5 | - Tracking
6 | - Labels
7 |
8 | ## API Credentials
9 | To use Sendle, you'll need to connect to their API.
10 |
11 | 1. Go to Sendle and login to your account.
12 | 1. You might prefer to create a Sandbox Sendle account for testing.
13 | 1. From the **Dashboard** visit the **Settings** tab from the sidebar. Click on the **Integrations** tab.
14 | 1. Copy the **Sendle ID** from Sendle as the `sendleId` with the Shippy carrier.
15 | 1. Copy the **API Key** from Sendle as the `apiKey` with the Shippy carrier.
16 |
17 | ```php
18 | use verbb\shippy\carriers\Sendle;
19 |
20 | new Sendle([
21 | 'isProduction' => false,
22 | 'sendleId' => '••••••••••••••••',
23 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
24 | ]);
25 | ```
26 |
--------------------------------------------------------------------------------
/docs/carriers/bring.md:
--------------------------------------------------------------------------------
1 | # Bring
2 | Shippy provides the following feature support for Bring.
3 |
4 | - Rates
5 | - Tracking
6 | - Labels
7 |
8 | ## API Credentials
9 | To use Bring, you'll need to connect to their API.
10 |
11 | 1. Go to Bring and login to your account.
12 | 1. From the **Dashboard** visit the **Settings and API** page and generate your API keys.
13 | 1. Copy the **Username** from Bring as the `username` with the Shippy carrier.
14 | 1. Copy the **API Key** from Bring as the `apiKey` with the Shippy carrier.
15 |
16 | To create labels, you'll be required to supply a few more details.
17 |
18 | ```php
19 | use verbb\shippy\carriers\Bring;
20 |
21 | new Bring([
22 | 'isProduction' => false,
23 | 'username' => '••••••••••••••••',
24 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
25 |
26 | // Required for labels
27 | 'clientUrl' => 'https://verbb.io',
28 | 'customerNumber' => '••••••••••',
29 | ]);
30 | ```
31 |
--------------------------------------------------------------------------------
/docs/models/request.md:
--------------------------------------------------------------------------------
1 | # Request
2 | A Request is a generic model for making a HTTP request for a given [HTTP Client](docs:models/http-client). Whenever requests need to be made to carrier APIs, it should be through a Request model. As such, it supports native [Guzzle](https://docs.guzzlephp.org/en/stable/request-options.html) requests parameters.
3 |
4 | ## Properties
5 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
6 |
7 | | Property | Type | Description
8 | | ----------------- | ----------------- | --------------------------------- |
9 | | `httpClient` | `HttpClient` | The [HTTP Client](docs:models/http-client) the request should use.
10 | | `method` | `string` | The HTTP method to use. Default to `POST`.
11 | | `endpoint` | `string` | The relative endpoint to request to.
12 | | `payload` | `array` | The payload of data to send.
13 |
--------------------------------------------------------------------------------
/docs/carriers/fedex.md:
--------------------------------------------------------------------------------
1 | # FedEx
2 | Shippy provides the following feature support for FedEx.
3 |
4 | - Rates
5 | - Tracking
6 | - Labels
7 |
8 | ## API Credentials
9 | To use FedEx, you'll need to connect to their API.
10 |
11 | 1. Go to FedEx and login to your account.
12 | 1. Follow the Get Started guide to create a **Project**.
13 | 1. Copy the **API Key** from FedEx as the `clientId` with the Shippy carrier.
14 | 1. Copy the **Secret Key** from FedEx as the `clientSecret` with the Shippy carrier.
15 | 1. Copy the **Shipping Account** from FedEx as the `accountNumber` with the Shippy carrier.
16 |
17 | ```php
18 | use verbb\shippy\carriers\FedEx;
19 |
20 | new FedEx([
21 | 'isProduction' => false,
22 | 'clientId' => '••••••••••••••••',
23 | 'clientSecret' => '•••••••••••••••••••••••••••••••••••',
24 | 'accountNumber' => '••••••••••',
25 | ]);
26 | ```
27 |
--------------------------------------------------------------------------------
/docs/carriers/royal-mail.md:
--------------------------------------------------------------------------------
1 | # Royal Mail
2 | Shippy provides the following feature support for Royal Mail.
3 |
4 | - Rates
5 | - Tracking
6 | - Labels
7 |
8 | Royal Mail do not offer live rates via their API. Prices according to the [2023 price guide](https://www.royalmail.com/sites/royalmail.com/files/2023-03/royal-mail-our-prices-april-2023-ta.pdf).
9 |
10 | ## API Credentials
11 | To use Royal Mail, you'll need to connect to their API.
12 |
13 | 1. Go to Royal Mail and login to your account.
14 | 1. From the **My Apps** section, follow the prompts to create a new app.
15 | 1. Copy the **API Key** from Royal Mail as the `clientId` with the Shippy carrier.
16 | 1. Copy the **API Secret** from Royal Mail as the `clientSecret` with the Shippy carrier.
17 |
18 | ```php
19 | use verbb\shippy\carriers\RoyalMail;
20 |
21 | new RoyalMail([
22 | 'isProduction' => false,
23 | 'clientId' => '••••••••••••••••',
24 | 'clientSecret' => '••••••••••••••••',
25 | ]);
26 | ```
27 |
--------------------------------------------------------------------------------
/docs/carriers/usps.md:
--------------------------------------------------------------------------------
1 | # USPS
2 | Shippy provides the following feature support for USPS.
3 |
4 | - Rates
5 | - Tracking
6 | - Labels
7 |
8 | ## API Credentials
9 | To use USPS, you'll need to connect to their API.
10 |
11 | 1. Go to USPS and login to your account.
12 | 1. From the **Apps** section, follow the prompts to create a new app.
13 | 1. Copy the **Consumer Key** from USPS as the `clientId` with the Shippy carrier.
14 | 1. Copy the **Consumer Secret** from USPS as the `clientSecret` with the Shippy carrier.
15 |
16 | To create labels, you'll be required to supply a few more details.
17 |
18 | ```php
19 | use verbb\shippy\carriers\USPS;
20 |
21 | new USPS([
22 | 'isProduction' => false,
23 | 'clientId' => '••••••••••••••••',
24 | 'clientSecret' => '••••••••••••••••',
25 | 'accountNumber' => '••••••••••••••••',
26 |
27 | // Required for labels
28 | 'customerRegistrationId' => '••••••••••••••••',
29 | 'mailerId' => '••••••••••••••••',
30 | ]);
31 | ```
32 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2024 Verbb
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/docs/models/label.md:
--------------------------------------------------------------------------------
1 | # Label
2 | When a [Shipment](docs:models/shipment) is created and lodged, a Label model will be created.
3 |
4 | ## Properties
5 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
6 |
7 | | Property | Type | Description
8 | | --------------------- | --------------------- | --------------------------------- |
9 | | `carrier` | `CarrierInterface` | The carrier associated with the label.
10 | | `rate` | `Rate` | The [Rate](docs:models/rate) model associated with the label.
11 | | `trackingNumber` | `?string` | The tracking number the label is for.
12 | | `labelId` | `?string` | The carrier label ID.
13 | | `labelData` | `?string` | The raw data for the label. This is typically a `base64encoded` string representing a PDF, GIF or PNG for the actual label image.
14 | | `labelMime` | `?string` | The mime-type for the label data, which denotes the type of file the data is encoded for.
15 | | `response` | `array` | The raw response from the carrier for the consignment.
16 |
17 |
--------------------------------------------------------------------------------
/docs/carriers/dhl-express.md:
--------------------------------------------------------------------------------
1 | # DHL Express
2 | Shippy provides the following feature support for DHL Express.
3 |
4 | - Rates
5 | - Tracking
6 | - Labels
7 |
8 | ## API Credentials
9 | To use DHL Express, you'll need to connect to their API.
10 |
11 | 1. Go to DHL Express and login to your account.
12 | 1. From the **Apps** section, follow the prompts to create a new app.
13 | 1. From the list of available APIs, select (as appropriate)
14 | - **DHL Express - MyDHL API**
15 | - **Shipment Tracking - Unified**
16 | 1. Copy the **API Key** from DHL Express as the `clientId` with the Shippy carrier.
17 | 1. Copy the **Username** from DHL Express as the `username` with the Shippy carrier.
18 | 1. Copy the **Password** from DHL Express as the `password` with the Shippy carrier.
19 | 1. Copy the **Account Number** from DHL Express as the `accountNumber` with the Shippy carrier.
20 |
21 | ```php
22 | use verbb\shippy\carriers\DHLExpress;
23 |
24 | new DHLExpress([
25 | 'isProduction' => false,
26 | 'clientId' => '•••••••••••••••••••••••••••••••••••',
27 | 'username' => '••••••••••••••••',
28 | 'password' => '••••••••••••••••',
29 | 'accountNumber' => '••••••••••••••••',
30 | ]);
31 | ```
32 |
--------------------------------------------------------------------------------
/docs/carriers/canada-post.md:
--------------------------------------------------------------------------------
1 | # Canada Post
2 | Shippy provides the following feature support for Canada Post.
3 |
4 | - Rates
5 | - Tracking
6 | - Labels
7 |
8 | ## API Credentials
9 | To use Canada Post, you'll need to connect to their API.
10 |
11 | 1. Go to Canada Post Developers Centre and register for API access.
12 | 1. Copy the **Customer Number** from Canada Post as the `customerNumber` with the Shippy carrier.
13 | 1. Copy the **Username** from Canada Post as the `username` with the Shippy carrier.
14 | 1. Copy the **Password** from Canada Post as the `password` with the Shippy carrier.
15 | 1. Copy the **Contract ID** from Canada Post as the `contractId` with the Shippy carrier.
16 |
17 | To create labels, you'll be required to supply a few more details.
18 |
19 | ```php
20 | use verbb\shippy\carriers\Canada Post;
21 |
22 | new Canada Post([
23 | 'isProduction' => false,
24 | 'username' => '••••••••••••••••',
25 | 'password' => '••••••••••••••••',
26 | 'customerNumber' => '•••••••••••••••••••••••••••••••••••',
27 |
28 | // Required for labels
29 | 'contractId' => '•••••••••••••••••••••••••••••••••••',
30 | ]);
31 | ```
32 |
--------------------------------------------------------------------------------
/docs/models/shipment.md:
--------------------------------------------------------------------------------
1 | # Shipment
2 | A Shipment model represents the top-level model that you work with from start to end.
3 |
4 | A shipment is assigned a origin and destination [Address](docs:models/address) and one or more [Package](docs:models/package) models. You also assign it one or more Carriers to fetch rates for.
5 |
6 | Once rates have been fetched, you can also generate labels for a shipment, which would be lodged with the carrier for pickup and dispatch.
7 |
8 | ## Properties
9 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
10 |
11 | | Property | Type | Description
12 | | ----------------- | ----------------- | --------------------------------- |
13 | | `from` | `Address` | The [Address](docs:models/address) model for the origin sender.
14 | | `to` | `Address` | The [Address](docs:models/address) model for the destination receiver.
15 | | `currency` | `string` | The currency the shipment should be using.
16 | | `packages` | `array` | A collection of [Package](docs:models/package) models for the shipment.
17 | | `carriers` | `array` | A collection of Carriers to fetch rates for.
18 |
--------------------------------------------------------------------------------
/src/models/ResourceResponse.php:
--------------------------------------------------------------------------------
1 | response;
31 | }
32 |
33 | public function setResponse(array $response): ResourceResponse
34 | {
35 | $this->response = $response;
36 | return $this;
37 | }
38 |
39 | public function getErrors(): array
40 | {
41 | return $this->errors;
42 | }
43 |
44 | public function setErrors(array $errors): ResourceResponse
45 | {
46 | $this->errors = $errors;
47 | return $this;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/events/RateEvent.php:
--------------------------------------------------------------------------------
1 | carrier;
23 | }
24 |
25 | public function setCarrier(?CarrierInterface $carrier): RateEvent
26 | {
27 | $this->carrier = $carrier;
28 | return $this;
29 | }
30 |
31 | public function getRequest(): ?Request
32 | {
33 | return $this->request;
34 | }
35 |
36 | public function setRequest(?Request $request): RateEvent
37 | {
38 | $this->request = $request;
39 | return $this;
40 | }
41 |
42 | public function getData(): array
43 | {
44 | return $this->data;
45 | }
46 |
47 | public function setData(array $data): RateEvent
48 | {
49 | $this->data = $data;
50 | return $this;
51 | }
52 | }
--------------------------------------------------------------------------------
/docs/carriers/new-zealand-post.md:
--------------------------------------------------------------------------------
1 | # New Zealand Post
2 | Shippy provides the following feature support for New Zealand Post.
3 |
4 | - Rates
5 | - Tracking
6 | - Labels
7 |
8 | ## API Credentials
9 | To use New Zealand Post, you'll need to connect to their API.
10 |
11 | 1. Go to New Zealand Post and login to your account. Complete the commercial access form.
12 | 1. Request API access for an application.
13 | 1. Once access have been granted, click “add a new application”.
14 | 1. Include OAuth 2.0 grant type "Client Credentials Grant".
15 | 1. Navigate to your application.
17 | 1. Copy the **Client ID** from New Zealand Post as the `clientId` with the Shippy carrier.
18 | 1. Copy the **Client Secret** from New Zealand Post as the `clientSecret` with the Shippy carrier.
19 |
20 | ```php
21 | use verbb\shippy\carriers\NewZealandPost;
22 |
23 | new NewZealandPost([
24 | 'isProduction' => false,
25 | 'clientId' => '••••••••••••••••',
26 | 'clientSecret' => '•••••••••••••••••••••••••••••••••••',
27 | ]);
28 | ```
29 |
--------------------------------------------------------------------------------
/src/events/LabelEvent.php:
--------------------------------------------------------------------------------
1 | carrier;
23 | }
24 |
25 | public function setCarrier(?CarrierInterface $carrier): LabelEvent
26 | {
27 | $this->carrier = $carrier;
28 | return $this;
29 | }
30 |
31 | public function getRequest(): ?Request
32 | {
33 | return $this->request;
34 | }
35 |
36 | public function setRequest(?Request $request): LabelEvent
37 | {
38 | $this->request = $request;
39 | return $this;
40 | }
41 |
42 | public function getData(): array
43 | {
44 | return $this->data;
45 | }
46 |
47 | public function setData(array $data): LabelEvent
48 | {
49 | $this->data = $data;
50 | return $this;
51 | }
52 | }
--------------------------------------------------------------------------------
/src/events/TrackingEvent.php:
--------------------------------------------------------------------------------
1 | carrier;
23 | }
24 |
25 | public function setCarrier(?CarrierInterface $carrier): TrackingEvent
26 | {
27 | $this->carrier = $carrier;
28 | return $this;
29 | }
30 |
31 | public function getRequest(): ?Request
32 | {
33 | return $this->request;
34 | }
35 |
36 | public function setRequest(?Request $request): TrackingEvent
37 | {
38 | $this->request = $request;
39 | return $this;
40 | }
41 |
42 | public function getData(): array
43 | {
44 | return $this->data;
45 | }
46 |
47 | public function setData(array $data): TrackingEvent
48 | {
49 | $this->data = $data;
50 | return $this;
51 | }
52 | }
--------------------------------------------------------------------------------
/docs/models/rate.md:
--------------------------------------------------------------------------------
1 | # Rate
2 | A Rate model represents the estimated cost to ship a shipment from an origin address to a destination address.
3 |
4 | ## Properties
5 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
6 |
7 | | Property | Type | Description
8 | | ------------------------- | --------------------- | --------------------------------- |
9 | | `carrier` | `CarrierInterface` | The carrier associated with the rate.
10 | | `serviceName` | `?string` | The name of the carrier service this rate is for.
11 | | `serviceCode` | `?string` | The code or identifier of the carrier service this rate is for.
12 | | `rate` | `?string` | The amount for the rate.
13 | | `currency` | `?string` | The currency code for the rate.
14 | | `deliveryDays` | `?int` | The number of delivery days estimated (carrier support).
15 | | `deliveryDate` | `?DateTime` | The date for estimated delivery (carrier support).
16 | | `deliveryDateGuaranteed` | `?bool` | Whether the delivery date is guaranteed (carrier support).
17 | | `response` | `array` | The raw response from the carrier API for the rate response.
18 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/ParcelforceExpress10.php:
--------------------------------------------------------------------------------
1 | [
21 | 'packet-200' => [
22 | 2000 => 2745,
23 | 5000 => 2745,
24 | 10000 => 3045,
25 | 15000 => 3395,
26 | 20000 => 3395,
27 | 25000 => 3795,
28 | 30000 => 3795,
29 | ],
30 | ],
31 | ];
32 |
33 | $boxes = [
34 | 'packet-200' => [
35 | 'length' => 1500,
36 | 'width' => 750,
37 | 'height' => 750,
38 | 'weight' => 30000,
39 | ],
40 | ];
41 |
42 | $boxPricing = self::getBoxPricing($boxes, $bands);
43 |
44 | foreach ($boxPricing as $key => $box) {
45 | // 20% VAT
46 | if (!self::$includeVat) {
47 | $boxPricing[$key]['price'] = $box['price'] / 1.2;
48 | }
49 | }
50 |
51 | return $boxPricing;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/ParcelforceExpress24.php:
--------------------------------------------------------------------------------
1 | [
21 | 'packet-150' => [
22 | 2000 => 1345,
23 | 5000 => 1345,
24 | 10000 => 1645,
25 | 15000 => 1995,
26 | 20000 => 1995,
27 | 25000 => 2395,
28 | 30000 => 2395,
29 | ],
30 | ],
31 | ];
32 |
33 | $boxes = [
34 | 'packet-150' => [
35 | 'length' => 1500,
36 | 'width' => 750,
37 | 'height' => 750,
38 | 'weight' => 30000,
39 | ],
40 | ];
41 |
42 | $boxPricing = self::getBoxPricing($boxes, $bands);
43 |
44 | foreach ($boxPricing as $key => $box) {
45 | // 20% VAT
46 | if (!self::$includeVat) {
47 | $boxPricing[$key]['price'] = $box['price'] / 1.2;
48 | }
49 | }
50 |
51 | return $boxPricing;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/ParcelforceExpress48.php:
--------------------------------------------------------------------------------
1 | [
21 | 'packet-150' => [
22 | 2000 => 1295,
23 | 5000 => 1295,
24 | 10000 => 1495,
25 | 15000 => 1795,
26 | 20000 => 1795,
27 | 25000 => 2095,
28 | 30000 => 2095,
29 | ],
30 | ],
31 | ];
32 |
33 | $boxes = [
34 | 'packet-150' => [
35 | 'length' => 1500,
36 | 'width' => 750,
37 | 'height' => 750,
38 | 'weight' => 30000,
39 | ],
40 | ];
41 |
42 | $boxPricing = self::getBoxPricing($boxes, $bands);
43 |
44 | foreach ($boxPricing as $key => $box) {
45 | // 20% VAT
46 | if (!self::$includeVat) {
47 | $boxPricing[$key]['price'] = $box['price'] / 1.2;
48 | }
49 | }
50 |
51 | return $boxPricing;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/ParcelforceExpressAm.php:
--------------------------------------------------------------------------------
1 | [
21 | 'packet-200' => [
22 | 2000 => 1745,
23 | 5000 => 1745,
24 | 10000 => 2045,
25 | 15000 => 2395,
26 | 20000 => 2395,
27 | 25000 => 2795,
28 | 30000 => 2795,
29 | ],
30 | ],
31 | ];
32 |
33 | $boxes = [
34 | 'packet-200' => [
35 | 'length' => 1500,
36 | 'width' => 750,
37 | 'height' => 750,
38 | 'weight' => 30000,
39 | ],
40 | ];
41 |
42 | $boxPricing = self::getBoxPricing($boxes, $bands);
43 |
44 | foreach ($boxPricing as $key => $box) {
45 | // 20% VAT
46 | if (!self::$includeVat) {
47 | $boxPricing[$key]['price'] = $box['price'] / 1.2;
48 | }
49 | }
50 |
51 | return $boxPricing;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/models/Request.php:
--------------------------------------------------------------------------------
1 | httpClient;
21 | }
22 |
23 | public function setHttpClient(?HttpClient $httpClient): Request
24 | {
25 | $this->httpClient = $httpClient;
26 | return $this;
27 | }
28 |
29 | public function getMethod(): string
30 | {
31 | return $this->method;
32 | }
33 |
34 | public function setMethod(string $method): Request
35 | {
36 | $this->method = $method;
37 | return $this;
38 | }
39 |
40 | public function getEndpoint(): string
41 | {
42 | return $this->endpoint;
43 | }
44 |
45 | public function setEndpoint(string $endpoint): Request
46 | {
47 | $this->endpoint = $endpoint;
48 | return $this;
49 | }
50 |
51 | public function getPayload(): array
52 | {
53 | return $this->payload;
54 | }
55 |
56 | public function setPayload(array $payload): Request
57 | {
58 | $this->payload = $payload;
59 | return $this;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/ParcelforceExpress48Large.php:
--------------------------------------------------------------------------------
1 | [
21 | 'packet-150' => [
22 | 2000 => 4795,
23 | 5000 => 4795,
24 | 10000 => 5495,
25 | 15000 => 6795,
26 | 20000 => 6795,
27 | 25000 => 9095,
28 | 30000 => 9095,
29 | ],
30 | ],
31 | ];
32 |
33 | $boxes = [
34 | 'packet-150' => [
35 | 'length' => 2500,
36 | 'width' => 1250,
37 | 'height' => 1250,
38 | 'weight' => 30000,
39 | ],
40 | ];
41 |
42 | $boxPricing = self::getBoxPricing($boxes, $bands);
43 |
44 | foreach ($boxPricing as $key => $box) {
45 | // 20% VAT
46 | if (!self::$includeVat) {
47 | $boxPricing[$key]['price'] = $box['price'] / 1.2;
48 | }
49 | }
50 |
51 | return $boxPricing;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/docs/models/tracking.md:
--------------------------------------------------------------------------------
1 | # Tracking
2 | A Tracking model represents a singular tracking update from a carrier on a shipment.
3 |
4 | ## Properties
5 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
6 |
7 | | Property | Type | Description
8 | | ------------------------- | --------------------- | --------------------------------- |
9 | | `carrier` | `CarrierInterface` | The carrier associated with the tracking.
10 | | `trackingNumber` | `?string` | The tracking number for the shipment.
11 | | `status` | `?string` | The carrier status for tracking.
12 | | `statusDetail` | `?string` | The carrier status in detail for tracking.
13 | | `estimatedDelivery` | `?DateTime` | The estimated delivery date for the shipment.
14 | | `signedBy` | `?string` | Who the parcel was signed by upon delivery (carrier support).
15 | | `weight` | `?string` | The weight of the shipment (carrier support).
16 | | `weightUnit` | `?string` | The weight unit of the shipment (carrier support).
17 | | `details` | `array` | A collection of [Tracking Detail](docs:models/tracking-detail) models.
18 | | `errors` | `array` | A collection of any errors encountered for tracking.
19 | | `response` | `array` | The raw response from the carrier API for the rate response.
20 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/ParcelforceExpress9.php:
--------------------------------------------------------------------------------
1 | [
21 | 'packet-200' => [
22 | 2000 => 5745,
23 | 5000 => 5745,
24 | 10000 => 6545,
25 | 15000 => 7395,
26 | 20000 => 7395,
27 | 25000 => 8795,
28 | 30000 => 8795,
29 | ],
30 | ],
31 | ];
32 |
33 | $boxes = [
34 | 'packet-200' => [
35 | 'length' => 1500,
36 | 'width' => 750,
37 | 'height' => 750,
38 | 'weight' => 30000,
39 | 'itemValue' => 500,
40 | ],
41 | ];
42 |
43 | $boxPricing = self::getBoxPricing($boxes, $bands);
44 |
45 | foreach ($boxPricing as $key => $box) {
46 | // 20% VAT
47 | if (!self::$includeVat) {
48 | $boxPricing[$key]['price'] = $box['price'] / 1.2;
49 | }
50 | }
51 |
52 | return $boxPricing;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "verbb/shippy",
3 | "description": "A framework agnostic, multi-carrier shipping library for PHP.",
4 | "version": "1.2.15",
5 | "keywords": [
6 | "australia-post",
7 | "auspost",
8 | "ups",
9 | "usps",
10 | "fedex"
11 | ],
12 | "support": {
13 | "email": "support@verbb.io",
14 | "issues": "https://github.com/verbb/shippy/issues?state=open",
15 | "source": "https://github.com/verbb/shippy",
16 | "docs": "https://github.com/verbb/shippy",
17 | "rss": "https://github.com/verbb/shippy/commits/v2.atom"
18 | },
19 | "license": "MIT",
20 | "authors": [
21 | {
22 | "name": "Verbb",
23 | "homepage": "https://verbb.io"
24 | }
25 | ],
26 | "require": {
27 | "php": "^8.0",
28 | "ext-json": "*",
29 | "commerceguys/addressing": "^1.0 || ^2.0",
30 | "dvdoug/boxpacker": "^3.0 || ^4.0",
31 | "guzzlehttp/guzzle": "^7.0",
32 | "illuminate/collections": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
33 | "php-units-of-measure/php-units-of-measure": "^2.0",
34 | "psr/log": "^1.0 || ^2.0 || ^3.0",
35 | "symfony/event-dispatcher": "^5.0 || ^6.0 || ^7.0",
36 | "symfony/serializer": "^5.0 || ^6.0 || ^7.0"
37 | },
38 | "require-dev": {
39 | "monolog/monolog": "^1.0 || ^2.0"
40 | },
41 | "config": {
42 | "sort-packages": true,
43 | "optimize-autoloader": true
44 | },
45 | "autoload": {
46 | "psr-4": {
47 | "verbb\\shippy\\": "src/"
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/helpers/Xml.php:
--------------------------------------------------------------------------------
1 | encode($data, 'xml', $options);
28 | } catch (Throwable $e) {
29 | Shippy::error('XML Encode Error: “{message}” {file}:{line}', [
30 | 'message' => $e->getMessage(),
31 | 'file' => $e->getFile(),
32 | 'line' => $e->getLine(),
33 | ]);
34 |
35 | return '';
36 | }
37 | }
38 |
39 | public static function decode(?string $data): array
40 | {
41 | try {
42 | return self::getXmlEncoder()->decode((string)$data, 'xml');
43 | } catch (Throwable $e) {
44 | Shippy::error('XML Decode Error: “{message}” {file}:{line}', [
45 | 'message' => $e->getMessage(),
46 | 'file' => $e->getFile(),
47 | 'line' => $e->getLine(),
48 | ]);
49 |
50 | return [];
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/src/helpers/Json.php:
--------------------------------------------------------------------------------
1 | encode($data, 'json', $options);
28 | } catch (Throwable $e) {
29 | Shippy::error('JSON Encode Error: “{message}” {file}:{line}', [
30 | 'message' => $e->getMessage(),
31 | 'file' => $e->getFile(),
32 | 'line' => $e->getLine(),
33 | ]);
34 |
35 | return '';
36 | }
37 | }
38 |
39 | public static function decode(?string $data): array
40 | {
41 | try {
42 | return self::getJsonEncoder()->decode((string)$data, 'json');
43 | } catch (Throwable $e) {
44 | Shippy::error('JSON Decode Error: “{message}” {file}:{line}', [
45 | 'message' => $e->getMessage(),
46 | 'file' => $e->getFile(),
47 | 'line' => $e->getLine(),
48 | ]);
49 |
50 | return [];
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/docs/models/address.md:
--------------------------------------------------------------------------------
1 | # Address
2 | An Address model is used to represent a location for both the sender and delivery of a shipment. It includes the physical address, name, email and phone.
3 |
4 | ## Properties
5 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
6 |
7 | | Property | Type | Description
8 | | --------------------- | ------------- | --------------------------------- |
9 | | `firstName` | `?string` | The first name of the sender or receiver.
10 | | `lastName` | `?string` | The last name of the sender or receiver.
11 | | `companyName` | `?string` | The company name of the sender or receiver.
12 | | `email` | `?string` | The email of the sender or receiver.
13 | | `phone` | `?string` | The phone number of the sender or receiver.
14 | | `street1` | `?string` | The street address (line 1) of the sender or receiver.
15 | | `street2` | `?string` | The street address (line 2) of the sender or receiver.
16 | | `street3` | `?string` | The street address (line 3) of the sender or receiver.
17 | | `city` | `?string` | The city of the sender or receiver.
18 | | `postalCode` | `?string` | The postal or zip code of the sender or receiver.
19 | | `countryCode` | `?string` | The country code of the sender or receiver.
20 | | `stateProvince` | `?string` | The state or province of the sender or receiver.
21 | | `isResidential` | `bool` | Whether this address is considered residential. Some providers require this definition.
22 |
--------------------------------------------------------------------------------
/docs/models/package.md:
--------------------------------------------------------------------------------
1 | # Package
2 | A Package model is used to represent the "thing" to ship, and is sent to the carrier API. It includes dimensions, weight and units associated with these values.
3 |
4 | A package should represent a box, satchel or parcel with your carrier, and can likely handle multiple items within it. Shippy doesn't handle packing your items into a Package.
5 |
6 | ## Properties
7 | Properties are `protected` and can be accessed with their `getPropertyName()` getter method or set via `setPropertyName(value)` setter method.
8 |
9 | | Property | Type | Description
10 | | --------------------- | ----------------- | --------------------------------- |
11 | | `weight` | `?string` | The total weight of the package.
12 | | `width` | `?string` | The total width of the package.
13 | | `length` | `?string` | The total length of the package.
14 | | `height` | `?string` | The total height of the package.
15 | | `price` | `?string` | The price for the contents of the package, used for insurance and customs.
16 | | `weightUnit` | `string` | The weight unit. Default to `g`.
17 | | `dimensionUnit` | `string` | The dimension unit. Default to `mm`.
18 | | `packageType` | `?string` | For carriers that need a "type".
19 | | `packagePreset` | `?string` | For carriers that support a pre-defined package name or service.
20 | | `reference` | `?string` | For carriers that support storing a reference against a package.
21 | | `description` | `?string` | For carriers that support storing a description against a package.
22 | | `isDocument` | `bool` | Whether the package should be classified as documents, for the carriers that support this definition.
23 |
--------------------------------------------------------------------------------
/src/helpers/StringHelper.php:
--------------------------------------------------------------------------------
1 | Australia Post Developers website and register for an API Key.
15 | 1. Use the **API Key** from Australia Post as the `apiKey` with the Shippy carrier.
16 |
17 | ```php
18 | use verbb\shippy\carriers\AustraliaPost;
19 |
20 | new AustraliaPost([
21 | 'isProduction' => false,
22 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
23 | ]);
24 | ```
25 |
26 | ### Shipping and Tracking (All)
27 | A more involved API that handles all features. You will be required to have an Australia Post account.
28 |
29 | 1. Go to Australia Post Developers website and register for an API Key.
30 | 1. Provide your Australia Post (eParcel) account number and complete the registration process.
31 | 1. Use the **API Key** from Australia Post as the `apiKey` with the Shippy carrier.
32 | 1. Use the **Password** from Australia Post as the `password` with the Shippy carrier.
33 | 1. Use the **Account Number** from Australia Post as the `accountNumber` with the Shippy carrier.
34 |
35 | ```php
36 | use verbb\shippy\carriers\AustraliaPost;
37 |
38 | new AustraliaPost([
39 | 'isProduction' => false,
40 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
41 | 'password' => '•••••••••••••••',
42 | 'accountNumber' => '•••••••••',
43 | ]);
44 | ```
--------------------------------------------------------------------------------
/src/models/Response.php:
--------------------------------------------------------------------------------
1 | content;
24 | }
25 |
26 | public function setContent(string $content): Response
27 | {
28 | $this->content = $content;
29 | return $this;
30 | }
31 |
32 | public function getResponse(): mixed
33 | {
34 | return $this->response;
35 | }
36 |
37 | public function setResponse(mixed $response): Response
38 | {
39 | $this->response = $response;
40 | return $this;
41 | }
42 |
43 | public function getStatusCode(): ?int
44 | {
45 | return $this->statusCode;
46 | }
47 |
48 | public function setStatusCode(?int $statusCode): Response
49 | {
50 | $this->statusCode = $statusCode;
51 | return $this;
52 | }
53 |
54 | public function getErrorMessage(): ?string
55 | {
56 | return $this->errorMessage;
57 | }
58 |
59 | public function setErrorMessage(?string $errorMessage): Response
60 | {
61 | $this->errorMessage = $errorMessage;
62 | return $this;
63 | }
64 |
65 | public function json(): array
66 | {
67 | return Json::decode($this->content);
68 | }
69 |
70 | public function xml(): array
71 | {
72 | return Xml::decode($this->content);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/rates/postnl/DomesticBrief.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 380,
16 | 'width' => 265,
17 | 'height' => 32,
18 | 'weight' => 20,
19 | 'price' => [
20 | self::ZONE_NL => 83,
21 | ],
22 | ],
23 | 'brief-50g' => [
24 | 'length' => 380,
25 | 'width' => 265,
26 | 'height' => 32,
27 | 'weight' => 50,
28 | 'price' => [
29 | self::ZONE_NL => 166,
30 | ],
31 | ],
32 | 'brief-100g' => [
33 | 'length' => 380,
34 | 'width' => 265,
35 | 'height' => 32,
36 | 'weight' => 100,
37 | 'price' => [
38 | self::ZONE_NL => 249,
39 | ],
40 | ],
41 | 'brief-250g' => [
42 | 'length' => 380,
43 | 'width' => 265,
44 | 'height' => 32,
45 | 'weight' => 250,
46 | 'price' => [
47 | self::ZONE_NL => 332,
48 | ],
49 | ],
50 | 'brief-2kg' => [
51 | 'length' => 380,
52 | 'width' => 265,
53 | 'height' => 32,
54 | 'weight' => 2000,
55 | 'price' => [
56 | self::ZONE_NL => 415,
57 | ],
58 | ],
59 | ];
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/rates/postnl/DomesticPakket.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 2000,
19 | 'price' => [
20 | self::ZONE_NL => 695,
21 | ],
22 | ],
23 | 'pakket-5kg' => [
24 | 'length' => 1000,
25 | 'width' => 500,
26 | 'height' => 500,
27 | 'weight' => 5000,
28 | 'price' => [
29 | self::ZONE_NL => 695,
30 | ],
31 | ],
32 | 'pakket-10kg' => [
33 | 'length' => 1760,
34 | 'width' => 780,
35 | 'height' => 580,
36 | 'weight' => 10000,
37 | 'price' => [
38 | self::ZONE_NL => 695,
39 | ],
40 | ],
41 | 'pakket-20kg' => [
42 | 'length' => 1760,
43 | 'width' => 780,
44 | 'height' => 580,
45 | 'weight' => 20000,
46 | 'price' => [
47 | self::ZONE_NL => 1325,
48 | ],
49 | ],
50 | 'pakket-30kg' => [
51 | 'length' => 1760,
52 | 'width' => 780,
53 | 'height' => 580,
54 | 'weight' => 30000,
55 | 'price' => [
56 | self::ZONE_NL => 1325,
57 | ],
58 | ],
59 | ];
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/rates/postnl/DomesticAangetekend.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 2000,
19 | 'price' => [
20 | self::ZONE_NL => 860,
21 | ],
22 | ],
23 | 'pakket-5kg' => [
24 | 'length' => 1000,
25 | 'width' => 500,
26 | 'height' => 500,
27 | 'weight' => 5000,
28 | 'price' => [
29 | self::ZONE_NL => 860,
30 | ],
31 | ],
32 | 'pakket-10kg' => [
33 | 'length' => 1760,
34 | 'width' => 780,
35 | 'height' => 580,
36 | 'weight' => 10000,
37 | 'price' => [
38 | self::ZONE_NL => 860,
39 | ],
40 | ],
41 | 'pakket-20kg' => [
42 | 'length' => 1760,
43 | 'width' => 780,
44 | 'height' => 580,
45 | 'weight' => 20000,
46 | 'price' => [
47 | self::ZONE_NL => 1490,
48 | ],
49 | ],
50 | 'pakket-30kg' => [
51 | 'length' => 1760,
52 | 'width' => 780,
53 | 'height' => 580,
54 | 'weight' => 30000,
55 | 'price' => [
56 | self::ZONE_NL => 1490,
57 | ],
58 | ],
59 | ];
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/rates/postnl/DomesticBetaalservice.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 2000,
19 | 'price' => [
20 | self::ZONE_NL => 1835,
21 | ],
22 | ],
23 | 'pakket-5kg' => [
24 | 'length' => 1000,
25 | 'width' => 500,
26 | 'height' => 500,
27 | 'weight' => 5000,
28 | 'price' => [
29 | self::ZONE_NL => 1835,
30 | ],
31 | ],
32 | 'pakket-10kg' => [
33 | 'length' => 1760,
34 | 'width' => 780,
35 | 'height' => 580,
36 | 'weight' => 10000,
37 | 'price' => [
38 | self::ZONE_NL => 1835,
39 | ],
40 | ],
41 | 'pakket-20kg' => [
42 | 'length' => 1760,
43 | 'width' => 780,
44 | 'height' => 580,
45 | 'weight' => 20000,
46 | 'price' => [
47 | self::ZONE_NL => 2320,
48 | ],
49 | ],
50 | 'pakket-30kg' => [
51 | 'length' => 1760,
52 | 'width' => 780,
53 | 'height' => 580,
54 | 'weight' => 30000,
55 | 'price' => [
56 | self::ZONE_NL => 2320,
57 | ],
58 | ],
59 | ];
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/rates/postnl/DomesticVerzekerservice.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 2000,
19 | 'price' => [
20 | self::ZONE_NL => 1445,
21 | ],
22 | ],
23 | 'pakket-5kg' => [
24 | 'length' => 1000,
25 | 'width' => 500,
26 | 'height' => 500,
27 | 'weight' => 5000,
28 | 'price' => [
29 | self::ZONE_NL => 1445,
30 | ],
31 | ],
32 | 'pakket-10kg' => [
33 | 'length' => 1760,
34 | 'width' => 780,
35 | 'height' => 580,
36 | 'weight' => 10000,
37 | 'price' => [
38 | self::ZONE_NL => 1445,
39 | ],
40 | ],
41 | 'pakket-20kg' => [
42 | 'length' => 1760,
43 | 'width' => 780,
44 | 'height' => 580,
45 | 'weight' => 20000,
46 | 'price' => [
47 | self::ZONE_NL => 2075,
48 | ],
49 | ],
50 | 'pakket-30kg' => [
51 | 'length' => 1760,
52 | 'width' => 780,
53 | 'height' => 580,
54 | 'weight' => 30000,
55 | 'price' => [
56 | self::ZONE_NL => 2075,
57 | ],
58 | ],
59 | ];
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/LogTrait.php:
--------------------------------------------------------------------------------
1 | error(self::t($message, $params));
31 | }
32 |
33 | public static function warning(string $message, array $params = []): void
34 | {
35 | static::getLogger()->warning(self::t($message, $params));
36 | }
37 |
38 | public static function notice(string $message, array $params = []): void
39 | {
40 | static::getLogger()->notice(self::t($message, $params));
41 | }
42 |
43 | public static function info(string $message, array $params = []): void
44 | {
45 | static::getLogger()->info(self::t($message, $params));
46 | }
47 |
48 | public static function debug(string $message, array $params = []): void
49 | {
50 | static::getLogger()->debug(self::t($message, $params));
51 | }
52 |
53 | public static function t(string $message, array $params = []): string
54 | {
55 | $placeholders = [];
56 |
57 | foreach ($params as $name => $value) {
58 | $placeholders['{' . $name . '}'] = $value;
59 | }
60 |
61 | return ($placeholders === []) ? $message : strtr($message, $placeholders);
62 | }
63 |
64 | }
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/InternationalEconomy.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LETTER => [
22 | 100 => 260,
23 | ],
24 | self::LARGE_LETTER => [
25 | 100 => 350,
26 | 250 => 585,
27 | 500 => 660,
28 | 750 => 775,
29 | ],
30 | self::PACKET => [
31 | 250 => 745,
32 | 500 => 1035,
33 | 750 => 1165,
34 | 1000 => 1300,
35 | 1500 => 1430,
36 | 2000 => 1620,
37 | ],
38 | ],
39 | '2025' => [
40 | self::LETTER => [
41 | 100 => 310,
42 | ],
43 | self::LARGE_LETTER => [
44 | 100 => 410,
45 | 250 => 730,
46 | 500 => 845,
47 | 750 => 1025,
48 | ],
49 | self::PACKET => [
50 | 250 => 930,
51 | 500 => 1400,
52 | 750 => 1445,
53 | 1000 => 1560,
54 | 1500 => 1715,
55 | 2000 => 2025,
56 | ],
57 | ],
58 | ];
59 |
60 | return self::getBoxPricing(self::$internationalDefaultBox, $bands, 20);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/docs/.sidebar.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "Get Started",
4 | "collapsable": false,
5 | "children": [
6 | "get-started/installation",
7 | "get-started/core-concepts",
8 | "get-started/fetching-rates",
9 | "get-started/tracking-status",
10 | "get-started/creating-labels"
11 | ]
12 | },
13 | {
14 | "title": "Carriers",
15 | "collapsable": false,
16 | "children": [
17 | "carriers/aramex",
18 | "carriers/aramex-australia",
19 | "carriers/aramex-new-zealand",
20 | "carriers/australia-post",
21 | "carriers/bring",
22 | "carriers/canada-post",
23 | "carriers/colissimo",
24 | "carriers/dhl-express",
25 | "carriers/fastway",
26 | "carriers/fedex",
27 | "carriers/fedex-freight",
28 | "carriers/interparcel",
29 | "carriers/new-zealand-post",
30 | "carriers/post-nl",
31 | "carriers/royal-mail",
32 | "carriers/sendle",
33 | "carriers/tnt-australia",
34 | "carriers/ups",
35 | "carriers/usps",
36 | "carriers/custom-carrier"
37 | ]
38 | },
39 | {
40 | "title": "API",
41 | "collapsable": false,
42 | "children": [
43 | "api/logging",
44 | "api/events"
45 | ]
46 | },
47 | {
48 | "title": "Models",
49 | "collapsable": false,
50 | "children": [
51 | "models/address",
52 | "models/http-client",
53 | "models/label",
54 | "models/label-response",
55 | "models/package",
56 | "models/rate",
57 | "models/rate-response",
58 | "models/request",
59 | "models/shipment",
60 | "models/tracking",
61 | "models/tracking-detail",
62 | "models/tracking-response"
63 | ]
64 | }
65 | ]
--------------------------------------------------------------------------------
/src/rates/royalmail/online/InternationalEconomy.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LETTER => [
22 | 100 => 260,
23 | ],
24 | self::LARGE_LETTER => [
25 | 100 => 350,
26 | 250 => 585,
27 | 500 => 660,
28 | 750 => 775,
29 | ],
30 | self::PACKET => [
31 | 100 => 740,
32 | 250 => 740,
33 | 500 => 1030,
34 | 750 => 1160,
35 | 1000 => 1295,
36 | 1250 => 1425,
37 | 1500 => 1425,
38 | 2000 => 1615,
39 | ],
40 | ],
41 | '2025' => [
42 | self::LETTER => [
43 | 100 => 310,
44 | ],
45 | self::LARGE_LETTER => [
46 | 100 => 410,
47 | 250 => 730,
48 | 500 => 845,
49 | 750 => 1025,
50 | ],
51 | self::PACKET => [
52 | 250 => 925,
53 | 500 => 1395,
54 | 750 => 1440,
55 | 1000 => 1555,
56 | 1500 => 1710,
57 | 2000 => 2020,
58 | ],
59 | ],
60 | ];
61 |
62 | return self::getBoxPricing(self::$internationalDefaultBox, $bands, 20);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/models/TrackingDetail.php:
--------------------------------------------------------------------------------
1 | description;
25 | }
26 |
27 | public function setDescription(?string $description): TrackingDetail
28 | {
29 | $this->description = $description;
30 | return $this;
31 | }
32 |
33 | public function getDate(): ?DateTime
34 | {
35 | return $this->date;
36 | }
37 |
38 | public function setDate(DateTime|string|null $date): TrackingDetail
39 | {
40 | $this->date = DateTimeHelper::toDateTime($date);
41 | return $this;
42 | }
43 |
44 | public function getLocation(): ?string
45 | {
46 | return $this->location;
47 | }
48 |
49 | public function setLocation(?string $location): TrackingDetail
50 | {
51 | $this->location = $location;
52 | return $this;
53 | }
54 |
55 | public function getStatus(): ?string
56 | {
57 | return $this->status;
58 | }
59 |
60 | public function setStatus(?string $status): TrackingDetail
61 | {
62 | $this->status = $status;
63 | return $this;
64 | }
65 |
66 | public function getStatusDetail(): ?string
67 | {
68 | return $this->statusDetail;
69 | }
70 |
71 | public function setStatusDetail(?string $statusDetail): TrackingDetail
72 | {
73 | $this->statusDetail = $statusDetail;
74 | return $this;
75 | }
76 |
77 | }
--------------------------------------------------------------------------------
/src/rates/colissimo/DomOutremer.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 500,
19 | 'price' => [
20 | self::ZONE_DOM => 930,
21 | ],
22 | ],
23 | 'pack-1000' => [
24 | 'length' => 1000,
25 | 'width' => 500,
26 | 'height' => 500,
27 | 'weight' => 1000,
28 | 'price' => [
29 | self::ZONE_DOM => 1410,
30 | ],
31 | ],
32 | 'pack-2000' => [
33 | 'length' => 1000,
34 | 'width' => 500,
35 | 'height' => 500,
36 | 'weight' => 2000,
37 | 'price' => [
38 | self::ZONE_DOM => 1920,
39 | ],
40 | ],
41 | 'pack-5000' => [
42 | 'length' => 1000,
43 | 'width' => 500,
44 | 'height' => 500,
45 | 'weight' => 5000,
46 | 'price' => [
47 | self::ZONE_DOM => 2890,
48 | ],
49 | ],
50 | 'pack-10000' => [
51 | 'length' => 1000,
52 | 'width' => 500,
53 | 'height' => 500,
54 | 'weight' => 10000,
55 | 'price' => [
56 | self::ZONE_DOM => 4640,
57 | ],
58 | ],
59 | 'pack-30000' => [
60 | 'length' => 1000,
61 | 'width' => 500,
62 | 'height' => 500,
63 | 'weight' => 30000,
64 | 'price' => [
65 | self::ZONE_DOM => 10360,
66 | ],
67 | ],
68 | ];
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/rates/colissimo/TomOutremer.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 990,
17 | 'height' => 990,
18 | 'weight' => 500,
19 | 'price' => [
20 | self::ZONE_TOM => 1120,
21 | ],
22 | ],
23 | 'pack-1000' => [
24 | 'length' => 1000,
25 | 'width' => 990,
26 | 'height' => 990,
27 | 'weight' => 1000,
28 | 'price' => [
29 | self::ZONE_TOM => 1680,
30 | ],
31 | ],
32 | 'pack-2000' => [
33 | 'length' => 1000,
34 | 'width' => 990,
35 | 'height' => 990,
36 | 'weight' => 2000,
37 | 'price' => [
38 | self::ZONE_TOM => 2960,
39 | ],
40 | ],
41 | 'pack-5000' => [
42 | 'length' => 1000,
43 | 'width' => 990,
44 | 'height' => 990,
45 | 'weight' => 5000,
46 | 'price' => [
47 | self::ZONE_TOM => 4960,
48 | ],
49 | ],
50 | 'pack-10000' => [
51 | 'length' => 1000,
52 | 'width' => 990,
53 | 'height' => 990,
54 | 'weight' => 10000,
55 | 'price' => [
56 | self::ZONE_TOM => 9660,
57 | ],
58 | ],
59 | 'pack-30000' => [
60 | 'length' => 1000,
61 | 'width' => 990,
62 | 'height' => 990,
63 | 'weight' => 30000,
64 | 'price' => [
65 | self::ZONE_TOM => 25000,
66 | ],
67 | ],
68 | ];
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/rates/colissimo/TomEconomiqueOutremer.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 500,
19 | 'price' => [
20 | self::ZONE_TOM => 1080,
21 | ],
22 | ],
23 | 'pack-1000' => [
24 | 'length' => 1000,
25 | 'width' => 500,
26 | 'height' => 500,
27 | 'weight' => 1000,
28 | 'price' => [
29 | self::ZONE_TOM => 1630,
30 | ],
31 | ],
32 | 'pack-2000' => [
33 | 'length' => 1000,
34 | 'width' => 500,
35 | 'height' => 500,
36 | 'weight' => 2000,
37 | 'price' => [
38 | self::ZONE_TOM => 2900,
39 | ],
40 | ],
41 | 'pack-5000' => [
42 | 'length' => 1000,
43 | 'width' => 500,
44 | 'height' => 500,
45 | 'weight' => 5000,
46 | 'price' => [
47 | self::ZONE_TOM => 4800,
48 | ],
49 | ],
50 | 'pack-10000' => [
51 | 'length' => 1000,
52 | 'width' => 500,
53 | 'height' => 500,
54 | 'weight' => 10000,
55 | 'price' => [
56 | self::ZONE_TOM => 9450,
57 | ],
58 | ],
59 | 'pack-30000' => [
60 | 'length' => 1000,
61 | 'width' => 500,
62 | 'height' => 500,
63 | 'weight' => 30000,
64 | 'price' => [
65 | self::ZONE_TOM => 24800,
66 | ],
67 | ],
68 | ];
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/rates/colissimo/Europe.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 990,
17 | 'height' => 990,
18 | 'weight' => 500,
19 | 'price' => [
20 | self::ZONE_INTERNATIONAL_A => 1230,
21 | ],
22 | ],
23 | 'pack-1000' => [
24 | 'length' => 1000,
25 | 'width' => 990,
26 | 'height' => 990,
27 | 'weight' => 1000,
28 | 'price' => [
29 | self::ZONE_INTERNATIONAL_A => 1505,
30 | ],
31 | ],
32 | 'pack-2000' => [
33 | 'length' => 1000,
34 | 'width' => 990,
35 | 'height' => 990,
36 | 'weight' => 2000,
37 | 'price' => [
38 | self::ZONE_INTERNATIONAL_A => 1680,
39 | ],
40 | ],
41 | 'pack-5000' => [
42 | 'length' => 1000,
43 | 'width' => 990,
44 | 'height' => 990,
45 | 'weight' => 5000,
46 | 'price' => [
47 | self::ZONE_INTERNATIONAL_A => 2150,
48 | ],
49 | ],
50 | 'pack-10000' => [
51 | 'length' => 1000,
52 | 'width' => 990,
53 | 'height' => 990,
54 | 'weight' => 10000,
55 | 'price' => [
56 | self::ZONE_INTERNATIONAL_A => 3550,
57 | ],
58 | ],
59 | 'pack-30000' => [
60 | 'length' => 1000,
61 | 'width' => 990,
62 | 'height' => 990,
63 | 'weight' => 30000,
64 | 'price' => [
65 | self::ZONE_INTERNATIONAL_A => 5900,
66 | ],
67 | ],
68 | ];
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/rates/colissimo/DomEconomiqueOutremer.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 500,
19 | 'price' => [
20 | self::ZONE_DOM => 880,
21 | ],
22 | ],
23 | 'pack-1000' => [
24 | 'length' => 1000,
25 | 'width' => 500,
26 | 'height' => 500,
27 | 'weight' => 1000,
28 | 'price' => [
29 | self::ZONE_DOM => 1150,
30 | ],
31 | ],
32 | 'pack-2000' => [
33 | 'length' => 1000,
34 | 'width' => 500,
35 | 'height' => 500,
36 | 'weight' => 2000,
37 | 'price' => [
38 | self::ZONE_DOM => 1400,
39 | ],
40 | ],
41 | 'pack-5000' => [
42 | 'length' => 1000,
43 | 'width' => 500,
44 | 'height' => 500,
45 | 'weight' => 5000,
46 | 'price' => [
47 | self::ZONE_DOM => 2500,
48 | ],
49 | ],
50 | 'pack-10000' => [
51 | 'length' => 1000,
52 | 'width' => 500,
53 | 'height' => 500,
54 | 'weight' => 10000,
55 | 'price' => [
56 | self::ZONE_DOM => 3500,
57 | ],
58 | ],
59 | 'pack-20000' => [
60 | 'length' => 1000,
61 | 'width' => 500,
62 | 'height' => 500,
63 | 'weight' => 30000,
64 | 'price' => [
65 | self::ZONE_DOM => 6500,
66 | ],
67 | ],
68 | 'pack-30000' => [
69 | 'length' => 1000,
70 | 'width' => 500,
71 | 'height' => 500,
72 | 'weight' => 30000,
73 | 'price' => [
74 | self::ZONE_DOM => 9000,
75 | ],
76 | ],
77 | ];
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/rates/colissimo/International.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 990,
17 | 'height' => 990,
18 | 'weight' => 500,
19 | 'price' => [
20 | self::ZONE_INTERNATIONAL_B => 1640,
21 | self::ZONE_INTERNATIONAL_C => 2400,
22 | ],
23 | ],
24 | 'pack-1000' => [
25 | 'length' => 1000,
26 | 'width' => 990,
27 | 'height' => 990,
28 | 'weight' => 1000,
29 | 'price' => [
30 | self::ZONE_INTERNATIONAL_B => 1960,
31 | self::ZONE_INTERNATIONAL_C => 2670,
32 | ],
33 | ],
34 | 'pack-2000' => [
35 | 'length' => 1000,
36 | 'width' => 990,
37 | 'height' => 990,
38 | 'weight' => 2000,
39 | 'price' => [
40 | self::ZONE_INTERNATIONAL_B => 2140,
41 | self::ZONE_INTERNATIONAL_C => 3670,
42 | ],
43 | ],
44 | 'pack-5000' => [
45 | 'length' => 1000,
46 | 'width' => 990,
47 | 'height' => 990,
48 | 'weight' => 5000,
49 | 'price' => [
50 | self::ZONE_INTERNATIONAL_B => 2750,
51 | self::ZONE_INTERNATIONAL_C => 5370,
52 | ],
53 | ],
54 | 'pack-10000' => [
55 | 'length' => 1000,
56 | 'width' => 990,
57 | 'height' => 990,
58 | 'weight' => 10000,
59 | 'price' => [
60 | self::ZONE_INTERNATIONAL_B => 4550,
61 | self::ZONE_INTERNATIONAL_C => 10150,
62 | ],
63 | ],
64 | 'pack-20000' => [
65 | 'length' => 1000,
66 | 'width' => 990,
67 | 'height' => 990,
68 | 'weight' => 10000,
69 | 'price' => [
70 | self::ZONE_INTERNATIONAL_B => 7100,
71 | self::ZONE_INTERNATIONAL_C => 16200,
72 | ],
73 | ],
74 | ];
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/rates/colissimo/EmballageInternational.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 500,
16 | 'width' => 250,
17 | 'height' => 250,
18 | 'weight' => 500,
19 | 'price' => [
20 | self::ZONE_INTERNATIONAL_B => 1620,
21 | self::ZONE_INTERNATIONAL_C => 2370,
22 | ],
23 | ],
24 | 'pack-1000' => [
25 | 'length' => 500,
26 | 'width' => 250,
27 | 'height' => 250,
28 | 'weight' => 1000,
29 | 'price' => [
30 | self::ZONE_INTERNATIONAL_B => 1935,
31 | self::ZONE_INTERNATIONAL_C => 2630,
32 | ],
33 | ],
34 | 'pack-2000' => [
35 | 'length' => 500,
36 | 'width' => 250,
37 | 'height' => 250,
38 | 'weight' => 2000,
39 | 'price' => [
40 | self::ZONE_INTERNATIONAL_B => 2105,
41 | self::ZONE_INTERNATIONAL_C => 3610,
42 | ],
43 | ],
44 | 'pack-5000' => [
45 | 'length' => 500,
46 | 'width' => 250,
47 | 'height' => 250,
48 | 'weight' => 5000,
49 | 'price' => [
50 | self::ZONE_INTERNATIONAL_B => 2700,
51 | self::ZONE_INTERNATIONAL_C => 5300,
52 | ],
53 | ],
54 | 'pack-10000' => [
55 | 'length' => 500,
56 | 'width' => 250,
57 | 'height' => 250,
58 | 'weight' => 10000,
59 | 'price' => [
60 | self::ZONE_INTERNATIONAL_B => 4500,
61 | self::ZONE_INTERNATIONAL_C => 10000,
62 | ],
63 | ],
64 | 'pack-20000' => [
65 | 'length' => 500,
66 | 'width' => 250,
67 | 'height' => 250,
68 | 'weight' => 10000,
69 | 'price' => [
70 | self::ZONE_INTERNATIONAL_B => 7000,
71 | self::ZONE_INTERNATIONAL_C => 16000,
72 | ],
73 | ],
74 | ];
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/rates/colissimo/FrFrance.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 990,
17 | 'height' => 990,
18 | 'weight' => 250,
19 | 'price' => [
20 | self::ZONE_FR => 495,
21 | ],
22 | ],
23 | 'pack-500' => [
24 | 'length' => 1000,
25 | 'width' => 990,
26 | 'height' => 990,
27 | 'weight' => 500,
28 | 'price' => [
29 | self::ZONE_FR => 615,
30 | ],
31 | ],
32 | 'pack-750' => [
33 | 'length' => 1000,
34 | 'width' => 990,
35 | 'height' => 990,
36 | 'weight' => 750,
37 | 'price' => [
38 | self::ZONE_FR => 700,
39 | ],
40 | ],
41 | 'pack-1000' => [
42 | 'length' => 1000,
43 | 'width' => 990,
44 | 'height' => 990,
45 | 'weight' => 1000,
46 | 'price' => [
47 | self::ZONE_FR => 765,
48 | ],
49 | ],
50 | 'pack-2000' => [
51 | 'length' => 1000,
52 | 'width' => 990,
53 | 'height' => 990,
54 | 'weight' => 2000,
55 | 'price' => [
56 | self::ZONE_FR => 865,
57 | ],
58 | ],
59 | 'pack-5000' => [
60 | 'length' => 1000,
61 | 'width' => 990,
62 | 'height' => 990,
63 | 'weight' => 5000,
64 | 'price' => [
65 | self::ZONE_FR => 1315,
66 | ],
67 | ],
68 | 'pack-10000' => [
69 | 'length' => 1000,
70 | 'width' => 990,
71 | 'height' => 990,
72 | 'weight' => 10000,
73 | 'price' => [
74 | self::ZONE_FR => 1920,
75 | ],
76 | ],
77 | 'pack-30000' => [
78 | 'length' => 1000,
79 | 'width' => 990,
80 | 'height' => 990,
81 | 'weight' => 30000,
82 | 'price' => [
83 | self::ZONE_FR => 2730,
84 | ],
85 | ],
86 | ];
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/rates/royalmail/online/InternationalStandard.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LETTER => [
22 | 100 => [280, 280, 280, 280, 280, 280],
23 | ],
24 | self::LARGE_LETTER => [
25 | 100 => [325, 325, 325, 420, 420, 420],
26 | 250 => [475, 475, 475, 635, 755, 650],
27 | 500 => [585, 585, 585, 885, 1090, 920],
28 | 750 => [695, 695, 695, 1180, 1500, 1230],
29 | ],
30 | self::PACKET => [
31 | 100 => [555, 605, 645, 745, 850, 820],
32 | 250 => [555, 605, 645, 900, 960, 985],
33 | 500 => [735, 815, 890, 1310, 1480, 1580],
34 | 750 => [860, 950, 1060, 1615, 1820, 1870],
35 | 1000 => [990, 1075, 1230, 1915, 2180, 2260],
36 | 1250 => [1035, 1230, 1360, 2135, 2510, 2615],
37 | 1500 => [1035, 1230, 1570, 2330, 2850, 2895],
38 | 2000 => [1200, 1400, 1825, 2450, 3035, 3025],
39 | ],
40 | ],
41 | '2025' => [
42 | self::LETTER => [
43 | 100 => [320, 320, 320, 320, 320, 320],
44 | ],
45 | self::LARGE_LETTER => [
46 | 100 => [340, 340, 340, 420, 420, 420],
47 | 250 => [505, 505, 505, 695, 825, 720],
48 | 500 => [645, 645, 645, 1000, 1230, 1070],
49 | 750 => [870, 870, 870, 1510, 1710, 1620],
50 | ],
51 | self::PACKET => [
52 | 100 => [580, 630, 675, 780, 890, 1175],
53 | 250 => [580, 630, 675, 940, 1005, 1175],
54 | 500 => [770, 850, 930, 1370, 1545, 1685],
55 | 750 => [900, 995, 1110, 1690, 1900, 1990],
56 | 1000 => [1035, 1125, 1285, 2000, 2280, 2285],
57 | 1250 => [1080, 1285, 1420, 2230, 2625, 2675],
58 | 1500 => [1080, 1285, 1640, 2435, 2980, 3040],
59 | 2000 => [1255, 1465, 1905, 2560, 3170, 3175],
60 | ],
61 | ],
62 | ];
63 |
64 | return self::getInternationalBoxPricing($bands, $countryCode, 20);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/rates/postnl/InternationalBrief.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 380,
16 | 'width' => 265,
17 | 'height' => 32,
18 | 'weight' => 20,
19 | 'price' => [
20 | self::ZONE_NL => false,
21 | self::ZONE_EU1 => 140,
22 | self::ZONE_EU2 => 140,
23 | self::ZONE_EU3 => false,
24 | self::ZONE_WORLD => 140,
25 | ],
26 | ],
27 | 'brief-50g' => [
28 | 'length' => 380,
29 | 'width' => 265,
30 | 'height' => 32,
31 | 'weight' => 50,
32 | 'price' => [
33 | self::ZONE_NL => false,
34 | self::ZONE_EU1 => 280,
35 | self::ZONE_EU2 => 280,
36 | self::ZONE_EU3 => false,
37 | self::ZONE_WORLD => 280,
38 | ],
39 | ],
40 | 'brief-100g' => [
41 | 'length' => 380,
42 | 'width' => 265,
43 | 'height' => 32,
44 | 'weight' => 100,
45 | 'price' => [
46 | self::ZONE_NL => false,
47 | self::ZONE_EU1 => 420,
48 | self::ZONE_EU2 => 420,
49 | self::ZONE_EU3 => false,
50 | self::ZONE_WORLD => 420,
51 | ],
52 | ],
53 | 'brief-250g' => [
54 | 'length' => 380,
55 | 'width' => 265,
56 | 'height' => 32,
57 | 'weight' => 250,
58 | 'price' => [
59 | self::ZONE_NL => false,
60 | self::ZONE_EU1 => 840,
61 | self::ZONE_EU2 => 840,
62 | self::ZONE_EU3 => false,
63 | self::ZONE_WORLD => 840,
64 | ],
65 | ],
66 | 'brief-2000g' => [
67 | 'length' => 380,
68 | 'width' => 265,
69 | 'height' => 32,
70 | 'weight' => 2000,
71 | 'price' => [
72 | self::ZONE_NL => false,
73 | self::ZONE_EU1 => 980,
74 | self::ZONE_EU2 => 1260,
75 | self::ZONE_EU3 => false,
76 | self::ZONE_WORLD => 1540,
77 | ],
78 | ],
79 | ];
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/InternationalStandard.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LETTER => [
22 | 100 => [280, 280, 280, 280, 280, 280],
23 | ],
24 | self::LARGE_LETTER => [
25 | 100 => [325, 325, 325, 420, 420, 420],
26 | 250 => [545, 545, 545, 705, 825, 720],
27 | 500 => [655, 655, 655, 955, 1160, 990],
28 | 750 => [765, 765, 765, 1250, 1570, 1300],
29 | ],
30 | self::PACKET => [
31 | 100 => [830, 845, 925, 1100, 1245, 1250],
32 | 250 => [830, 845, 925, 1250, 1350, 1425],
33 | 500 => [1040, 1075, 1140, 1700, 1870, 2045],
34 | 750 => [1170, 1210, 1295, 2000, 2210, 2350],
35 | 1000 => [1305, 1335, 1445, 2310, 2570, 2750],
36 | 1250 => [1415, 1470, 1575, 2575, 2900, 3130],
37 | 1500 => [1415, 1470, 1700, 2820, 3240, 3430],
38 | 2000 => [1580, 1635, 1850, 2955, 3425, 3570],
39 | ],
40 | ],
41 | '2025' => [
42 | self::LETTER => [
43 | 100 => [320, 320, 320, 320, 320, 320],
44 | ],
45 | self::LARGE_LETTER => [
46 | 100 => [350, 350, 350, 430, 430, 430],
47 | 250 => [580, 580, 580, 770, 900, 800],
48 | 500 => [720, 720, 720, 1080, 1310, 1150],
49 | 750 => [955, 955, 955, 1600, 2010, 1710],
50 | ],
51 | self::PACKET => [
52 | 100 => [895, 970, 1065, 1305, 1455, 1695],
53 | 250 => [895, 970, 1065, 1405, 1520, 1695],
54 | 500 => [1125, 1235, 1310, 1930, 2120, 2385],
55 | 750 => [1240, 1390, 1490, 2270, 2510, 2695],
56 | 1000 => [1355, 1535, 1660, 2620, 2915, 3005],
57 | 1250 => [1425, 1690, 1810, 2925, 3290, 3415],
58 | 1500 => [1425, 1690, 1955, 3200, 3675, 3415],
59 | 2000 => [1625, 1880, 2125, 3355, 3885, 3570],
60 | ],
61 | ],
62 | ];
63 |
64 | return self::getInternationalBoxPricing($bands, $countryCode, 20);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/rates/postnl/InternationalPakket.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 2000,
19 | 'price' => [
20 | self::ZONE_NL => false,
21 | self::ZONE_EU1 => 1300,
22 | self::ZONE_EU2 => 1850,
23 | self::ZONE_EU3 => false,
24 | self::ZONE_WORLD => 2430,
25 | ],
26 | ],
27 | 'pakket-5kg' => [
28 | 'length' => 1000,
29 | 'width' => 500,
30 | 'height' => 500,
31 | 'weight' => 5000,
32 | 'price' => [
33 | self::ZONE_NL => false,
34 | self::ZONE_EU1 => 1950,
35 | self::ZONE_EU2 => 2500,
36 | self::ZONE_EU3 => false,
37 | self::ZONE_WORLD => 3430,
38 | ],
39 | ],
40 | 'pakket-10kg' => [
41 | 'length' => 1000,
42 | 'width' => 500,
43 | 'height' => 500,
44 | 'weight' => 10000,
45 | 'price' => [
46 | self::ZONE_NL => false,
47 | self::ZONE_EU1 => 2500,
48 | self::ZONE_EU2 => 3100,
49 | self::ZONE_EU3 => false,
50 | self::ZONE_WORLD => 5830,
51 | ],
52 | ],
53 | 'pakket-20kg' => [
54 | 'length' => 1000,
55 | 'width' => 500,
56 | 'height' => 500,
57 | 'weight' => 20000,
58 | 'price' => [
59 | self::ZONE_NL => false,
60 | self::ZONE_EU1 => 3400,
61 | self::ZONE_EU2 => 4000,
62 | self::ZONE_EU3 => false,
63 | self::ZONE_WORLD => 10530,
64 | ],
65 | ],
66 | 'pakket-30kg' => [
67 | 'length' => 1000,
68 | 'width' => 500,
69 | 'height' => 500,
70 | 'weight' => 30000,
71 | 'price' => [
72 | self::ZONE_NL => false,
73 | self::ZONE_EU1 => 4500,
74 | self::ZONE_EU2 => 5500,
75 | self::ZONE_EU3 => false,
76 | self::ZONE_WORLD => false,
77 | ],
78 | ],
79 | ];
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/models/Label.php:
--------------------------------------------------------------------------------
1 | carrier;
26 | }
27 |
28 | public function setCarrier(CarrierInterface $carrier): Label
29 | {
30 | $this->carrier = $carrier;
31 | return $this;
32 | }
33 |
34 | public function getRate(): Rate
35 | {
36 | return $this->rate;
37 | }
38 |
39 | public function setRate(Rate $rate): Label
40 | {
41 | $this->rate = $rate;
42 | return $this;
43 | }
44 |
45 | public function getTrackingNumber(): string
46 | {
47 | return (string)$this->trackingNumber;
48 | }
49 |
50 | public function setTrackingNumber(string $trackingNumber): Label
51 | {
52 | $this->trackingNumber = $trackingNumber;
53 | return $this;
54 | }
55 |
56 | public function getLabelId(): string
57 | {
58 | return (string)$this->labelId;
59 | }
60 |
61 | public function setLabelId(string $labelId): Label
62 | {
63 | $this->labelId = $labelId;
64 | return $this;
65 | }
66 |
67 | public function getLabelData(): string
68 | {
69 | return (string)$this->labelData;
70 | }
71 |
72 | public function setLabelData(string $labelData): Label
73 | {
74 | $this->labelData = $labelData;
75 | return $this;
76 | }
77 |
78 | public function getLabelMime(): string
79 | {
80 | return (string)$this->labelMime;
81 | }
82 |
83 | public function setLabelMime(string $labelMime): Label
84 | {
85 | $this->labelMime = $labelMime;
86 | return $this;
87 | }
88 |
89 | public function getResponse(): array
90 | {
91 | return $this->response;
92 | }
93 |
94 | public function setResponse(array $response): Label
95 | {
96 | $this->response = $response;
97 | return $this;
98 | }
99 |
100 | public function toArray(): array
101 | {
102 | // Remove debug/info attributes
103 | $vars = parent::toArray();
104 | unset($vars['carrier'], $vars['response']);
105 |
106 | return $vars;
107 | }
108 |
109 | }
--------------------------------------------------------------------------------
/src/rates/postnl/InternationalAangetekend.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 2000,
19 | 'price' => [
20 | self::ZONE_NL => false,
21 | self::ZONE_EU1 => 1550,
22 | self::ZONE_EU2 => 2100,
23 | self::ZONE_EU3 => false,
24 | self::ZONE_WORLD => 2680,
25 | ],
26 | ],
27 | 'pakket-5kg' => [
28 | 'length' => 1000,
29 | 'width' => 500,
30 | 'height' => 500,
31 | 'weight' => 5000,
32 | 'price' => [
33 | self::ZONE_NL => false,
34 | self::ZONE_EU1 => 2200,
35 | self::ZONE_EU2 => 2750,
36 | self::ZONE_EU3 => false,
37 | self::ZONE_WORLD => 3680,
38 | ],
39 | ],
40 | 'pakket-10kg' => [
41 | 'length' => 1000,
42 | 'width' => 500,
43 | 'height' => 500,
44 | 'weight' => 10000,
45 | 'price' => [
46 | self::ZONE_NL => false,
47 | self::ZONE_EU1 => 2750,
48 | self::ZONE_EU2 => 3350,
49 | self::ZONE_EU3 => false,
50 | self::ZONE_WORLD => 6080,
51 | ],
52 | ],
53 | 'pakket-20kg' => [
54 | 'length' => 1000,
55 | 'width' => 500,
56 | 'height' => 500,
57 | 'weight' => 20000,
58 | 'price' => [
59 | self::ZONE_NL => false,
60 | self::ZONE_EU1 => 3650,
61 | self::ZONE_EU2 => 4250,
62 | self::ZONE_EU3 => false,
63 | self::ZONE_WORLD => 10780,
64 | ],
65 | ],
66 | 'pakket-30kg' => [
67 | 'length' => 1000,
68 | 'width' => 500,
69 | 'height' => 500,
70 | 'weight' => 30000,
71 | 'price' => [
72 | self::ZONE_NL => false,
73 | self::ZONE_EU1 => 4750,
74 | self::ZONE_EU2 => 5750,
75 | self::ZONE_EU3 => false,
76 | self::ZONE_WORLD => false,
77 | ],
78 | ],
79 | ];
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/rates/postnl/InternationalVerzekerservice.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 1000,
16 | 'width' => 500,
17 | 'height' => 500,
18 | 'weight' => 2000,
19 | 'price' => [
20 | self::ZONE_NL => false,
21 | self::ZONE_EU1 => 2300,
22 | self::ZONE_EU2 => 2850,
23 | self::ZONE_EU3 => false,
24 | self::ZONE_WORLD => 3430,
25 | ],
26 | ],
27 | 'pakket-5kg' => [
28 | 'length' => 1000,
29 | 'width' => 500,
30 | 'height' => 500,
31 | 'weight' => 5000,
32 | 'price' => [
33 | self::ZONE_NL => false,
34 | self::ZONE_EU1 => 2950,
35 | self::ZONE_EU2 => 3500,
36 | self::ZONE_EU3 => false,
37 | self::ZONE_WORLD => 4430,
38 | ],
39 | ],
40 | 'pakket-10kg' => [
41 | 'length' => 1000,
42 | 'width' => 500,
43 | 'height' => 500,
44 | 'weight' => 10000,
45 | 'price' => [
46 | self::ZONE_NL => false,
47 | self::ZONE_EU1 => 3500,
48 | self::ZONE_EU2 => 4100,
49 | self::ZONE_EU3 => false,
50 | self::ZONE_WORLD => 6830,
51 | ],
52 | ],
53 | 'pakket-20kg' => [
54 | 'length' => 1000,
55 | 'width' => 500,
56 | 'height' => 500,
57 | 'weight' => 20000,
58 | 'price' => [
59 | self::ZONE_NL => false,
60 | self::ZONE_EU1 => 4400,
61 | self::ZONE_EU2 => 5000,
62 | self::ZONE_EU3 => false,
63 | self::ZONE_WORLD => 11530,
64 | ],
65 | ],
66 | 'pakket-30kg' => [
67 | 'length' => 1000,
68 | 'width' => 500,
69 | 'height' => 500,
70 | 'weight' => 30000,
71 | 'price' => [
72 | self::ZONE_NL => false,
73 | self::ZONE_EU1 => 5500,
74 | self::ZONE_EU2 => 6500,
75 | self::ZONE_EU3 => false,
76 | self::ZONE_WORLD => false,
77 | ],
78 | ],
79 | ];
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/InternationalTrackedSigned.php:
--------------------------------------------------------------------------------
1 | [
27 | self::LETTER => [
28 | 100 => [815, 815, 815, 815, 815, 815],
29 | ],
30 | self::LARGE_LETTER => [
31 | 100 => [965, 965, 965, 1065, 1080, 1075],
32 | 250 => [1090, 1090, 1090, 1230, 1350, 1250],
33 | 500 => [1170, 1170, 1170, 1430, 1630, 1465],
34 | 750 => [1215, 1215, 1215, 1635, 1935, 1685],
35 | ],
36 | self::PACKET => [
37 | 100 => [1375, 1390, 1530, 1770, 1900, 1845],
38 | 250 => [1375, 1390, 1530, 1810, 1935, 2020],
39 | 500 => [1520, 1560, 1700, 2240, 2430, 2615],
40 | 750 => [1635, 1670, 1825, 2500, 2740, 2835],
41 | 1000 => [1740, 1770, 1955, 2795, 3085, 3235],
42 | 1250 => [1800, 1805, 2025, 3015, 3355, 3615],
43 | 1500 => [1810, 1830, 2090, 3170, 3630, 3915],
44 | 2000 => [1825, 1880, 2140, 3220, 3745, 3970],
45 | ],
46 | self::PRINTED_PAPERS => [
47 | 100 => [1375, 1390, 1530, 1770, 1900, 1845],
48 | 250 => [1375, 1390, 1530, 1810, 1935, 2020],
49 | 500 => [1520, 1560, 1700, 2240, 2430, 2615],
50 | 750 => [1635, 1670, 1825, 2500, 2740, 2835],
51 | 1000 => [1740, 1770, 1955, 2795, 3085, 3235],
52 | 1250 => [1800, 1805, 2025, 3015, 3355, 3615],
53 | 1500 => [1810, 1830, 2090, 3170, 3630, 3915],
54 | 2000 => [1825, 1880, 2140, 3220, 3745, 3970],
55 | ],
56 | ],
57 | ];
58 |
59 | return self::getInternationalBoxPricing($bands, $countryCode);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/models/PackageItem.php:
--------------------------------------------------------------------------------
1 | description = $description;
26 | $this->width = $width;
27 | $this->length = $length;
28 | $this->depth = $depth;
29 | $this->weight = $weight;
30 | $this->keepFlat = false;
31 | }
32 |
33 | public function getDescription(): string
34 | {
35 | return (string)$this->description;
36 | }
37 |
38 | public function setDescription($value): void
39 | {
40 | $this->description = $value;
41 | }
42 |
43 | public function getWidth(): int
44 | {
45 | return (int)$this->width;
46 | }
47 |
48 | public function setWidth($value): void
49 | {
50 | $this->width = $value;
51 | }
52 |
53 | public function getLength(): int
54 | {
55 | return (int)$this->length;
56 | }
57 |
58 | public function setLength($value): void
59 | {
60 | $this->length = $value;
61 | }
62 |
63 | public function getDepth(): int
64 | {
65 | return (int)$this->depth;
66 | }
67 |
68 | public function setDepth($value): void
69 | {
70 | $this->depth = $value;
71 | }
72 |
73 | public function getWeight(): int
74 | {
75 | return (int)$this->weight;
76 | }
77 |
78 | public function setWeight($value): void
79 | {
80 | $this->weight = $value;
81 | }
82 |
83 | public function getKeepFlat(): bool
84 | {
85 | return $this->keepFlat;
86 | }
87 |
88 | public function setKeepFlat($value): void
89 | {
90 | $this->keepFlat = $value;
91 | }
92 |
93 | public function getItemValue(): float
94 | {
95 | return (float)$this->itemValue;
96 | }
97 |
98 | public function setItemValue($value): void
99 | {
100 | $this->itemValue = $value;
101 | }
102 |
103 | public function getAllowedRotation(): \DVDoug\BoxPacker\Rotation
104 | {
105 | if ($this->keepFlat) {
106 | return \DVDoug\BoxPacker\Rotation::KeepFlat;
107 | }
108 | return \DVDoug\BoxPacker\Rotation::BestFit;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/carriers/PostNL.php:
--------------------------------------------------------------------------------
1 | 'Brief',
41 | 'brievenbuspakje' => 'Brievenbuspakje',
42 | 'pakket-no-track-and-trace' => 'Pakket no Track & Trace',
43 | 'pakket' => 'Pakket',
44 | 'aangetekend' => 'Aangetekend',
45 | 'verzekerservice' => 'Verzekerservice',
46 | 'betaalservice' => 'Betaalservice',
47 | ];
48 | }
49 |
50 | public static function supportsTrackingStatus(): bool
51 | {
52 | return false;
53 | }
54 |
55 | public static function supportsLabels(): bool
56 | {
57 | return false;
58 | }
59 |
60 |
61 | // Public Methods
62 | // =========================================================================
63 |
64 | public function getRates(Shipment $shipment): ?RateResponse
65 | {
66 | $rates = [];
67 |
68 | foreach (self::getServiceCodes() as $serviceCode => $serviceName) {
69 | if ($rate = PostNLRates::getRate($serviceCode, $this, $shipment)) {
70 | $rates[] = $rate;
71 | }
72 | }
73 |
74 | return new RateResponse([
75 | 'rates' => $rates,
76 | ]);
77 | }
78 |
79 | /**
80 | * @throws Exception
81 | */
82 | public function getTrackingStatus(array $trackingNumbers, array $options = []): ?TrackingResponse
83 | {
84 | throw new Exception('Not implemented.');
85 | }
86 |
87 | /**
88 | * @throws Exception
89 | */
90 | public function getLabels(Shipment $shipment, Rate $rate, array $options = []): ?LabelResponse
91 | {
92 | throw new Exception('Not implemented.');
93 | }
94 |
95 | public function getHttpClient(): HttpClient
96 | {
97 | return new HttpClient();
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/models/Model.php:
--------------------------------------------------------------------------------
1 | $value) {
22 | $this->__set($name, $value);
23 | }
24 | }
25 |
26 | $this->init();
27 | }
28 |
29 | public function __get($name)
30 | {
31 | $getter = 'get' . ucfirst($name);
32 |
33 | if (method_exists($this, $getter)) {
34 | return $this->$getter();
35 | }
36 | }
37 |
38 | public function __set($name, $value)
39 | {
40 | $setter = 'set' . ucfirst($name);
41 |
42 | if (method_exists($this, $setter)) {
43 | $this->$setter($value);
44 | }
45 | }
46 |
47 | public function __isset($name)
48 | {
49 | $getter = 'get' . ucfirst($name);
50 |
51 | if (method_exists($this, $getter)) {
52 | return $this->$getter() !== null;
53 | }
54 |
55 | return false;
56 | }
57 |
58 | public function __unset($name)
59 | {
60 | $setter = 'set' . ucfirst($name);
61 |
62 | if (method_exists($this, $setter)) {
63 | $this->$setter(null);
64 | }
65 | }
66 |
67 | public function __debugInfo()
68 | {
69 | return $this->toArray();
70 | }
71 |
72 | public function __sleep(): array
73 | {
74 | // Ensure that any `serialize()` calls respect `toArray()`.
75 | return array_keys($this->toArray());
76 | }
77 |
78 | public function init(): void
79 | {
80 | $this->events = new EventDispatcher();
81 | }
82 |
83 | public function jsonSerialize()
84 | {
85 | return $this->toArray();
86 | }
87 |
88 | public function displayName(): string
89 | {
90 | $classNameParts = explode('\\', static::class);
91 | return array_pop($classNameParts);
92 | }
93 |
94 | public function on(string $eventName, callable|array $listener, int $priority = 0): void
95 | {
96 | $this->events->addListener($eventName, $listener, $priority);
97 | }
98 |
99 | public function trigger(string $eventName, object $event): void
100 | {
101 | $this->events->dispatch($event, $eventName);
102 | }
103 |
104 | public function toArray(): array
105 | {
106 | $vars = get_object_vars($this);
107 | unset($vars['events']);
108 |
109 | return $vars;
110 | }
111 | }
--------------------------------------------------------------------------------
/src/carriers/Colissimo.php:
--------------------------------------------------------------------------------
1 | 'France',
41 | 'emballage-france' => 'Emballage France',
42 | 'outremer' => 'Outre-Mer',
43 | 'europe' => 'Europe',
44 | 'economique-outremer' => 'Economique Outre-Mer',
45 | 'international' => 'International',
46 | 'emballage-international' => 'Emballage International',
47 | ];
48 | }
49 |
50 | public static function supportsTrackingStatus(): bool
51 | {
52 | return false;
53 | }
54 |
55 | public static function supportsLabels(): bool
56 | {
57 | return false;
58 | }
59 |
60 |
61 | // Public Methods
62 | // =========================================================================
63 |
64 | public function getRates(Shipment $shipment): ?RateResponse
65 | {
66 | $rates = [];
67 |
68 | foreach (self::getServiceCodes() as $serviceCode => $serviceName) {
69 | if ($rate = ColissimoRates::getRate($serviceCode, $this, $shipment)) {
70 | $rates[] = $rate;
71 | }
72 | }
73 |
74 | return new RateResponse([
75 | 'rates' => $rates,
76 | ]);
77 | }
78 |
79 | /**
80 | * @throws Exception
81 | */
82 | public function getTrackingStatus(array $trackingNumbers, array $options = []): ?TrackingResponse
83 | {
84 | throw new Exception('Not implemented.');
85 | }
86 |
87 | /**
88 | * @throws Exception
89 | */
90 | public function getLabels(Shipment $shipment, Rate $rate, array $options = []): ?LabelResponse
91 | {
92 | throw new Exception('Not implemented.');
93 | }
94 |
95 | public function getHttpClient(): HttpClient
96 | {
97 | return new HttpClient();
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/ParcelforceIrelandexpress.php:
--------------------------------------------------------------------------------
1 | [
21 | '5' => [
22 | 500 => 2754,
23 | 1000 => 2754,
24 | 1500 => 2754,
25 | 2000 => 2754,
26 | 2500 => 2754,
27 | 3000 => 2754,
28 | 3500 => 2754,
29 | 4000 => 2754,
30 | 4500 => 2754,
31 | 5000 => 2754,
32 | 5500 => 2886,
33 | 6000 => 3018,
34 | 6500 => 3150,
35 | 7000 => 3282,
36 | 7500 => 3414,
37 | 8000 => 3546,
38 | 8500 => 3678,
39 | 9000 => 3810,
40 | 9500 => 3942,
41 | 10000 => 4074,
42 | 10500 => 4158,
43 | 11000 => 4242,
44 | 11500 => 4326,
45 | 12000 => 4410,
46 | 12500 => 4494,
47 | 13000 => 4578,
48 | 13500 => 4662,
49 | 14000 => 4746,
50 | 14500 => 4830,
51 | 15000 => 4914,
52 | 15500 => 5022,
53 | 16000 => 5130,
54 | 16500 => 5238,
55 | 17000 => 5346,
56 | 17500 => 5454,
57 | 18000 => 5562,
58 | 18500 => 5670,
59 | 19000 => 5778,
60 | 19500 => 5886,
61 | 20000 => 5994,
62 | 20500 => 6102,
63 | 21000 => 6210,
64 | 21500 => 6318,
65 | 22000 => 6426,
66 | 22500 => 6534,
67 | 23000 => 6642,
68 | 23500 => 6750,
69 | 24000 => 6858,
70 | 24500 => 6966,
71 | 25000 => 7074,
72 | 25500 => 7182,
73 | 26000 => 7290,
74 | 26500 => 7398,
75 | 27000 => 7506,
76 | 27500 => 7614,
77 | 28000 => 7722,
78 | 28500 => 7830,
79 | 29000 => 7938,
80 | 29500 => 8046,
81 | 30000 => 8154,
82 | ],
83 | ],
84 | ];
85 |
86 | return self::getParcelforceBoxPricing($bands, $countryCode, [
87 | 'maximumInclusiveCompensation' => 200,
88 | 'maximumTotalCover' => 2500,
89 | ]);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/SpecialDelivery9am.php:
--------------------------------------------------------------------------------
1 | [
31 | 'packet-50' => [
32 | 100 => 3195,
33 | 500 => 3695,
34 | 1000 => 4195,
35 | 2000 => 5295,
36 | ],
37 | 'packet-1000' => [
38 | 100 => 3895,
39 | 500 => 4395,
40 | 1000 => 4895,
41 | 2000 => 5995,
42 | ],
43 | 'packet-2500' => [
44 | 100 => 4695,
45 | 500 => 5195,
46 | 1000 => 5695,
47 | 2000 => 6795,
48 | ],
49 | ],
50 | '2025' => [
51 | 'packet-50' => [
52 | 100 => 3895,
53 | 500 => 4395,
54 | 1000 => 4895,
55 | 2000 => 6095,
56 | ],
57 | 'packet-1000' => [
58 | 100 => 4595,
59 | 500 => 5095,
60 | 1000 => 5595,
61 | 2000 => 6795,
62 | ],
63 | 'packet-2500' => [
64 | 100 => 5395,
65 | 500 => 5895,
66 | 1000 => 6395,
67 | 2000 => 7595,
68 | ],
69 | ],
70 | ];
71 |
72 | $boxes = [
73 | 'packet-50' => [
74 | 'length' => 610,
75 | 'width' => 460,
76 | 'height' => 460,
77 | 'weight' => 2000,
78 | ],
79 | 'packet-1000' => [
80 | 'length' => 610,
81 | 'width' => 460,
82 | 'height' => 460,
83 | 'weight' => 2000,
84 | ],
85 | 'packet-2500' => [
86 | 'length' => 610,
87 | 'width' => 460,
88 | 'height' => 460,
89 | 'weight' => 2000,
90 | ],
91 | ];
92 |
93 | $boxPricing = self::getBoxPricing($boxes, $bands);
94 |
95 | foreach ($boxPricing as $key => $box) {
96 | // 20% VAT
97 | if (!self::$includeVat) {
98 | $boxPricing[$key]['price'] = $box['price'] / 1.2;
99 | }
100 | }
101 |
102 | return $boxPricing;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/models/StaticRates.php:
--------------------------------------------------------------------------------
1 | $b['price'];
22 | });
23 |
24 | // For each package, find the cheapest box that fits. We'll use that price for the rate for each package.
25 | foreach ($shipment->getPackages() as $package) {
26 | foreach ($boxRates as $name => $boxRate) {
27 | $box = new PackageBox([
28 | 'reference' => $name,
29 | 'outerWidth' => $boxRate['width'],
30 | 'outerLength' => $boxRate['length'],
31 | 'outerDepth' => $boxRate['height'],
32 | 'emptyWeight' => 0,
33 | 'innerWidth' => $boxRate['width'],
34 | 'innerLength' => $boxRate['length'],
35 | 'innerDepth' => $boxRate['height'],
36 | 'maxWeight' => $boxRate['weight'],
37 | 'price' => $boxRate['price'],
38 | 'currency' => $boxRate['currency'] ?? null,
39 | 'maxItemValue' => $boxRate['itemValue'] ?? null,
40 | ]);
41 |
42 | // Allow the boxes currency to set the overall rate currency
43 | $currency = $boxRate['currency'] ?? null;
44 |
45 | $items = new ItemList();
46 |
47 | $items->insert(new PackageItem([
48 | 'width' => $package->getWidth(),
49 | 'length' => $package->getLength(),
50 | 'depth' => $package->getHeight(),
51 | 'weight' => $package->getWeight(),
52 | 'itemValue' => $package->getPrice(),
53 | 'keepFlat' => false,
54 | ]));
55 |
56 | $volumePacker = new VolumePacker($box, $items);
57 | $packedBox = $volumePacker->pack();
58 |
59 | if ($packedBox->getItems()->count()) {
60 | // Accumulate the price of each box from the carrier to handle multiple packages.
61 | $rate += $packedBox->getBox()->getPrice();
62 |
63 | // Quit looking through boxes that are suitable, we've got one.
64 | break;
65 | }
66 | }
67 | }
68 |
69 | if (!$rate) {
70 | return null;
71 | }
72 |
73 | return new Rate([
74 | 'carrier' => $carrier,
75 | 'serviceName' => Arr::get($carrier::getServiceCodes(), $serviceCode, ''),
76 | 'serviceCode' => $serviceCode,
77 | 'rate' => $rate,
78 | 'currency' => $currency,
79 | ]);
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/src/rates/royalmail/online/SpecialDelivery1pm.php:
--------------------------------------------------------------------------------
1 | [
21 | 'packet-750' => [
22 | 100 => 775,
23 | 500 => 875,
24 | 1000 => 975,
25 | 2000 => 1275,
26 | 10000 => 1735,
27 | 20000 => 2135,
28 | ],
29 | 'packet-1000' => [
30 | 100 => 1075,
31 | 500 => 1175,
32 | 1000 => 1275,
33 | 2000 => 1575,
34 | 10000 => 2035,
35 | 20000 => 2435,
36 | ],
37 | 'packet-2500' => [
38 | 100 => 1775,
39 | 500 => 1875,
40 | 1000 => 1975,
41 | 2000 => 2275,
42 | 10000 => 2735,
43 | 20000 => 3135,
44 | ],
45 | ],
46 | '2025' => [
47 | 'packet-750' => [
48 | 100 => 815,
49 | 500 => 925,
50 | 1000 => 1035,
51 | 2000 => 1345,
52 | 10000 => 1835,
53 | 20000 => 2255,
54 | ],
55 | 'packet-1000' => [
56 | 100 => 1115,
57 | 500 => 1225,
58 | 1000 => 1335,
59 | 2000 => 1645,
60 | 10000 => 2135,
61 | 20000 => 2555,
62 | ],
63 | 'packet-2500' => [
64 | 100 => 1815,
65 | 500 => 1925,
66 | 1000 => 2035,
67 | 2000 => 2345,
68 | 10000 => 2835,
69 | 20000 => 3255,
70 | ],
71 | ],
72 | ];
73 |
74 | $boxes = [
75 | 'packet-750' => [
76 | 'length' => 610,
77 | 'width' => 460,
78 | 'height' => 460,
79 | 'weight' => 20000,
80 | 'itemValue' => 750,
81 | ],
82 | 'packet-1000' => [
83 | 'length' => 610,
84 | 'width' => 460,
85 | 'height' => 460,
86 | 'weight' => 20000,
87 | 'itemValue' => 1000,
88 | ],
89 | 'packet-2500' => [
90 | 'length' => 610,
91 | 'width' => 460,
92 | 'height' => 460,
93 | 'weight' => 20000,
94 | 'itemValue' => 2500,
95 | ],
96 | ];
97 |
98 | return self::getBoxPricing($boxes, $bands);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/SpecialDelivery1pm.php:
--------------------------------------------------------------------------------
1 | [
21 | 'packet-750' => [
22 | 100 => 835,
23 | 500 => 935,
24 | 1000 => 1035,
25 | 2000 => 1335,
26 | 10000 => 1855,
27 | 20000 => 2255,
28 | ],
29 | 'packet-1000' => [
30 | 100 => 1135,
31 | 500 => 1235,
32 | 1000 => 1335,
33 | 2000 => 1635,
34 | 10000 => 2155,
35 | 20000 => 2555,
36 | ],
37 | 'packet-2500' => [
38 | 100 => 1835,
39 | 500 => 1935,
40 | 1000 => 2035,
41 | 2000 => 2335,
42 | 10000 => 2855,
43 | 20000 => 3255,
44 | ],
45 | ],
46 | '2025' => [
47 | 'packet-750' => [
48 | 100 => 875,
49 | 500 => 985,
50 | 1000 => 1095,
51 | 2000 => 1405,
52 | 10000 => 1955,
53 | 20000 => 2375,
54 | ],
55 | 'packet-1000' => [
56 | 100 => 1175,
57 | 500 => 1285,
58 | 1000 => 1395,
59 | 2000 => 1705,
60 | 10000 => 2255,
61 | 20000 => 2675,
62 | ],
63 | 'packet-2500' => [
64 | 100 => 1875,
65 | 500 => 1985,
66 | 1000 => 2095,
67 | 2000 => 2405,
68 | 10000 => 2955,
69 | 20000 => 3375,
70 | ],
71 | ],
72 | ];
73 |
74 | $boxes = [
75 | 'packet-750' => [
76 | 'length' => 610,
77 | 'width' => 460,
78 | 'height' => 460,
79 | 'weight' => 20000,
80 | 'itemValue' => 750,
81 | ],
82 | 'packet-1000' => [
83 | 'length' => 610,
84 | 'width' => 460,
85 | 'height' => 460,
86 | 'weight' => 20000,
87 | 'itemValue' => 1000,
88 | ],
89 | 'packet-2500' => [
90 | 'length' => 610,
91 | 'width' => 460,
92 | 'height' => 460,
93 | 'weight' => 20000,
94 | 'itemValue' => 2500,
95 | ],
96 | ];
97 |
98 | return self::getBoxPricing($boxes, $bands);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/rates/royalmail/online/Tracked24.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LARGE_LETTER => [
22 | 750 => 350,
23 | ],
24 | self::SMALL_PARCEL_WIDE => [
25 | 2000 => 425,
26 | ],
27 | self::SMALL_PARCEL_DEEP => [
28 | 2000 => 425,
29 | ],
30 | self::SMALL_PARCEL_BIGGER => [
31 | 2000 => 425,
32 | ],
33 | self::MEDIUM_PARCEL => [
34 | 2000 => 599,
35 | 10000 => 769,
36 | 20000 => 1219,
37 | ],
38 | self::TUBE => [
39 | 2000 => 599,
40 | 10000 => 769,
41 | 20000 => 1219,
42 | ],
43 | ],
44 | '2025' => [
45 | self::LARGE_LETTER => [
46 | 750 => 360,
47 | ],
48 | self::SMALL_PARCEL_WIDE => [
49 | 2000 => 429,
50 | ],
51 | self::SMALL_PARCEL_DEEP => [
52 | 2000 => 429,
53 | ],
54 | self::SMALL_PARCEL_BIGGER => [
55 | 2000 => 429,
56 | ],
57 | self::MEDIUM_PARCEL => [
58 | 2000 => 605,
59 | 10000 => 790,
60 | 20000 => 1260,
61 | ],
62 | self::TUBE => [
63 | 2000 => 605,
64 | 10000 => 790,
65 | 20000 => 1260,
66 | ],
67 | ],
68 | ];
69 |
70 | $boxes = [
71 | self::LARGE_LETTER => [
72 | 'length' => 353,
73 | 'width' => 250,
74 | 'height' => 25,
75 | 'weight' => 750,
76 | ],
77 | self::SMALL_PARCEL_WIDE => [
78 | 'length' => 450,
79 | 'width' => 350,
80 | 'height' => 160,
81 | 'weight' => 2000,
82 | ],
83 | self::SMALL_PARCEL_DEEP => [
84 | 'length' => 350,
85 | 'width' => 250,
86 | 'height' => 160,
87 | 'weight' => 2000,
88 | ],
89 | self::SMALL_PARCEL_BIGGER => [
90 | 'length' => 450,
91 | 'width' => 350,
92 | 'height' => 160,
93 | 'weight' => 2000,
94 | ],
95 | self::MEDIUM_PARCEL => [
96 | 'length' => 610,
97 | 'width' => 460,
98 | 'height' => 460,
99 | 'weight' => 20000,
100 | ],
101 | self::TUBE => [
102 | 'length' => 900,
103 | 'width' => 70,
104 | 'height' => 70,
105 | 'weight' => 2000,
106 | ],
107 | ];
108 |
109 | return self::getBoxPricing($boxes, $bands, 150);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/rates/royalmail/online/Tracked48.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LARGE_LETTER => [
22 | 750 => 270,
23 | ],
24 | self::SMALL_PARCEL_WIDE => [
25 | 2000 => 339,
26 | ],
27 | self::SMALL_PARCEL_DEEP => [
28 | 2000 => 339,
29 | ],
30 | self::SMALL_PARCEL_BIGGER => [
31 | 2000 => 339,
32 | ],
33 | self::MEDIUM_PARCEL => [
34 | 2000 => 515,
35 | 10000 => 665,
36 | 20000 => 1055,
37 | ],
38 | self::TUBE => [
39 | 2000 => 515,
40 | 10000 => 665,
41 | 20000 => 1055,
42 | ],
43 | ],
44 | '2025' => [
45 | self::LARGE_LETTER => [
46 | 750 => 270,
47 | ],
48 | self::SMALL_PARCEL_WIDE => [
49 | 2000 => 345,
50 | ],
51 | self::SMALL_PARCEL_DEEP => [
52 | 2000 => 345,
53 | ],
54 | self::SMALL_PARCEL_BIGGER => [
55 | 2000 => 345,
56 | ],
57 | self::MEDIUM_PARCEL => [
58 | 2000 => 515,
59 | 10000 => 680,
60 | 20000 => 1080,
61 | ],
62 | self::TUBE => [
63 | 2000 => 515,
64 | 10000 => 680,
65 | 20000 => 1080,
66 | ],
67 | ],
68 | ];
69 |
70 | $boxes = [
71 | self::LARGE_LETTER => [
72 | 'length' => 353,
73 | 'width' => 250,
74 | 'height' => 25,
75 | 'weight' => 750,
76 | ],
77 | self::SMALL_PARCEL_WIDE => [
78 | 'length' => 450,
79 | 'width' => 350,
80 | 'height' => 160,
81 | 'weight' => 2000,
82 | ],
83 | self::SMALL_PARCEL_DEEP => [
84 | 'length' => 350,
85 | 'width' => 250,
86 | 'height' => 160,
87 | 'weight' => 2000,
88 | ],
89 | self::SMALL_PARCEL_BIGGER => [
90 | 'length' => 450,
91 | 'width' => 350,
92 | 'height' => 160,
93 | 'weight' => 2000,
94 | ],
95 | self::MEDIUM_PARCEL => [
96 | 'length' => 610,
97 | 'width' => 460,
98 | 'height' => 460,
99 | 'weight' => 20000,
100 | ],
101 | self::TUBE => [
102 | 'length' => 900,
103 | 'width' => 70,
104 | 'height' => 70,
105 | 'weight' => 2000,
106 | ],
107 | ];
108 |
109 | return self::getBoxPricing($boxes, $bands, 150);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/Tracked24.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LARGE_LETTER => [
22 | 750 => 360,
23 | ],
24 | self::SMALL_PARCEL_WIDE => [
25 | 2000 => 499,
26 | ],
27 | self::SMALL_PARCEL_DEEP => [
28 | 2000 => 499,
29 | ],
30 | self::SMALL_PARCEL_BIGGER => [
31 | 2000 => 499,
32 | ],
33 | self::MEDIUM_PARCEL => [
34 | 2000 => 729,
35 | 10000 => 899,
36 | 20000 => 1349,
37 | ],
38 | self::TUBE => [
39 | 2000 => 729,
40 | 10000 => 899,
41 | 20000 => 1349,
42 | ],
43 | ],
44 | '2025' => [
45 | self::LARGE_LETTER => [
46 | 750 => 370,
47 | ],
48 | self::SMALL_PARCEL_WIDE => [
49 | 2000 => 515,
50 | ],
51 | self::SMALL_PARCEL_DEEP => [
52 | 2000 => 515,
53 | ],
54 | self::SMALL_PARCEL_BIGGER => [
55 | 2000 => 515,
56 | ],
57 | self::MEDIUM_PARCEL => [
58 | 2000 => 745,
59 | 10000 => 929,
60 | 20000 => 1399,
61 | ],
62 | self::TUBE => [
63 | 2000 => 745,
64 | 10000 => 929,
65 | 20000 => 1399,
66 | ],
67 | ],
68 | ];
69 |
70 | $boxes = [
71 | self::LARGE_LETTER => [
72 | 'length' => 353,
73 | 'width' => 250,
74 | 'height' => 25,
75 | 'weight' => 750,
76 | ],
77 | self::SMALL_PARCEL_WIDE => [
78 | 'length' => 450,
79 | 'width' => 350,
80 | 'height' => 160,
81 | 'weight' => 2000,
82 | ],
83 | self::SMALL_PARCEL_DEEP => [
84 | 'length' => 350,
85 | 'width' => 250,
86 | 'height' => 160,
87 | 'weight' => 2000,
88 | ],
89 | self::SMALL_PARCEL_BIGGER => [
90 | 'length' => 450,
91 | 'width' => 350,
92 | 'height' => 160,
93 | 'weight' => 2000,
94 | ],
95 | self::MEDIUM_PARCEL => [
96 | 'length' => 610,
97 | 'width' => 460,
98 | 'height' => 460,
99 | 'weight' => 20000,
100 | ],
101 | self::TUBE => [
102 | 'length' => 900,
103 | 'width' => 70,
104 | 'height' => 70,
105 | 'weight' => 2000,
106 | ],
107 | ];
108 |
109 | return self::getBoxPricing($boxes, $bands, 100);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/Tracked48.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LARGE_LETTER => [
22 | 750 => 280,
23 | ],
24 | self::SMALL_PARCEL_WIDE => [
25 | 2000 => 395,
26 | ],
27 | self::SMALL_PARCEL_DEEP => [
28 | 2000 => 395,
29 | ],
30 | self::SMALL_PARCEL_BIGGER => [
31 | 2000 => 395,
32 | ],
33 | self::MEDIUM_PARCEL => [
34 | 2000 => 645,
35 | 10000 => 795,
36 | 20000 => 1185,
37 | ],
38 | self::TUBE => [
39 | 2000 => 645,
40 | 10000 => 795,
41 | 20000 => 1185,
42 | ],
43 | ],
44 | '2025' => [
45 | self::LARGE_LETTER => [
46 | 750 => 280,
47 | ],
48 | self::SMALL_PARCEL_WIDE => [
49 | 2000 => 405,
50 | ],
51 | self::SMALL_PARCEL_DEEP => [
52 | 2000 => 405,
53 | ],
54 | self::SMALL_PARCEL_BIGGER => [
55 | 2000 => 405,
56 | ],
57 | self::MEDIUM_PARCEL => [
58 | 2000 => 655,
59 | 10000 => 819,
60 | 20000 => 1219,
61 | ],
62 | self::TUBE => [
63 | 2000 => 655,
64 | 10000 => 819,
65 | 20000 => 1219,
66 | ],
67 | ],
68 | ];
69 |
70 | $boxes = [
71 | self::LARGE_LETTER => [
72 | 'length' => 353,
73 | 'width' => 250,
74 | 'height' => 25,
75 | 'weight' => 750,
76 | ],
77 | self::SMALL_PARCEL_WIDE => [
78 | 'length' => 450,
79 | 'width' => 350,
80 | 'height' => 160,
81 | 'weight' => 2000,
82 | ],
83 | self::SMALL_PARCEL_DEEP => [
84 | 'length' => 350,
85 | 'width' => 250,
86 | 'height' => 160,
87 | 'weight' => 2000,
88 | ],
89 | self::SMALL_PARCEL_BIGGER => [
90 | 'length' => 450,
91 | 'width' => 350,
92 | 'height' => 160,
93 | 'weight' => 2000,
94 | ],
95 | self::MEDIUM_PARCEL => [
96 | 'length' => 610,
97 | 'width' => 460,
98 | 'height' => 460,
99 | 'weight' => 20000,
100 | ],
101 | self::TUBE => [
102 | 'length' => 900,
103 | 'width' => 70,
104 | 'height' => 70,
105 | 'weight' => 2000,
106 | ],
107 | ];
108 |
109 | return self::getBoxPricing($boxes, $bands, 100);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/InternationalTracked.php:
--------------------------------------------------------------------------------
1 | [
27 | self::LETTER => [
28 | 100 => [790, 790, 790, 790, 790, 790],
29 | ],
30 | self::LARGE_LETTER => [
31 | 100 => [950, 950, 950, 1055, 1060, 1060],
32 | 250 => [1050, 1050, 1050, 1215, 1335, 1240],
33 | 500 => [1160, 1160, 1160, 1420, 1615, 1450],
34 | 750 => [1205, 1205, 1205, 1625, 1925, 1670],
35 | ],
36 | self::PACKET => [
37 | 250 => [1205, 1240, 1325, 1525, 1670, 1720],
38 | 500 => [1335, 1370, 1500, 1970, 2180, 2185],
39 | 750 => [1435, 1475, 1595, 2240, 2485, 2470],
40 | 1000 => [1500, 1545, 1670, 2530, 2810, 2765],
41 | 1250 => [1550, 1590, 1755, 2745, 3120, 3185],
42 | 1500 => [1550, 1590, 1845, 2900, 3395, 3185],
43 | 2000 => [1550, 1745, 1920, 3020, 3580, 3185],
44 | ],
45 | self::PRINTED_PAPERS => [
46 | 250 => [1205, 1240, 1325, 1525, 1670, 1720],
47 | 500 => [1335, 1370, 1500, 1970, 2180, 2185],
48 | 750 => [1435, 1475, 1595, 2240, 2485, 2470],
49 | 1000 => [1500, 1545, 1670, 2530, 2810, 2765],
50 | 1250 => [1550, 1590, 1755, 2745, 3120, 3185],
51 | 1500 => [1550, 1590, 1845, 2900, 3395, 3185],
52 | 2000 => [1550, 1745, 1920, 3020, 3580, 3185],
53 | ],
54 | ],
55 | '2025' => [
56 | self::LETTER => [
57 | 100 => [810, 810, 810, 810, 810, 810],
58 | ],
59 | self::LARGE_LETTER => [
60 | 100 => [975, 975, 975, 1080, 1085, 1070],
61 | 250 => [1075, 1075, 1075, 1245, 1370, 1250],
62 | 500 => [1190, 1190, 1190, 1455, 1655, 1465],
63 | 750 => [1235, 1235, 1235, 1665, 1975, 1690],
64 | ],
65 | self::PACKET => [
66 | 250 => [1240, 1270, 1390, 1600, 1755, 1685],
67 | 500 => [1370, 1405, 1575, 2070, 2290, 2185],
68 | 750 => [1425, 1510, 1675, 2350, 2610, 2495],
69 | 1000 => [1500, 1585, 1755, 2655, 2950, 2805],
70 | 1250 => [1550, 1630, 1845, 2880, 3275, 3235],
71 | 1500 => [1550, 1630, 1935, 3045, 3565, 3235],
72 | 2000 => [1550, 1790, 2015, 3170, 3760, 3235],
73 | ],
74 | ],
75 | ];
76 |
77 | return self::getInternationalBoxPricing($bands, $countryCode);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/models/Rate.php:
--------------------------------------------------------------------------------
1 | carrier;
30 | }
31 |
32 | public function setCarrier(CarrierInterface $carrier): Rate
33 | {
34 | $this->carrier = $carrier;
35 | return $this;
36 | }
37 |
38 | public function getServiceName(): ?string
39 | {
40 | return $this->serviceName;
41 | }
42 |
43 | public function setServiceName(?string $serviceName): Rate
44 | {
45 | $this->serviceName = $serviceName;
46 | return $this;
47 | }
48 |
49 | public function getServiceCode(): ?string
50 | {
51 | return $this->serviceCode;
52 | }
53 |
54 | public function setServiceCode(?string $serviceCode): Rate
55 | {
56 | $this->serviceCode = $serviceCode;
57 | return $this;
58 | }
59 |
60 | public function getRate(): ?string
61 | {
62 | return $this->rate;
63 | }
64 |
65 | public function setRate(?string $rate): Rate
66 | {
67 | $this->rate = $rate;
68 | return $this;
69 | }
70 |
71 | public function getCurrency(): ?string
72 | {
73 | return $this->currency;
74 | }
75 |
76 | public function setCurrency(?string $currency): Rate
77 | {
78 | $this->currency = $currency;
79 | return $this;
80 | }
81 |
82 | public function getDeliveryDays(): ?int
83 | {
84 | return $this->deliveryDays;
85 | }
86 |
87 | public function setDeliveryDays(?int $deliveryDays): Rate
88 | {
89 | $this->deliveryDays = $deliveryDays;
90 | return $this;
91 | }
92 |
93 | public function getDeliveryDate(): ?DateTime
94 | {
95 | return $this->deliveryDate;
96 | }
97 |
98 | public function setDeliveryDate(DateTime|string|null $deliveryDate): Rate
99 | {
100 | $this->deliveryDate = DateTimeHelper::toDateTime($deliveryDate);
101 | return $this;
102 | }
103 |
104 | public function getDeliveryDateGuaranteed(): ?bool
105 | {
106 | return $this->deliveryDateGuaranteed;
107 | }
108 |
109 | public function setDeliveryDateGuaranteed(?bool $deliveryDateGuaranteed): Rate
110 | {
111 | $this->deliveryDateGuaranteed = $deliveryDateGuaranteed;
112 | return $this;
113 | }
114 |
115 | public function getResponse(): array
116 | {
117 | return $this->response;
118 | }
119 |
120 | public function setResponse(array $response): Rate
121 | {
122 | $this->response = $response;
123 | return $this;
124 | }
125 |
126 | public function toArray(): array
127 | {
128 | // Remove debug/info attributes
129 | $vars = parent::toArray();
130 | unset($vars['carrier'], $vars['response']);
131 |
132 | return $vars;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/rates/royalmail/online/FirstClass.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LETTER => [
22 | 100 => 165,
23 | ],
24 | self::LARGE_LETTER => [
25 | 100 => 250,
26 | 750 => 330,
27 | ],
28 | self::SMALL_PARCEL_WIDE => [
29 | 2000 => 409,
30 | ],
31 | self::SMALL_PARCEL_DEEP => [
32 | 2000 => 409,
33 | ],
34 | self::SMALL_PARCEL_BIGGER => [
35 | 2000 => 409,
36 | ],
37 | self::MEDIUM_PARCEL => [
38 | 2000 => 569,
39 | 10000 => 739,
40 | 20000 => 1189,
41 | ],
42 | ],
43 | '2025' => [
44 | self::LETTER => [
45 | 100 => 170,
46 | ],
47 | self::LARGE_LETTER => [
48 | 100 => 305,
49 | 750 => 330,
50 | ],
51 | self::SMALL_PARCEL_WIDE => [
52 | 2000 => 419,
53 | ],
54 | self::SMALL_PARCEL_DEEP => [
55 | 2000 => 419,
56 | ],
57 | self::SMALL_PARCEL_BIGGER => [
58 | 2000 => 419,
59 | ],
60 | self::MEDIUM_PARCEL => [
61 | 2000 => 585,
62 | 10000 => 765,
63 | 20000 => 1235,
64 | ],
65 | ],
66 | ];
67 |
68 | $boxes = [
69 | self::LETTER => [
70 | 'length' => 240,
71 | 'width' => 165,
72 | 'height' => 5,
73 | 'weight' => 100,
74 | ],
75 | self::LARGE_LETTER => [
76 | 'length' => 353,
77 | 'width' => 250,
78 | 'height' => 25,
79 | 'weight' => 750,
80 | ],
81 | self::SMALL_PARCEL_WIDE => [
82 | 'length' => 450,
83 | 'width' => 350,
84 | 'height' => 160,
85 | 'weight' => 2000,
86 | ],
87 | self::SMALL_PARCEL_DEEP => [
88 | 'length' => 350,
89 | 'width' => 250,
90 | 'height' => 160,
91 | 'weight' => 2000,
92 | ],
93 | self::SMALL_PARCEL_BIGGER => [
94 | 'length' => 450,
95 | 'width' => 350,
96 | 'height' => 160,
97 | 'weight' => 2000,
98 | ],
99 | self::MEDIUM_PARCEL => [
100 | 'length' => 610,
101 | 'width' => 460,
102 | 'height' => 460,
103 | 'weight' => 20000,
104 | ],
105 | self::TUBE => [
106 | 'length' => 900,
107 | 'width' => 70,
108 | 'height' => 70,
109 | 'weight' => 2000,
110 | ],
111 | ];
112 |
113 | return self::getBoxPricing($boxes, $bands, 20);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/rates/royalmail/online/InternationalSigned.php:
--------------------------------------------------------------------------------
1 | [
27 | self::LETTER => [
28 | 100 => [815, 815, 815, 815, 815],
29 | ],
30 | self::LARGE_LETTER => [
31 | 100 => [965, 965, 965, 1065, 1080],
32 | 250 => [1020, 1020, 1020, 1160, 1280],
33 | 500 => [1100, 1100, 1100, 1360, 1560],
34 | 750 => [1145, 1145, 1145, 1565, 1865],
35 | ],
36 | self::PACKET => [
37 | 100 => [1015, 970, 1095, 1540, 1330],
38 | 250 => [1015, 970, 1095, 1575, 1365],
39 | 500 => [1135, 1125, 1250, 1665, 1815],
40 | 750 => [1240, 1225, 1365, 1905, 2095],
41 | 1000 => [1335, 1315, 1490, 2170, 2410],
42 | 1250 => [1390, 1345, 1645, 2370, 2705],
43 | 1500 => [1400, 1370, 1755, 2550, 3005],
44 | 2000 => [1415, 1415, 2135, 2655, 3210],
45 | ],
46 | ],
47 | '2025' => [
48 | self::LETTER => [
49 | 100 => [850, 850, 850, 850, 850],
50 | ],
51 | self::LARGE_LETTER => [
52 | 100 => [995, 995, 995, 1100, 1115],
53 | 250 => [1040, 1040, 1040, 1185, 1305],
54 | 500 => [1120, 1120, 1120, 1385, 1590],
55 | 750 => [1170, 1170, 1170, 1595, 1900],
56 | ],
57 | self::PACKET => [
58 | 100 => [1065, 1020, 1150, 1615, 1395],
59 | 250 => [1065, 1020, 1150, 1655, 1435],
60 | 500 => [1190, 1180, 1315, 1750, 1905],
61 | 750 => [1300, 1285, 1435, 2000, 2200],
62 | 1000 => [1400, 1380, 1565, 2280, 2530],
63 | 1250 => [1460, 1410, 1725, 2490, 2840],
64 | 1500 => [1470, 1440, 1845, 2675, 3155],
65 | 2000 => [1485, 1485, 2240, 2790, 3370],
66 | ],
67 | ],
68 | ];
69 |
70 | return self::getInternationalBoxPricing($bands, $countryCode);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/FirstClass.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LETTER => [
22 | 100 => 165,
23 | ],
24 | self::LARGE_LETTER => [
25 | 100 => 260,
26 | 750 => 350,
27 | ],
28 | self::SMALL_PARCEL_WIDE => [
29 | 2000 => 479,
30 | ],
31 | self::SMALL_PARCEL_DEEP => [
32 | 2000 => 479,
33 | ],
34 | self::SMALL_PARCEL_BIGGER => [
35 | 2000 => 479,
36 | ],
37 | self::MEDIUM_PARCEL => [
38 | 2000 => 699,
39 | 10000 => 869,
40 | 20000 => 1319,
41 | ],
42 | ],
43 | '2025' => [
44 | self::LETTER => [
45 | 100 => 170,
46 | ],
47 | self::LARGE_LETTER => [
48 | 100 => 315,
49 | 750 => 360,
50 | ],
51 | self::SMALL_PARCEL_WIDE => [
52 | 2000 => 499,
53 | ],
54 | self::SMALL_PARCEL_DEEP => [
55 | 2000 => 499,
56 | ],
57 | self::SMALL_PARCEL_BIGGER => [
58 | 2000 => 499,
59 | ],
60 | self::MEDIUM_PARCEL => [
61 | 2000 => 719,
62 | 10000 => 899,
63 | 20000 => 1369,
64 | ],
65 | ],
66 | ];
67 |
68 | $boxes = [
69 | self::LETTER => [
70 | 'length' => 240,
71 | 'width' => 165,
72 | 'height' => 5,
73 | 'weight' => 100,
74 | ],
75 | self::LARGE_LETTER => [
76 | 'length' => 353,
77 | 'width' => 250,
78 | 'height' => 25,
79 | 'weight' => 750,
80 | ],
81 | self::SMALL_PARCEL_WIDE => [
82 | 'length' => 450,
83 | 'width' => 350,
84 | 'height' => 160,
85 | 'weight' => 2000,
86 | ],
87 | self::SMALL_PARCEL_DEEP => [
88 | 'length' => 350,
89 | 'width' => 250,
90 | 'height' => 160,
91 | 'weight' => 2000,
92 | ],
93 | self::SMALL_PARCEL_BIGGER => [
94 | 'length' => 450,
95 | 'width' => 350,
96 | 'height' => 160,
97 | 'weight' => 2000,
98 | ],
99 | self::MEDIUM_PARCEL => [
100 | 'length' => 610,
101 | 'width' => 460,
102 | 'height' => 460,
103 | 'weight' => 20000,
104 | ],
105 | self::TUBE => [
106 | 'length' => 900,
107 | 'width' => 70,
108 | 'height' => 70,
109 | 'weight' => 2000,
110 | ],
111 | ];
112 |
113 | return self::getBoxPricing($boxes, $bands, 20);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/rates/colissimo/FrEmballageFrance.php:
--------------------------------------------------------------------------------
1 | [
15 | 'length' => 180,
16 | 'width' => 230,
17 | 'height' => 20,
18 | 'weight' => 1000,
19 | 'price' => [
20 | self::ZONE_FR => 1000,
21 | ],
22 | ],
23 | 'bubble-bag-S' => [
24 | 'length' => 290,
25 | 'width' => 330,
26 | 'height' => 20,
27 | 'weight' => 3000,
28 | 'price' => [
29 | self::ZONE_FR => 1000,
30 | ],
31 | ],
32 | 'cardboard-sleeve-XS' => [
33 | 'length' => 220,
34 | 'width' => 140,
35 | 'height' => 50,
36 | 'weight' => 1000,
37 | 'price' => [
38 | self::ZONE_FR => 1000,
39 | ],
40 | ],
41 | 'cardboard-sleeve-S' => [
42 | 'length' => 335,
43 | 'width' => 215,
44 | 'height' => 60,
45 | 'weight' => 3000,
46 | 'price' => [
47 | self::ZONE_FR => 1000,
48 | ],
49 | ],
50 | 'box-S' => [
51 | 'length' => 280,
52 | 'width' => 210,
53 | 'height' => 20,
54 | 'weight' => 1000,
55 | 'price' => [
56 | self::ZONE_FR => 895,
57 | ],
58 | ],
59 | 'box-M' => [
60 | 'length' => 230,
61 | 'width' => 130,
62 | 'height' => 100,
63 | 'weight' => 3000,
64 | 'price' => [
65 | self::ZONE_FR => 800,
66 | ],
67 | ],
68 | 'box-L' => [
69 | 'length' => 315,
70 | 'width' => 210,
71 | 'height' => 157,
72 | 'weight' => 5000,
73 | 'price' => [
74 | self::ZONE_FR => 1200,
75 | ],
76 | ],
77 | 'CD' => [
78 | 'length' => 217,
79 | 'width' => 140,
80 | 'height' => 60,
81 | 'weight' => 1000,
82 | 'price' => [
83 | self::ZONE_FR => 790,
84 | ],
85 | ],
86 | '1-Bottle' => [
87 | 'length' => 390,
88 | 'width' => 168,
89 | 'height' => 104,
90 | 'weight' => 2000,
91 | 'price' => [
92 | self::ZONE_FR => 1110,
93 | ],
94 | ],
95 | '2-Bottles' => [
96 | 'length' => 390,
97 | 'width' => 297,
98 | 'height' => 106,
99 | 'weight' => 5000,
100 | 'price' => [
101 | self::ZONE_FR => 1360,
102 | ],
103 | ],
104 | '3-Bottles' => [
105 | 'length' => 390,
106 | 'width' => 425,
107 | 'height' => 106,
108 | 'weight' => 7000,
109 | 'price' => [
110 | self::ZONE_FR => 1460,
111 | ],
112 | ],
113 | ];
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/rates/royalmail/online/SecondClass.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LETTER => [
22 | 100 => 85,
23 | ],
24 | self::LARGE_LETTER => [
25 | 100 => 155,
26 | 250 => 190,
27 | 500 => 230,
28 | 750 => 250,
29 | ],
30 | self::SMALL_PARCEL_WIDE => [
31 | 2000 => 325,
32 | ],
33 | self::SMALL_PARCEL_DEEP => [
34 | 2000 => 325,
35 | ],
36 | self::SMALL_PARCEL_BIGGER => [
37 | 2000 => 325,
38 | ],
39 | self::MEDIUM_PARCEL => [
40 | 2000 => 485,
41 | 10000 => 635,
42 | 20000 => 1025,
43 | ],
44 | ],
45 | '2025' => [
46 | self::LETTER => [
47 | 100 => 87,
48 | ],
49 | self::LARGE_LETTER => [
50 | 100 => 155,
51 | 250 => 180,
52 | 500 => 220,
53 | 750 => 250,
54 | ],
55 | self::SMALL_PARCEL_WIDE => [
56 | 2000 => 335,
57 | ],
58 | self::SMALL_PARCEL_DEEP => [
59 | 2000 => 335,
60 | ],
61 | self::SMALL_PARCEL_BIGGER => [
62 | 2000 => 335,
63 | ],
64 | self::MEDIUM_PARCEL => [
65 | 2000 => 495,
66 | 10000 => 655,
67 | 20000 => 1055,
68 | ],
69 | ],
70 | ];
71 |
72 | $boxes = [
73 | self::LETTER => [
74 | 'length' => 240,
75 | 'width' => 165,
76 | 'height' => 5,
77 | 'weight' => 100,
78 | ],
79 | self::LARGE_LETTER => [
80 | 'length' => 353,
81 | 'width' => 250,
82 | 'height' => 25,
83 | 'weight' => 750,
84 | ],
85 | self::SMALL_PARCEL_WIDE => [
86 | 'length' => 450,
87 | 'width' => 350,
88 | 'height' => 160,
89 | 'weight' => 2000,
90 | ],
91 | self::SMALL_PARCEL_DEEP => [
92 | 'length' => 350,
93 | 'width' => 250,
94 | 'height' => 160,
95 | 'weight' => 2000,
96 | ],
97 | self::SMALL_PARCEL_BIGGER => [
98 | 'length' => 450,
99 | 'width' => 350,
100 | 'height' => 160,
101 | 'weight' => 2000,
102 | ],
103 | self::MEDIUM_PARCEL => [
104 | 'length' => 610,
105 | 'width' => 460,
106 | 'height' => 460,
107 | 'weight' => 20000,
108 | ],
109 | self::TUBE => [
110 | 'length' => 900,
111 | 'width' => 70,
112 | 'height' => 70,
113 | 'weight' => 2000,
114 | ],
115 | ];
116 |
117 | return self::getBoxPricing($boxes, $bands, 20);
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/SecondClass.php:
--------------------------------------------------------------------------------
1 | [
21 | self::LETTER => [
22 | 100 => 85,
23 | ],
24 | self::LARGE_LETTER => [
25 | 100 => 155,
26 | 250 => 210,
27 | 500 => 250,
28 | 750 => 270,
29 | ],
30 | self::SMALL_PARCEL_WIDE => [
31 | 2000 => 375,
32 | ],
33 | self::SMALL_PARCEL_DEEP => [
34 | 2000 => 375,
35 | ],
36 | self::SMALL_PARCEL_BIGGER => [
37 | 2000 => 375,
38 | ],
39 | self::MEDIUM_PARCEL => [
40 | 2000 => 615,
41 | 10000 => 765,
42 | 20000 => 1155,
43 | ],
44 | ],
45 | '2025' => [
46 | self::LETTER => [
47 | 100 => 87,
48 | ],
49 | self::LARGE_LETTER => [
50 | 100 => 155,
51 | 250 => 200,
52 | 500 => 240,
53 | 750 => 270,
54 | ],
55 | self::SMALL_PARCEL_WIDE => [
56 | 2000 => 390,
57 | ],
58 | self::SMALL_PARCEL_DEEP => [
59 | 2000 => 390,
60 | ],
61 | self::SMALL_PARCEL_BIGGER => [
62 | 2000 => 390,
63 | ],
64 | self::MEDIUM_PARCEL => [
65 | 2000 => 629,
66 | 10000 => 789,
67 | 20000 => 1189,
68 | ],
69 | ],
70 | ];
71 |
72 | $boxes = [
73 | self::LETTER => [
74 | 'length' => 240,
75 | 'width' => 165,
76 | 'height' => 5,
77 | 'weight' => 100,
78 | ],
79 | self::LARGE_LETTER => [
80 | 'length' => 353,
81 | 'width' => 250,
82 | 'height' => 25,
83 | 'weight' => 750,
84 | ],
85 | self::SMALL_PARCEL_WIDE => [
86 | 'length' => 450,
87 | 'width' => 350,
88 | 'height' => 160,
89 | 'weight' => 2000,
90 | ],
91 | self::SMALL_PARCEL_DEEP => [
92 | 'length' => 350,
93 | 'width' => 250,
94 | 'height' => 160,
95 | 'weight' => 2000,
96 | ],
97 | self::SMALL_PARCEL_BIGGER => [
98 | 'length' => 450,
99 | 'width' => 350,
100 | 'height' => 160,
101 | 'weight' => 2000,
102 | ],
103 | self::MEDIUM_PARCEL => [
104 | 'length' => 610,
105 | 'width' => 460,
106 | 'height' => 460,
107 | 'weight' => 20000,
108 | ],
109 | self::TUBE => [
110 | 'length' => 900,
111 | 'width' => 70,
112 | 'height' => 70,
113 | 'weight' => 2000,
114 | ],
115 | ];
116 |
117 | return self::getBoxPricing($boxes, $bands, 20);
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/docs/get-started/core-concepts.md:
--------------------------------------------------------------------------------
1 | # Core Concepts
2 |
3 | ## A unified API
4 | Shipping carriers come in all shapes and sizes. Some use JSON, XML or even SOAP for data. Some have simple authentication, others use OAuth. But every carrier will require the payloads sent to their APIs to be formatted in a specific way — likewise, their responses back will be unique.
5 |
6 | The goal of Shippy is to provide a unified API that abstracts away having to deal with multiple carrier APIs, or their API's themselves as they change with time. To achieve this, Shippy provides a range of classes to represent some of the consistent data that are common across tasks like fetching rates and printing labels.
7 |
8 | ## Models
9 | Shippy supplies several object classes to abstract things. Most notable are:
10 |
11 | ### Rates
12 | - [Address](docs:models/address)
13 | - [Shipment](docs:models/shipment)
14 | - [Package](docs:models/package)
15 | - [Rate](docs:models/rate)
16 |
17 | ### Tracking
18 | - [Tracking](docs:models/tracking)
19 |
20 | ### Labels
21 | - [Shipment](docs:models/shipment)
22 | - [Label](docs:models/label)
23 |
24 | See the [Models](docs:models) section for a full list of models.
25 |
26 | Any Shippy model can be initialized in the following ways — depending on your preference. In all cases, you're free to mix and match, which might be beneficial depending on the logic of your app.
27 |
28 | ### Array-based Syntax
29 | Classes can be created by passing an array into the constructor. For example:
30 |
31 | ```php
32 | use verbb\shippy\models\Address;
33 |
34 | new Address([
35 | 'street1' => 'One Infinite Loop',
36 | 'city' => 'Cupertino',
37 | 'stateProvince' => 'CA',
38 | 'postalCode' => '95014',
39 | 'countryCode' => 'US',
40 | ]);
41 | ```
42 |
43 | ### Fluent-based Syntax
44 | Classes can be created, and then configured by chaining setter methods. For example:
45 |
46 | ```php
47 | use verbb\shippy\models\Address;
48 |
49 | $toAddress = new Address()
50 | ->setStreet1('One Infinite Loop')
51 | ->setCity('Cupertino')
52 | ->setStateProvince('CA')
53 | ->setPostalCode('95014')
54 | ->setCountryCode('US');
55 | ```
56 |
57 | ### Method-based Syntax
58 | Classes can be created using the "usual" approach with non-chained setter methods. For example:
59 |
60 | ```php
61 | use verbb\shippy\models\Address;
62 |
63 | $toAddress = new Address();
64 | $toAddress->setStreet1('One Infinite Loop');
65 | $toAddress->setCity('Cupertino');
66 | $toAddress->setStateProvince('CA');
67 | $toAddress->setPostalCode('95014');
68 | $toAddress->setCountryCode('US');
69 | ```
70 |
71 | ### Hybrid-based Syntax
72 | You're able to mix and match these syntaxes as you see fit.
73 |
74 | ```php
75 | use verbb\shippy\models\Package;
76 |
77 | $package = new Package([
78 | 'length' => 300,
79 | 'width' => 100,
80 | 'height' => 80,
81 | 'weight' => 2000,
82 | ]);
83 |
84 | if ($isPriced) {
85 | $package->setPrice(20);
86 | }
87 |
88 | if ($isMetric) {
89 | $package
90 | ->setDimensionUnit('mm')
91 | ->setWeightUnit('g');
92 | }
93 | ```
94 |
95 | ## Packages
96 | [Package](docs:models/package) models define the items we want to fetch rates for or generate labels for. They have defined dimensions and weight values.
97 |
98 | Alongside these values, we also define the units used. Shippy will handle all the converting for the carrier.
99 |
100 | For example, USPS as a carrier uses pounds (`lbs`) and inches (`in`) for units, and their API requires values to be sent in those units. But you might like to define your packages in kilograms (`kg`) and millimetres (`mm`). Just be sure to set the appropriate units for what you _provide_ and Shippy and the carrier implementation will take care of the rest.
101 |
102 | ```php
103 | use verbb\shippy\models\Package;
104 |
105 | $package = new Package([
106 | 'length' => 3000,
107 | 'width' => 1000,
108 | 'height' => 800,
109 | 'weight' => 2,
110 | 'dimensionUnit' => 'mm',
111 | 'weightUnit' => 'kg',
112 | ]);
113 | ```
--------------------------------------------------------------------------------
/docs/api/events.md:
--------------------------------------------------------------------------------
1 | # Events
2 | Shippy raises some events when communicating with carrier APIs. This can be useful not only for knowing before or after requests are raised, but for manipulating them as well.
3 |
4 | For example, we might like to modify something about the payload sent to carrier APIs before it's sent. Here, we can call `on()` on an instance of a carrier, and which event we'd like to be notified on.
5 |
6 | ```php
7 | use verbb\shippy\carriers\AustraliaPost;
8 | use verbb\shippy\events\RateEvent;
9 |
10 | $carrier = new AustraliaPost([
11 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
12 | ]);
13 |
14 | $carrier->on(AustraliaPost::EVENT_BEFORE_FETCH_RATES, function(RateEvent $event) {
15 | // Change the endpoint for the request
16 | $event->getRequest()->setEndpoint('my/alternative/endpoint');
17 |
18 | // Change some data about the payload
19 | $payload = $event->getRequest()->getPayload();
20 | $payload['my-data'] = 'my-value';
21 |
22 | $event->getRequest()->setPayload($payload);
23 | });
24 | ```
25 |
26 | This would alter the [Request](docs:models/request) object's `endpoint` and `payload` properties to our custom values.
27 |
28 | ## Rate related events
29 |
30 | ### The `beforeFetchRates` event
31 | The event raised before the rates are fetched from the carrier's API.
32 |
33 | ```php
34 | use verbb\shippy\carriers\AustraliaPost;
35 | use verbb\shippy\events\RateEvent;
36 |
37 | $carrier = new AustraliaPost([
38 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
39 | ]);
40 |
41 | $carrier->on(AustraliaPost::EVENT_BEFORE_FETCH_RATES, function(RateEvent $event) {
42 | // ...
43 | });
44 | ```
45 |
46 | ### The `afterFetchRates` event
47 | The event raised after the rates are fetched from the carrier's API, and parsed by the carrier class.
48 |
49 | ```php
50 | use verbb\shippy\carriers\AustraliaPost;
51 | use verbb\shippy\events\RateEvent;
52 |
53 | $carrier = new AustraliaPost([
54 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
55 | ]);
56 |
57 | $carrier->on(AustraliaPost::EVENT_AFTER_FETCH_RATES, function(RateEvent $event) {
58 | // ...
59 | });
60 | ```
61 |
62 | ## Tracking related events
63 |
64 | ### The `beforeFetchTracking` event
65 | The event raised before the tracking information is fetched from the carrier's API.
66 |
67 | ```php
68 | use verbb\shippy\carriers\AustraliaPost;
69 | use verbb\shippy\events\TrackingEvent;
70 |
71 | $carrier = new AustraliaPost([
72 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
73 | ]);
74 |
75 | $carrier->on(AustraliaPost::EVENT_BEFORE_FETCH_TRACKING, function(TrackingEvent $event) {
76 | // ...
77 | });
78 | ```
79 |
80 | ### The `afterFetchTracking` event
81 | The event raised after the tracking information is fetched from the carrier's API, and parsed by the carrier class.
82 |
83 | ```php
84 | use verbb\shippy\carriers\AustraliaPost;
85 | use verbb\shippy\events\TrackingEvent;
86 |
87 | $carrier = new AustraliaPost([
88 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
89 | ]);
90 |
91 | $carrier->on(AustraliaPost::EVENT_AFTER_FETCH_TRACKING, function(TrackingEvent $event) {
92 | // ...
93 | });
94 | ```
95 |
96 | ## Label related events
97 |
98 | ### The `beforeFetchLabels` event
99 | The event raised before the labels are fetched from the carrier's API.
100 |
101 | ```php
102 | use verbb\shippy\carriers\AustraliaPost;
103 | use verbb\shippy\events\LabelEvent;
104 |
105 | $carrier = new AustraliaPost([
106 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
107 | ]);
108 |
109 | $carrier->on(AustraliaPost::EVENT_BEFORE_FETCH_LABELS, function(LabelEvent $event) {
110 | // ...
111 | });
112 | ```
113 |
114 | ### The `afterFetchLabels` event
115 | The event raised after the labels are fetched from the carrier's API, and parsed by the carrier class.
116 |
117 | ```php
118 | use verbb\shippy\carriers\AustraliaPost;
119 | use verbb\shippy\events\LabelEvent;
120 |
121 | $carrier = new AustraliaPost([
122 | 'apiKey' => '•••••••••••••••••••••••••••••••••••',
123 | ]);
124 |
125 | $carrier->on(AustraliaPost::EVENT_AFTER_FETCH_LABELS, function(LabelEvent $event) {
126 | // ...
127 | });
128 | ```
129 |
--------------------------------------------------------------------------------
/src/models/PackageBox.php:
--------------------------------------------------------------------------------
1 | reference = $reference;
31 | $this->outerWidth = $width;
32 | $this->outerLength = $length;
33 | $this->outerDepth = $depth;
34 | $this->emptyWeight = 0;
35 | $this->innerWidth = $width;
36 | $this->innerLength = $length;
37 | $this->innerDepth = $depth;
38 | $this->maxWeight = $weight;
39 | }
40 |
41 | public function getReference(): string
42 | {
43 | return (string)$this->reference;
44 | }
45 |
46 | public function setReference($value): void
47 | {
48 | $this->reference = $value;
49 | }
50 |
51 | public function getOuterWidth(): int
52 | {
53 | return (int)$this->outerWidth;
54 | }
55 |
56 | public function setOuterWidth($value): void
57 | {
58 | $this->outerWidth = $value;
59 | }
60 |
61 | public function getOuterLength(): int
62 | {
63 | return (int)$this->outerLength;
64 | }
65 |
66 | public function setOuterLength($value): void
67 | {
68 | $this->outerLength = $value;
69 | }
70 |
71 | public function getOuterDepth(): int
72 | {
73 | return (int)$this->outerDepth;
74 | }
75 |
76 | public function setOuterDepth($value): void
77 | {
78 | $this->outerDepth = $value;
79 | }
80 |
81 | public function getEmptyWeight(): int
82 | {
83 | return (int)$this->emptyWeight;
84 | }
85 |
86 | public function setEmptyWeight($value): void
87 | {
88 | $this->emptyWeight = $value;
89 | }
90 |
91 | public function getInnerWidth(): int
92 | {
93 | return (int)$this->innerWidth;
94 | }
95 |
96 | public function setInnerWidth($value): void
97 | {
98 | $this->innerWidth = $value;
99 | }
100 |
101 | public function getInnerLength(): int
102 | {
103 | return (int)$this->innerLength;
104 | }
105 |
106 | public function setInnerLength($value): void
107 | {
108 | $this->innerLength = $value;
109 | }
110 |
111 | public function getInnerDepth(): int
112 | {
113 | return (int)$this->innerDepth;
114 | }
115 |
116 | public function setInnerDepth($value): void
117 | {
118 | $this->innerDepth = $value;
119 | }
120 |
121 | public function getMaxWeight(): int
122 | {
123 | return (int)$this->maxWeight;
124 | }
125 |
126 | public function setMaxWeight($value): void
127 | {
128 | $this->maxWeight = $value;
129 | }
130 |
131 | public function getType(): string
132 | {
133 | return (string)$this->type;
134 | }
135 |
136 | public function setType($value): void
137 | {
138 | $this->type = $value;
139 | }
140 |
141 | public function getPrice(): float
142 | {
143 | return (float)$this->price;
144 | }
145 |
146 | public function setPrice($value): void
147 | {
148 | $this->price = $value;
149 | }
150 |
151 | public function getCurrency(): string
152 | {
153 | return (string)$this->currency;
154 | }
155 |
156 | public function setCurrency($value): void
157 | {
158 | $this->currency = $value;
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/src/rates/royalmail/postoffice/InternationalSigned.php:
--------------------------------------------------------------------------------
1 | [
27 | self::LETTER => [
28 | 100 => [815, 815, 815, 815, 815],
29 | ],
30 | self::LARGE_LETTER => [
31 | 100 => [965, 965, 965, 1065, 1080],
32 | 250 => [1090, 1090, 1090, 1230, 1350],
33 | 500 => [1170, 1170, 1170, 1430, 1630],
34 | 750 => [1215, 1215, 1215, 1635, 1935],
35 | ],
36 | self::PACKET => [
37 | 100 => [1375, 1390, 1530, 1770, 1900],
38 | 250 => [1375, 1390, 1530, 1810, 1935],
39 | 500 => [1520, 1560, 1700, 2240, 2430],
40 | 750 => [1635, 1670, 1825, 2500, 2740],
41 | 1000 => [1740, 1770, 1955, 2795, 3085],
42 | 1250 => [1800, 1805, 2025, 3015, 3355],
43 | 1500 => [1810, 1830, 2090, 3170, 3630],
44 | 2000 => [1825, 1880, 2140, 3220, 3745],
45 | ],
46 | self::PRINTED_PAPERS => [
47 | 100 => [1375, 1390, 1530, 1770, 1900],
48 | 250 => [1375, 1390, 1530, 1810, 1935],
49 | 500 => [1520, 1560, 1700, 2240, 2430],
50 | 750 => [1635, 1670, 1825, 2500, 2740],
51 | 1000 => [1740, 1770, 1955, 2795, 3085],
52 | 1250 => [1800, 1805, 2025, 3015, 3355],
53 | 1500 => [1810, 1830, 2090, 3170, 3630],
54 | 2000 => [1825, 1880, 2140, 3220, 3745],
55 | ],
56 | ],
57 | '2025' => [
58 | self::LETTER => [
59 | 100 => [850, 850, 850, 850, 850],
60 | ],
61 | self::LARGE_LETTER => [
62 | 100 => [1005, 1005, 1005, 1110, 1125],
63 | 250 => [1135, 1135, 1135, 1280, 1405],
64 | 500 => [1215, 1215, 1215, 1485, 1695],
65 | 750 => [1265, 1265, 1265, 1700, 2010],
66 | ],
67 | self::PACKET => [
68 | 100 => [1425, 1460, 1635, 1895, 1995],
69 | 250 => [1425, 1460, 1635, 1895, 1995],
70 | 500 => [1580, 1640, 1820, 2350, 2550],
71 | 750 => [1700, 1755, 1955, 2625, 2875],
72 | 1000 => [1810, 1860, 2090, 2935, 3240],
73 | 1250 => [1870, 1895, 2165, 3165, 3525],
74 | 1500 => [1880, 1920, 2235, 3330, 3810],
75 | 2000 => [1900, 1975, 2290, 3380, 3930],
76 | ],
77 | ],
78 | ];
79 |
80 | return self::getInternationalBoxPricing($bands, $countryCode);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------