You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bpost has released a new version of the Locator API, https://pudo.bpost.be/Locator. This causes errors with the current implementation of the library. It appears they are phasing out support for HTTP POST requests.
Info API:
The package does an HTTP POST request for the info API to fetch the details of a pudo point. This no longer works since the upgrade. If I do an HTTP GET request it works.
Search API:
The package does an HTTP POST request for the search API with the search parameters as a form url-encoded body. This only works partially since the upgrade. It seems only the postal code is taken into account and the street not. If I encode the parameters as JSON in the body, it works again. A GET request with the parameters as query string works well.
I have contacted bpost to check if they are willing to make this backward compatible again. To fix this temporarily I made my own copy of the Geo6 class. For those experiencing the same issue here is my code:
<?phpnamespaceApp\Services\Logistics\Bpost\Geo6;
useBpost\BpostApiClient\ApiCaller\ApiCaller;
useBpost\BpostApiClient\Exception\BpostApiResponseException\BpostCurlException;
useBpost\BpostApiClient\Exception\BpostApiResponseException\BpostInvalidXmlResponseException;
useBpost\BpostApiClient\Exception\BpostApiResponseException\BpostTaxipostLocatorException;
useBpost\BpostApiClient\Geo6\Poi;
useBpost\BpostApiClient\Logger;
/** * Copy of Bpost\BpostApiClient\Geo6 to "temporarily" fix the API call to support json encoded body instead of form query string, to fix new Bpost API */class Geo6Locator
{
// URL for the apiconstAPI_URL = 'https://pudo.bpost.be/Locator';
// current versionconstVERSION = '3';
/** * @see getPointType * @see getServicePointPageUrl */constPOINT_TYPE_POST_OFFICE = 1;
constPOINT_TYPE_POST_POINT = 2;
constPOINT_TYPE_BPACK_247 = 4;
constPOINT_TYPE_CLICK_COLLECT_SHOP = 8;
/** @var ApiCaller */private$apiCaller;
/** * @var string */private$appId;
/** * @var string */private$partner;
/** * The timeout * * @var int */private$timeOut = 10;
/** * The user agent * * @var string */private$userAgent;
/** * Constructor * @param string $partner Static parameter used for protection/statistics * @param string $appId Static parameter used for protection/statistics */publicfunction__construct($partner, $appId)
{
$this->setPartner((string)$partner);
$this->setAppId((string)$appId);
}
/** * @return ApiCaller */publicfunctiongetApiCaller()
{
if ($this->apiCaller === null) {
$this->apiCaller = newApiCaller(newLogger());
}
return$this->apiCaller;
}
/** * @param ApiCaller $apiCaller */publicfunctionsetApiCaller(ApiCaller$apiCaller)
{
$this->apiCaller = $apiCaller;
}
/** * Build the url to be called * * @param string $method * @param array $parameters * @return string */privatefunctionbuildUrl($method, array$parameters = array())
{
returnself::API_URL . '?' . $this->buildParameters($method, $parameters);
}
/** * Build the parameters to send (URL-encoded string) * * @param string $method * @param array $parameters * @return string */privatefunctionbuildParameters($method, array$parameters = array())
{
// add credentials$parameters = $this->addExtraParameters($method, $parameters);
returnhttp_build_query($parameters);
}
privatefunctionaddExtraParameters($method, array$parameters = array()): array {
$parameters['Function'] = $method;
$parameters['Partner'] = $this->getPartner();
$parameters['AppId'] = $this->getAppId();
$parameters['Format'] = 'xml';
return$parameters;
}
/** * Make the HTTP POST call * * @param string $method * @param array $parameters * @return \SimpleXMLElement * @throws BpostCurlException * @throws BpostInvalidXmlResponseException * @throws BpostTaxipostLocatorException */privatefunctiondoCall($method, array$parameters = array())
{
$parameters = $this->addExtraParameters($method, $parameters);
$options = array(
CURLOPT_URL => self::API_URL,
CURLOPT_USERAGENT => $this->getUserAgent(),
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => (int)$this->getTimeOut(),
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($parameters),
);
$this->getApiCaller()->doCall($options);
return$this->parseResponse();
}
/** * Make the HTTP GET call * * @param string $method * @param array $parameters * @return \SimpleXMLElement * @throws BpostCurlException * @throws BpostInvalidXmlResponseException * @throws BpostTaxipostLocatorException */privatefunctiondoGetCall($method, array$parameters = array())
{
$options = array(
CURLOPT_URL => $this->buildUrl($method, $parameters),
CURLOPT_USERAGENT => $this->getUserAgent(),
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => (int)$this->getTimeOut(),
CURLOPT_POST => false,
);
$this->getApiCaller()->doCall($options);
return$this->parseResponse();
}
/** * @return \SimpleXMLElement * @throws BpostInvalidXmlResponseException * @throws BpostTaxipostLocatorException */privatefunctionparseResponse(): \SimpleXMLElement {
// we expect XML so decode it$xml = @simplexml_load_string($this->getApiCaller()->getResponseBody());
// validate xmlif ($xml === false || (isset($xml->head) && isset($xml->body))) {
thrownewBpostInvalidXmlResponseException();
}
// catch generic errorsif (isset($xml['type']) && (string)$xml['type'] == 'TaxipostLocatorError') {
thrownewBpostTaxipostLocatorException((string)$xml->txt, (int)$xml->status);
}
// returnreturn$xml;
}
/** * @param string $appId */publicfunctionsetAppId($appId)
{
$this->appId = $appId;
}
/** * @return string */publicfunctiongetAppId()
{
return$this->appId;
}
/** * @param string $partner */publicfunctionsetPartner($partner)
{
$this->partner = $partner;
}
/** * @return string */publicfunctiongetPartner()
{
return$this->partner;
}
/** * Set the timeout * After this time the request will stop. You should handle any errors triggered by this. * * @param int $seconds The timeout in seconds. */publicfunctionsetTimeOut($seconds)
{
$this->timeOut = (int)$seconds;
}
/** * Get the timeout that will be used * * @return int */publicfunctiongetTimeOut()
{
return (int)$this->timeOut;
}
/** * Get the useragent that will be used. * Our version will be prepended to yours. * It will look like: "PHP Bpost/<version> <your-user-agent>" * * @return string */publicfunctiongetUserAgent()
{
return (string)'PHP Bpost Geo6/' . self::VERSION . '' . $this->userAgent;
}
/** * Set the user-agent for you application * It will be appended to ours, the result will look like: "PHP Bpost/<version> <your-user-agent>" * * @param string $userAgent Your user-agent, it should look like <app-name>/<app-version>. */publicfunctionsetUserAgent($userAgent)
{
$this->userAgent = (string)$userAgent;
}
// webservice methods/** * The GetNearestServicePoints web service delivers the nearest bpost pick-up points to a location * * @param string $street Street name * @param string $number Street number * @param string $zone Postal code and/or city * @param string $language Language, possible values are: nl, fr * @param int $type Requested point type, possible values are: * - 1: Post Office * - 2: Post Point * - 3: (1+2, Post Office + Post Point) * - 4: bpack 24/7 * - 7: (1+2+4, Post Office + Post Point + bpack 24/7) * @param int $limit * @param string $country Country: "BE", "FR"... * @return array * @throws BpostCurlException * @throws BpostInvalidXmlResponseException * @throws BpostTaxipostLocatorException *///public function getNearestServicePoint($street, $number, $zone, $country = 'BE', $language = 'nl', $type = 3, $limit = 10)publicfunctiongetNearestServicePoint($street, $number, $zone, $language = 'nl', $type = 3, $limit = 10, $country = 'BE')
{
$parameters = array(
'Street' => (string)$street,
'Number' => (string)$number,
'Zone' => (string)$zone,
'Country' => (string)$country,
'Language' => (string)$language,
'Type' => (int)$type,
'Limit' => (int)$limit
);
$xml = $this->doCall('search', $parameters);
if (!isset($xml->PoiList->Poi)) {
thrownewBpostInvalidXmlResponseException();
}
$pois = array();
foreach ($xml->PoiList->Poias$poi) {
$pois[] = array(
'poi' => Poi::createFromXML($poi),
'distance' => (float)$poi->Distance,
);
}
return$pois;
}
/** * The GetServicePointDetails web service delivers the details for a bpost * pick up point referred to by its identifier. * * @param string $id Requested point identifier * @param string $language Language, possible values: nl, fr * @param int $type Requested point type, possible values are: * - 1: Post Office * - 2: Post Point * - 4: bpack 24/7 * @param string $country Country: "BE", "FR"... * * @return Poi * @throws BpostCurlException * @throws BpostInvalidXmlResponseException * @throws BpostTaxipostLocatorException */publicfunctiongetServicePointDetails($id, $language = 'nl', $type = 3, $country = 'BE')
{
$parameters = array(
'Id' => (string)$id,
'Language' => (string)$language,
'Type' => (int)$type,
'Country' => (string)$country,
);
$xml = $this->doGetCall('info', $parameters);
if (!isset($xml->Poi)) {
thrownewBpostInvalidXmlResponseException();
}
return Poi::createFromXML($xml->Poi);
}
/** * @param int $id * @param string $language * @param int $type * @param string $country * @return string * * @see getPointType to feed the param $type */publicfunctiongetServicePointPageUrl($id, $language = 'nl', $type = 3, $country = 'BE')
{
$parameters = array(
'Id' => (string)$id,
'Language' => (string)$language,
'Type' => (int)$type,
'Country' => (string)$country,
);
return$this->buildUrl('page', $parameters);
}
/** * @param int $id * @param string $language * @param int $type * @param string $country * @return string * * @deprecated Renamed * @see getServicePointPageUrl */publicfunctiongetServicePointPage($id, $language = 'nl', $type = 3, $country = 'BE')
{
return$this->getServicePointPageUrl($id, $language, $type, $country);
}
/** * @param bool $withPostOffice * @param bool $withPostPoint * @param bool $withBpack247 * @param bool $withClickAndCollectShop * @return int */publicfunctiongetPointType(
$withPostOffice = true,
$withPostPoint = true,
$withBpack247 = false,
$withClickAndCollectShop = false
) {
return
($withPostOffice ? self::POINT_TYPE_POST_OFFICE : 0)
+ ($withPostPoint ? self::POINT_TYPE_POST_POINT : 0)
+ ($withBpack247 ? self::POINT_TYPE_BPACK_247 : 0)
+ ($withClickAndCollectShop ? self::POINT_TYPE_CLICK_COLLECT_SHOP : 0);
}
}
The text was updated successfully, but these errors were encountered:
Bpost has released a new version of the Locator API, https://pudo.bpost.be/Locator. This causes errors with the current implementation of the library. It appears they are phasing out support for HTTP POST requests.
Info API:
The package does an HTTP POST request for the info API to fetch the details of a pudo point. This no longer works since the upgrade. If I do an HTTP GET request it works.
Search API:
The package does an HTTP POST request for the search API with the search parameters as a form url-encoded body. This only works partially since the upgrade. It seems only the postal code is taken into account and the street not. If I encode the parameters as JSON in the body, it works again. A GET request with the parameters as query string works well.
I have contacted bpost to check if they are willing to make this backward compatible again. To fix this temporarily I made my own copy of the Geo6 class. For those experiencing the same issue here is my code:
The text was updated successfully, but these errors were encountered: