├── LICENSE.txt ├── README.md ├── composer.json ├── config └── dpd.php └── src ├── DPDAuthorisation.php ├── DPDException.php ├── DPDParcelStatus.php ├── DPDShipment.php └── DpdServiceProvider.php /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright Bernhard Kraemer and other contributors, https://www.bernhard-kraemer.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DPD Webservices for Laravel 2 | 3 | [![Latest Stable Version](https://poser.pugx.org/bernhardk/laravel-dpd/v/stable)](https://packagist.org/packages/bernhardk/laravel-dpd) 4 | [![GitHub issues](https://img.shields.io/github/issues/BernhardK91/laravel-dpd.svg)](https://github.com/BernhardK91/laravel-dpd/issues) 5 | [![GitHub license](https://img.shields.io/github/license/BernhardK91/laravel-dpd.svg)](https://github.com/BernhardK91/laravel-dpd/blob/master/LICENSE.txt) 6 | [![Packagist](https://img.shields.io/packagist/dt/bernhardk/laravel-dpd.svg)](https://packagist.org/packages/bernhardk/laravel-dpd) 7 | [![Twitter](https://img.shields.io/twitter/url/https/github.com/BernhardK91/laravel-dpd.svg?style=social)](https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Fgithub.com%2FBernhardK91%2Flaravel-dpd) 8 | 9 | 10 | This is a laravel package for the _DPD Webservices_ based on Michiel Meertens' "DPD Webservice" 11 | (https://github.com/meertensm/DPD). 12 | 13 | ## Installation 14 | You can install the package via composer with the following command into an existing laravel project. Please note the requirements below. 15 | ```bash 16 | $ composer require bernhardk/laravel-dpd 17 | ``` 18 | 19 | After that you need to publish the config-file with the following command: 20 | ```bash 21 | $ php artisan vendor:publish --provider="BernhardK\Dpd\DpdServiceProvider" --tag="config" 22 | ``` 23 | 24 | As soon you have configured the credentials in /config/dpd.php you are ready to use the package as described below. 25 | 26 | ## Features 27 | - Submit a shipment to the dpd webservice and retrieve it's label and tracking information 28 | - Retrieve parcel status information 29 | 30 | ## Requirements 31 | - PHP SOAP extension needs to be installed (https://stackoverflow.com/questions/2509143/how-do-i-install-soap-extension/41518256) 32 | - Edit configuration parameters in /config/dpd.php. All parameters are described. 33 | 34 | ## DPD Webservice versions 35 | 36 | | Webservice | Version | 37 | | --- | --- | 38 | | Login Service | 2.0 | 39 | | Shipment Service | 4.4 | 40 | | Parcel Life Cycle Service | 2.0 | 41 | 42 | ## Basic shipment usage 43 | The package registers a class that can be directly used: 44 | ```php 45 | app()->dpdShipment 46 | ``` 47 | 48 | The following code describes a sample usage and returns a PDF file. 49 | 50 | ```php 51 | // Enable DPD B2C delivery method 52 | app()->dpdShipment->setPredict([ 53 | 'channel' => 'email', 54 | 'value' => 'someone@mail.com', 55 | 'language' => 'EN' 56 | ]); 57 | // ATTENTION: Cause of privacy reasons transmitting clients email address is only allowed if client agreed. 58 | 59 | // Set the general shipmentdata 60 | app()->dpdShipment->setGeneralShipmentData([ 61 | 'product' => 'CL', 62 | 'mpsCustomerReferenceNumber1' => 'Test shipment' 63 | ]); 64 | 65 | // Set the sender's address 66 | app()->dpdShipment->setSender([ 67 | 'name1' => 'Your Company', 68 | 'street' => 'Street 12', 69 | 'country' => 'NL', 70 | 'zipCode' => '1234AB', 71 | 'city' => 'Amsterdam', 72 | 'email' => 'contact@yourcompany.com', 73 | 'phone' => '1234567645' 74 | ]); 75 | 76 | // Set the receiver's address 77 | app()->dpdShipment->setReceiver([ 78 | 'name1' => 'Joh Doe', 79 | 'name2' => null, 80 | 'street' => 'Street', 81 | 'houseNo' => '12', 82 | 'zipCode' => '1234AB', 83 | 'city' => 'Amsterdam', 84 | 'country' => 'NL', 85 | 'contact' => null, 86 | 'phone' => null, 87 | 'email' => null, 88 | 'comment' => null 89 | ]); 90 | 91 | // Add as many parcels as you want 92 | app()->dpdShipment->addParcel([ 93 | 'weight' => 3000, // In gram 94 | 'height' => 10, // In centimeters 95 | 'width' => 10, 96 | 'length' => 10 97 | ]); 98 | 99 | app()->dpdShipment->addParcel([ 100 | 'weight' => 5000, 101 | 'height' => 0, // In centimeters 102 | 'width' => 0, 103 | 'length' => 0 // All parameters need to be given. Enter 0 if you have no value 104 | ]); 105 | 106 | // Submit the shipment 107 | app()->dpdShipment->submit(); 108 | 109 | // Get the trackingdata 110 | $trackinglinks = app()->dpdShipment->getParcelResponses(); 111 | 112 | // Show the pdf label 113 | header('Content-Type: application/pdf'); 114 | echo app()->dpdShipment->getLabels(); 115 | ``` 116 | 117 | ## Basic tracking usage 118 | The package registers a class that can be directly used: 119 | ```php 120 | app()->dpdTracking 121 | ``` 122 | 123 | The following code describes a sample usage and returns the Tracking-Status. 124 | 125 | ```php 126 | // Retrieve the parcel's status by it's awb number 127 | $parcelStatus = app()->dpdTracking->getStatus('09981122330100'); 128 | ``` 129 | 130 | ## Support 131 | If you have any questions or problems please open a new issue. 132 | 133 | ## License 134 | This package is licensed under the MIT license. The package is based on Michiel Meertens' "DPD Webservice" 135 | (https://github.com/meertensm/DPD), which is also licensed under the MIT license. 136 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bernhardk/laravel-dpd", 3 | "description": "Laravel package for using DPD Webservices to submit shipment to dpd und retrieve its label and tracking information.", 4 | "keywords": ["laravel", "dpd", "dpd cloud service", "webservices"], 5 | "type": "library", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Bernhard Kraemer", 10 | "email": "mail@bernhard-kraemer.com" 11 | } 12 | ], 13 | "minimum-stability": "dev", 14 | "require": { 15 | "php": ">=8.0.2 || ^8.2", 16 | "ext-soap": "*", 17 | "illuminate/support": "^6|^7|^8|^9|^10|^11|^12" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "BernhardK\\Dpd\\": "src/" 22 | } 23 | }, 24 | "extra": { 25 | "laravel": { 26 | "providers": [ 27 | "BernhardK\\Dpd\\DpdServiceProvider" 28 | ] 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /config/dpd.php: -------------------------------------------------------------------------------- 1 | true, 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Credentials 19 | |-------------------------------------------------------------------------- 20 | | 21 | | Here you need to enter your credentials. If you are still using the sandbox 22 | | you will find the credentials here: https://esolutions.dpd.com/entwickler/entwicklerdaten/sandbox.aspx 23 | | 24 | | delisid => The user's DELIS-Id. 25 | | customerUid => The user's customer uid. This is needed for subaccounts, 26 | | usually this is equal to DELIS-Id. For sendbox usage use 0. 27 | | password => The password of the user. 28 | */ 29 | 30 | 'delisId' => '...', 31 | 'customerUid' => '...', 32 | 'password' => '...', 33 | 34 | /* 35 | |-------------------------------------------------------------------------- 36 | | Message language 37 | |-------------------------------------------------------------------------- 38 | | 39 | | Defines the language of the messages that are logged. Default is 'en_EN' 40 | */ 41 | 42 | 'messageLanguage' => 'en_EN', 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Tracking language 47 | |-------------------------------------------------------------------------- 48 | | 49 | | Defines the language for the track&trace link 50 | */ 51 | 52 | 'trackingLanguage' => 'de_DE', 53 | 54 | /* 55 | |-------------------------------------------------------------------------- 56 | | Saturday delivery 57 | |-------------------------------------------------------------------------- 58 | | 59 | | Defines if saturday delivery is demanded. Only selectable for product 60 | | "E12". Default value is false. 61 | */ 62 | 63 | 'saturdayDelivery' => false, 64 | 65 | /* 66 | |-------------------------------------------------------------------------- 67 | | Printer options 68 | |-------------------------------------------------------------------------- 69 | | 70 | | printerLanguage => !!! DEPRECATED !!! => renamed to outputFormat 71 | | The language in which the parcel labels should be 72 | | returned. PDF as file output. In any case the output 73 | | is base64 encoded. Default is PDF. 74 | | outputFormat => The language in which the parcel labels should be 75 | | returned. PDF as file output. In any case the output 76 | | is base64 encoded. Default is PDF. 77 | | paperFormat => Declares the paper format for parcel label print, 78 | | either "A4" or "A6". For direct printing the format has 79 | | to be set to "A6". "A7" only for return labels, other 80 | | type are not allowed. Default is A6. 81 | | startPosition => Start position for print on A4 paper. 82 | | Value range: UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, LOWER_RIGHT 83 | */ 84 | 85 | 'outputFormat' => 'PDF', 86 | 'paperFormat' => 'A6', 87 | 'startPosition' => 'UPPER_LEFT', 88 | 89 | 90 | /* 91 | |-------------------------------------------------------------------------- 92 | | Tracing 93 | |-------------------------------------------------------------------------- 94 | | 95 | | If tracing is activated, every SOAP-Request and every SOAP-Response will be 96 | | logged. For security, privacy and storage reasons this option should only be 97 | | activated for debug reasons. 98 | | DEFAULT: false 99 | */ 100 | 101 | 'tracing' => false, 102 | 103 | ]; 104 | -------------------------------------------------------------------------------- /src/DPDAuthorisation.php: -------------------------------------------------------------------------------- 1 | false, 13 | 'delisId' => null, 14 | 'password' => null, 15 | 'messageLanguage' => 'en_EN', 16 | 'customerNumber' => null, 17 | 'token' => null 18 | ]; 19 | 20 | const TEST_LOGIN_WSDL = 'https://public-ws-stage.dpd.com/services/LoginService/V2_0/?wsdl'; 21 | const LOGIN_WSDL = 'https://public-ws.dpd.com/services/LoginService/V2_0?wsdl'; 22 | 23 | /** 24 | * Get an authorisation token from the DPD webservice 25 | * @param array $array 26 | * @param boolean $wsdlCache cache the wsdl 27 | * @throws DPDException 28 | */ 29 | public function __construct($array, $wsdlCache = true) 30 | { 31 | $this->authorisation = array_merge($this->authorisation, $array); 32 | $this->environment = [ 33 | 'wsdlCache' => $wsdlCache, 34 | 'loginWsdl' => ($this->authorisation['staging'] ? self::TEST_LOGIN_WSDL : self::LOGIN_WSDL), 35 | ]; 36 | 37 | if($this->environment['wsdlCache']){ 38 | $soapParams = [ 39 | 'cache_wsdl' => WSDL_CACHE_BOTH, 40 | 'trace' => config('dpd.tracing') 41 | ]; 42 | } 43 | else{ 44 | $soapParams = [ 45 | 'cache_wsdl' => WSDL_CACHE_NONE, 46 | 'exceptions' => true, 47 | 'trace' => config('dpd.tracing') 48 | ]; 49 | } 50 | 51 | try{ 52 | 53 | $client = new Soapclient($this->environment['loginWsdl'], $soapParams); 54 | 55 | $auth = $client->getAuth([ 56 | 'delisId' => $this->authorisation['delisId'], 57 | 'password' => $this->authorisation['password'], 58 | 'messageLanguage' => $this->authorisation['messageLanguage'], 59 | ]); 60 | 61 | if(config('dpd.tracing')) { 62 | Log::debug('DPD: SOAP-Request Authorisation: ' . $client->__getLastRequest()); 63 | Log::debug('DPD: SOAP-Response Authorisation: ' . $client->__getLastResponse()); 64 | } 65 | 66 | $auth->return->messageLanguage = $this->authorisation['messageLanguage']; 67 | $this->authorisation['token'] = $auth->return; 68 | 69 | Log::debug('DPD: Authorisation successfull.'); 70 | } 71 | catch (SoapFault $e){ 72 | Log::emergency('DPD: '.$e->detail->authenticationFault->errorMessage); 73 | throw new DPDException('DPD authentication failed: '. $e->detail->authenticationFault->errorMessage); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/DPDException.php: -------------------------------------------------------------------------------- 1 | authorisation = $authorisationObject->authorisation; 24 | $this->environment = [ 25 | 'wsdlCache' => $wsdlCache, 26 | 'parcelStatusWsdl' => ($this->authorisation['staging'] ? self::TEST_PARCELSTATUS_WSDL : self::PARCELSTATUS_WSDL), 27 | ]; 28 | } 29 | 30 | /** 31 | * Get the parcel's current status 32 | * @param string $awb 33 | * @return array 34 | */ 35 | public function getStatus($awb) 36 | { 37 | 38 | if ($this->environment['wsdlCache']){ 39 | $soapParams = [ 40 | 'cache_wsdl' => WSDL_CACHE_BOTH, 41 | 'trace' => config('dpd.tracing') 42 | ]; 43 | } 44 | else{ 45 | $soapParams = [ 46 | 'cache_wsdl' => WSDL_CACHE_NONE, 47 | 'exceptions' => true, 48 | 'trace' => config('dpd.tracing') 49 | ]; 50 | } 51 | 52 | try{ 53 | 54 | $client = new Soapclient($this->environment['parcelStatusWsdl'], $soapParams); 55 | $header = new SOAPHeader(self::SOAPHEADER_URL, 'authentication', $this->authorisation['token']); 56 | $client->__setSoapHeaders($header); 57 | $response = $client->getTrackingData(['parcelLabelNumber' => $awb]); 58 | 59 | if(config('dpd.tracing')) { 60 | Log::debug('DPD: SOAP-Request ParcelStatus: ' . $client->__getLastRequest()); 61 | Log::debug('DPD: SOAP-Response ParcelStatus: ' . $client->__getLastResponse()); 62 | } 63 | 64 | $check = (array)$response->trackingresult; 65 | if (empty($check)) { 66 | Log::emergency('DPD: Parcel not found'); 67 | return array(); 68 | } 69 | 70 | foreach($response->trackingresult->statusInfo as $statusInfo){ 71 | if ($statusInfo->isCurrentStatus){ 72 | return [ 73 | 'statusCode' => $statusInfo->status, 74 | 'statusLabel' => $statusInfo->label->content, 75 | 'statusDescription' => $statusInfo->description->content->content, 76 | ]; 77 | } 78 | } 79 | } 80 | catch (SoapFault $e) 81 | { 82 | Log::emergency('DPD: '.$e->faultstring); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/DPDShipment.php: -------------------------------------------------------------------------------- 1 | [ 26 | 'printOption' => [ 27 | 'paperFormat' => null, 28 | 'startPosition' => null, 29 | 'outputFormat' => null 30 | ] 31 | ], 32 | 'order' => [ 33 | 'generalShipmentData' => [ 34 | 'sendingDepot' => null, 35 | 'product' => null, 36 | 'mpsCustomerReferenceNumber1' => null, 37 | 'mpsCustomerReferenceNumber2' => null, 38 | 'sender' => [ 39 | 'name1' => null, 40 | 'name2' => null, 41 | 'street' => null, 42 | 'houseNo' => null, 43 | 'state' => null, 44 | 'country' => null, 45 | 'zipCode' => null, 46 | 'city' => null, 47 | 'email' => null, 48 | 'phone' => null, 49 | 'gln' => null, 50 | 'contact' => null, 51 | 'fax' => null, 52 | 'customerNumber' => null, 53 | ], 54 | 'recipient' => [ 55 | 'name1' => null, 56 | 'name2' => null, 57 | 'street' => null, 58 | 'houseNo' => null, 59 | 'state' => null, 60 | 'country' => null, 61 | 'gln' => null, 62 | 'zipCode' => null, 63 | 'customerNumber' => null, 64 | 'contact' => null, 65 | 'phone' => null, 66 | 'fax' => null, 67 | 'email' => null, 68 | 'city' => null, 69 | 'comment' => null 70 | ] 71 | ], 72 | 'parcels' => [ 73 | ], 74 | 'productAndServiceData' => [ 75 | 'saturdayDelivery' => false, 76 | 'orderType' => 'consignment' 77 | ] 78 | ] 79 | ]; 80 | 81 | protected $trackingLanguage = null; 82 | protected $label = null; 83 | protected $airWayBills = []; 84 | 85 | const TEST_SHIP_WSDL = 'https://public-ws-stage.dpd.com/services/ShipmentService/V4_4?wsdl'; 86 | const SHIP_WSDL = 'https://public-ws.dpd.com/services/ShipmentService/V4_4?wsdl'; 87 | const SOAPHEADER_URL = 'http://dpd.com/common/service/types/Authentication/2.0'; 88 | const TRACKING_URL = 'https://tracking.dpd.de/parcelstatus?locale=:lang&query=:awb'; 89 | 90 | /** 91 | * @param object DPDAuthorisation $authorisationObject 92 | * @param boolean [$wsdlCache = true] 93 | */ 94 | public function __construct(DPDAuthorisation $authorisationObject, $wsdlCache = true) 95 | { 96 | $this->authorisation = $authorisationObject->authorisation; 97 | $this->environment = [ 98 | 'wsdlCache' => $wsdlCache, 99 | 'shipWsdl' => ($this->authorisation['staging'] ? self::TEST_SHIP_WSDL : self::SHIP_WSDL), 100 | ]; 101 | $this->storeOrderMessage['order']['generalShipmentData']['sendingDepot'] = $this->authorisation['token']->depot; 102 | } 103 | 104 | 105 | /** 106 | * Add a parcel to the shipment 107 | * @param array $array 108 | * @throws \BernhardK\Dpd\DPDException 109 | */ 110 | public function addParcel($array) 111 | { 112 | if (!isset($array['weight']) or !isset($array['height']) or !isset($array['length']) or !isset($array['width'])){ 113 | Log::emergency('DPD: Parcel array not complete'); 114 | throw new DPDException('DPD: Parcel array not complete'); 115 | } 116 | 117 | if ((int) $array['length'] < 1) { 118 | Log::emergency('DPD: Minimum value for "length" is 1 cm.'); 119 | throw new DPDException('DPD: Minimum value for "length" is 1 cm.'); 120 | } 121 | 122 | if ((int) $array['width'] < 1) { 123 | Log::emergency('DPD: Minimum value for "width" is 1 cm.'); 124 | throw new DPDException('DPD: Minimum value for "width" is 1 cm.'); 125 | } 126 | 127 | if ((int) $array['height'] < 1) { 128 | Log::emergency('DPD: Minimum value for "height" is 1 cm.'); 129 | throw new DPDException('DPD: Minimum value for "height" is 1 cm.'); 130 | } 131 | 132 | $volume = str_pad((string) ceil($array['length']), 3, '0', STR_PAD_LEFT); 133 | $volume .= str_pad((string) ceil($array['width']), 3, '0', STR_PAD_LEFT); 134 | $volume .= str_pad((string) ceil($array['height']), 3, '0', STR_PAD_LEFT); 135 | 136 | $this->storeOrderMessage['order']['parcels'][] = [ 137 | 'volume' => $volume, 138 | 'weight' => (int) ceil($array['weight'] / 10) 139 | ]; 140 | 141 | //set the flag for return package. DPD will flip sender and receiver on their server 142 | if(isset($array['return']) && $array['return'] === true){ 143 | $this->storeOrderMessage['order']['parcels']['returns'] = true; 144 | } 145 | 146 | 147 | } 148 | 149 | /** 150 | * Submit the parcel to the DPD webservice 151 | */ 152 | public function submit() 153 | { 154 | 155 | if (isset($this->storeOrderMessage['order']['productAndServiceData']['predict'])){ 156 | if (!in_array(strtoupper($this->storeOrderMessage['order']['generalShipmentData']['recipient']['country']), $this->predictCountries)){ 157 | Log::emergency('DPD: Predict service not available for this destination'); 158 | throw new DPDException('DPD: Predict service not available for this destination'); 159 | } 160 | } 161 | if (count($this->storeOrderMessage['order']['parcels']) === 0){ 162 | Log::emergency('DPD: Create at least 1 parcel'); 163 | throw new DPDException('DPD: Create at least 1 parcel'); 164 | } 165 | 166 | if ($this->environment['wsdlCache']){ 167 | $soapParams = [ 168 | 'cache_wsdl' => WSDL_CACHE_BOTH, 169 | 'trace' => config('dpd.tracing') 170 | ]; 171 | } 172 | else{ 173 | $soapParams = [ 174 | 'cache_wsdl' => WSDL_CACHE_NONE, 175 | 'exceptions' => true, 176 | 'trace' => config('dpd.tracing') 177 | ]; 178 | } 179 | 180 | try{ 181 | 182 | $client = new Soapclient($this->environment['shipWsdl'], $soapParams); 183 | $header = new SOAPHeader(self::SOAPHEADER_URL, 'authentication', $this->authorisation['token']); 184 | $client->__setSoapHeaders($header); 185 | $response = $client->storeOrders($this->storeOrderMessage); 186 | 187 | if(config('dpd.tracing')) { 188 | Log::debug('DPD: SOAP-Request Shipment: ' . $client->__getLastRequest()); 189 | Log::debug('DPD: SOAP-Response Shipment: ' . $client->__getLastResponse()); 190 | } 191 | 192 | if (isset($response->orderResult->shipmentResponses->faults)){ 193 | Log::emergency('DPD: '.$response->orderResult->shipmentResponses->faults->message); 194 | throw new DPDException('SOAP Fehler ' . $response->orderResult->shipmentResponses->faults->message); 195 | } 196 | 197 | $this->label = $response->orderResult->output->content; 198 | unset($response->orderResult->output->content); 199 | 200 | if (is_array($response->orderResult->shipmentResponses->parcelInformation)){ 201 | foreach($response->orderResult->shipmentResponses->parcelInformation as $parcelResponse){ 202 | $this->airWayBills[] = [ 203 | 'airWayBill' => $parcelResponse->parcelLabelNumber, 204 | 'trackingLink' => strtr(self::TRACKING_URL, [ 205 | ':awb' => $parcelResponse->parcelLabelNumber, 206 | ':lang' => $this->trackingLanguage 207 | ]) 208 | ]; 209 | } 210 | } 211 | else{ 212 | $this->airWayBills[] = [ 213 | 'airWayBill' => $response->orderResult->shipmentResponses->parcelInformation->parcelLabelNumber, 214 | 'trackingLink' => strtr(self::TRACKING_URL, [ 215 | ':awb' => $response->orderResult->shipmentResponses->parcelInformation->parcelLabelNumber, 216 | ':lang' => $this->trackingLanguage 217 | ]) 218 | ]; 219 | } 220 | } 221 | catch (SoapFault $e) 222 | { 223 | Log::emergency('DPD: '.$e->faultstring); 224 | throw new DPDException('SOAP Fehler ' . $e->faultstring); 225 | } 226 | 227 | } 228 | 229 | /** 230 | * Enable DPD's B2C service. Only allowed for countries in protected $predictCountries 231 | * @param array $array 232 | * 'channel' => email|telephone|sms, 233 | * 'value' => emailaddress or phone number, 234 | * 'language' => EN 235 | */ 236 | public function setPredict($array) 237 | { 238 | 239 | if (!isset($array['channel']) or !isset($array['value']) or !isset($array['language'])){ 240 | Log::emergency('DPD: Predict array not complete'); 241 | throw new DPDException('DPD: Parcel array not complete'); 242 | } 243 | 244 | switch (strtolower($array['channel'])) { 245 | case 'email': 246 | $array['channel'] = 1; 247 | if (!filter_var($array['value'], FILTER_VALIDATE_EMAIL)) { 248 | Log::emergency('DPD: Predict email address not valid'); 249 | throw new DPDException('DPD: Predict email address not valid'); 250 | } 251 | break; 252 | case 'telephone': 253 | $array['channel'] = 2; 254 | if (empty($array['value'])){ 255 | Log::emergency('DPD: Predict value (telephone) empty'); 256 | throw new DPDException('DPD: Predict value (telephone) empty'); 257 | } 258 | break; 259 | case 'sms': 260 | $array['channel'] = 3; 261 | if (empty($array['value'])){ 262 | Log::emergency('DPD: Predict value (sms) empty'); 263 | throw new DPDException('DPD: Predict value (sms) empty'); 264 | } 265 | break; 266 | default: 267 | Log::emergency('DPD: Predict channel not allowed'); 268 | throw new DPDException('DPD: Predict channel not allowed'); 269 | } 270 | 271 | if (ctype_alpha($array['language']) && strlen($array['language']) === 2){ 272 | $array['language'] = strtoupper($array['language']); 273 | } 274 | $this->storeOrderMessage['order']['productAndServiceData']['predict'] = $array; 275 | } 276 | 277 | /** 278 | * Get an array with parcelnumber and trackinglink for each package 279 | * @return array 280 | */ 281 | public function getParcelResponses() 282 | { 283 | return $this->airWayBills; 284 | } 285 | 286 | /** 287 | * Set the general shipmentdata 288 | * @param array $array see protected $storeOrderMessage 289 | */ 290 | public function setGeneralShipmentData($array) 291 | { 292 | $this->storeOrderMessage['order']['generalShipmentData'] = array_merge($this->storeOrderMessage['order']['generalShipmentData'], $array); 293 | } 294 | 295 | /** 296 | * Enable saturday delivery 297 | * @param boolean $bool default false 298 | */ 299 | public function setSaturdayDelivery($bool) 300 | { 301 | $this->storeOrderMessage['order']['productAndServiceData']['saturdayDelivery'] = $bool; 302 | } 303 | 304 | /** 305 | * Set the shipment's sender 306 | * @param array $array see protected $storeOrderMessage 307 | */ 308 | public function setSender($array) 309 | { 310 | $array['customerNumber'] = $this->authorisation['customerNumber']; 311 | $array['city'] = strtoupper($array['city']); 312 | $this->storeOrderMessage['order']['generalShipmentData']['sender'] = array_merge($this->storeOrderMessage['order']['generalShipmentData']['sender'], $array); 313 | } 314 | 315 | /** 316 | * Set the shipment's receiver 317 | * @param array $array see protected $storeOrderMessage 318 | */ 319 | public function setReceiver($array) 320 | { 321 | $this->storeOrderMessage['order']['generalShipmentData']['recipient'] = array_merge($this->storeOrderMessage['order']['generalShipmentData']['recipient'], $array); 322 | } 323 | 324 | /** 325 | * Set the printoptions 326 | * @param array $array see protected $storeOrderMessage 327 | */ 328 | public function setPrintOptions($printoptions) 329 | { 330 | $this->storeOrderMessage['printOptions'] = array_merge($this->storeOrderMessage['printOptions'], $printoptions); 331 | } 332 | 333 | /** 334 | * Set the language for the track & trace link 335 | * @param string $language format: en_EN 336 | */ 337 | public function setTrackingLanguage($language) 338 | { 339 | $this->trackingLanguage = $language; 340 | } 341 | 342 | /** 343 | * Get's the shipment label pdf as a string 344 | * @return string 345 | */ 346 | public function getLabels() 347 | { 348 | return $this->label; 349 | } 350 | 351 | } 352 | -------------------------------------------------------------------------------- /src/DpdServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 15 | __DIR__.'/../config/dpd.php' => config_path('dpd.php'), 16 | ], 'config'); 17 | 18 | } 19 | 20 | public function register() 21 | { 22 | // printerLanguage config deprecation message 23 | if (config('dpd.printerLanguage') != '') { 24 | Log::info('DPD: Config value "printerLanguage" is deprecated. Please update your config!'); 25 | } 26 | 27 | $this->mergeConfigFrom( 28 | __DIR__.'/../config/dpd.php', 'dpd' 29 | ); 30 | 31 | $this->app->singleton('dpdShipment', function(){ 32 | 33 | if (config('dpd.delisId') == '...') { 34 | Log::info('DPD: Package is installed, but config is not set yet. Update config at /config/dpd.php.'); 35 | } 36 | 37 | $authorisation = new DPDAuthorisation([ 38 | 'staging' => config('dpd.sandbox'), 39 | 'delisId' => config('dpd.delisId'), 40 | 'password' => config('dpd.password'), 41 | 'messageLanguage' => config('dpd.messageLanguage'), 42 | 'customerNumber' => config('dpd.customerUid') 43 | ]); 44 | 45 | $shipment = new DPDShipment($authorisation); 46 | 47 | // Set the language for the track&trace link 48 | $shipment->setTrackingLanguage(config('dpd.trackingLanguage')); 49 | 50 | // Enable saturday delivery 51 | $shipment->setSaturdayDelivery(config('dpd.saturdayDelivery')); 52 | 53 | // Set the printer options 54 | $shipment->setPrintOptions([ 55 | 'printOption' => [ 56 | // printerLanguage is deprecated but should still work. 57 | 'outputFormat' => config('dpd.outputFormat') == "" ? config('dpd.printerLanguage') : config('dpd.outputFormat'), 58 | 'paperFormat' => config('dpd.paperFormat'), 59 | 'startPosition' => config('dpd.startPosition') 60 | ] 61 | ]); 62 | 63 | return $shipment; 64 | }); 65 | 66 | $this->app->singleton('dpdTracking', function(){ 67 | 68 | if (config('dpd.delisId') == '...') { 69 | Log::info('DPD: Package is installed, but config is not set yet. Update config at /config/dpd.php.'); 70 | } 71 | 72 | $authorisation = new DPDAuthorisation([ 73 | 'staging' => config('dpd.sandbox'), 74 | 'delisId' => config('dpd.delisId'), 75 | 'password' => config('dpd.password'), 76 | 'messageLanguage' => config('dpd.messageLanguage'), 77 | 'customerNumber' => config('dpd.customerUid') 78 | ]); 79 | 80 | $status = new DPDParcelStatus($authorisation); 81 | 82 | return $status; 83 | }); 84 | } 85 | } 86 | --------------------------------------------------------------------------------