This package provides a straightforward and easy-to-use integration with PPL myApi 2, focusing on creating shipments and downloading shipping labels within the PPL system. Rather than implementing the entire API, this package is designed to cover only the essential features needed for shipment processing.
While our primary focus is on shipment creation, we welcome community contributions and encourage pull requests for additional features.
- Full support for all
/codelist/
endpoints - Shipment creation via
POST /shipment/batch
- Label download (retrievable from the shipment creation response)
- Direct API requests via
PplMyApi::request
, with customizable response handling
For detailed implementation instructions, see the Usage section below.
- Official API documentation: PPL Sandbox
- Need help? Open an issue on GitHub
You can install the package via composer:
composer require bohemicastudio/ppl-myapi
You have to publish the config file and setup proper credentials:
php artisan vendor:publish --tag="ppl-myapi-config"
This is the contents of the published config file:
return [
'client_id' => env('PPL_MYAPI2_CLIENT_ID'),
'client_secret' => env('PPL_MYAPI2_CLIENT_SECRET'),
'production' => env('PPL_MYAPI2_PRODUCTION', false),
'access_token_url' => env('PPL_MYAPI2_ACCESS_TOKEN_URL', env('PPL_MYAPI2_PRODUCTION') ? 'https://api.dhl.com/ecs/ppl/myapi2/login/getAccessToken' : 'https://api-dev.dhl.com/ecs/ppl/myapi2/login/getAccessToken'),
'base_url' => env('PPL_MYAPI2_BASE_URL', env('PPL_MYAPI2_PRODUCTION') ? 'https://api.dhl.com/ecs/ppl/myapi2' : 'https://api-dev.dhl.com/ecs/ppl/myapi2'),
];
Below is a basic example of how to create a shipment batch using this package and download the labels. You can customize the shipment details by adding additional fields as needed. The provided models ensure a structured approach to handling shipments efficiently.
use BohemicaStudio\PplMyApi\Enums\ProductList;
use BohemicaStudio\PplMyApi\Models\Data\Shipment\ShipmentBatch;
use BohemicaStudio\PplMyApi\Models\Data\Shipment\Shipment;
use BohemicaStudio\PplMyApi\Models\Data\Shipment\Address;
use BohemicaStudio\PplMyApi\Models\Data\Shipment\CashOnDelivery;
use BohemicaStudio\PplMyApi\Models\Data\Shipment\ShipmentSet;
use BohemicaStudio\PplMyApi\Models\Data\Shipment\LabelSettings;
use BohemicaStudio\PplMyApi\Models\Data\Shipment\CompleteLabelSettings;
use BohemicaStudio\PplMyApi\Services\PplMyApiShipmentService;
use BohemicaStudio\PplMyApi\PplMyApi;
use GuzzleHttp\Exception\ClientException;
// First, create a shipment batch. This is a basic example; you can add more fields as required.
$shipmentBatch = new ShipmentBatch(
shipments: [
new Shipment(
// Ideally, use PplMyApiCodelistService to fetch all product types, but you can also use enum as we assume it won't change
productType: ProductList::ParcelCzechBusinessCod->value,
recipient: new Address(
country: 'CZ',
zipCode: '15500',
name: 'Company Name',
name2: 'Company Name',
street: 'Street 10/1',
city: 'Praha 13',
contact: 'John Doe',
phone: '+420123456789',
email: '[email protected]',
),
referenceId: '96aeaec1-4ca6-49f5-b0a6-8eef258586a5',
sender: new Address(
country: 'CZ',
zipCode: '15500',
name: 'Your Company Name',
name2: 'Your Company Name',
street: 'Your Street 10/1',
city: 'Praha 13',
contact: 'Your Name',
phone: '+420223456789',
email: '[email protected]',
),
cashOnDelivery: new CashOnDelivery(
codCurrency: 'CZK',
codPrice: 1000,
codVarSym: '1234567890',
),
shipmentSet: new ShipmentSet(
numberOfShipments: 2, // Number of packages in the shipment
shipmentSetItems: [],
),
),
],
labelSettings: new LabelSettings(
format: 'Pdf',
completeLabelSettings: new CompleteLabelSettings(
isCompleteLabelRequested: true,
pageSize: 'A4',
),
),
shipmentsOrderBy: 'ShipmentNumber',
);
$pplApi = new PplMyApi();
$service = new PplMyApiShipmentService($pplApi);
try {
$shipmentBatchUrl = $service->createShipmentBatch($shipmentBatch);
} catch (ClientException $e) {
// You may want to output the validation error
dd($e->getResponse()->getBody()->getContents());
}
// Ideally, you should create a delayed queued job for this, that will try this after 1 minute and repeat for let's say 10 minutes (as PPL API does not provide any webhook or callback)
// But if you are forced to do it in the same request, you can do it like this:
$attempts = 0;
while ($attempts < 24) {
sleep($attempts === 0 ? 3 : 2);
// Then we can get the shipment batch detail - parsing of shipment batch detail will work only if there is only one shipment in the batch
// Otherwise you need to parse the response yourself
$detail = $service->getShipmentBatchDetail($shipmentBatchUrl);
if ($detail->isFullyCompleted()) {
$count = 0;
foreach ($detail->items as $item) {
// Make sure the directory exists
$name = 'pdf/' . $item->shipmentNumber . '_' . $count . '.pdf';
file_put_contents(public_path($name), $pplApi->request($item->labelUrl)->getBody()->getContents());
$count++;
}
break;
}
$attempts++;
}
This example demonstrates the core structure for creating a shipment. Be sure to adjust the shipment details based on your requirements.
composer test
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.
This package was inspired by PplMyApi and php-ppl-create-package-label-api.
Discover Bohemica Signage—the hassle-free way to manage digital displays!