Closed MarcoWel closed 1 year ago
Issue persists in 2023.1.8: karrio seems to sucessfully send the request but receives a 500 error back which might not be properly handled:
karrio.api | DEBUG helpers.py 189 sending request (b00523e2-67cd-436c-aa8c-d5ea9a547a1f)...
karrio.api | INFO helpers.py 130 Request URL:: https://cig.dhl.de/services/production/soap
karrio.api | ERROR helpers.py 162 HTTP Error 500: Server Error
karrio.api | ERROR interface.py 64 'utf-8' codec can't decode byte 0xe4 in position 316: invalid continuation byte
DPDHL still does not work for us with live credentials.
Request Log: "Document is empty, line 1, column 1 (<string>, line 1)"
Docker Log:
karrio.api | DEBUG helpers.py 189 sending request (7ce9b009-f4a6-48c8-bc54-9a8ea4b9f565)...
karrio.api | INFO helpers.py 130 Request URL:: https://cig.dhl.de/services/production/soap
karrio.api | ERROR helpers.py 162 HTTP Error 500: Server Error
karrio.api | DEBUG helpers.py 172 Error content:: HTTP Error 500: Server Error
karrio.api | DEBUG serializable.py 30
karrio.api | ERROR interface.py 64 Document is empty, line 1, column 1 (<string>, line 1)
Request Log: {"code":"failure"}
Docker Log:
karrio.api | DEBUG helpers.py 189 sending request (7d90eeb0-3ac6-4de9-b244-de72fa05388f)...
karrio.api | INFO helpers.py 130 Request URL:: https://cig.dhl.de/services/production/soap
karrio.api | ERROR helpers.py 162 HTTP Error 401: Unauthorized
karrio.api | DEBUG helpers.py 172 Error content:: HTTP Error 401: Unauthorized
karrio.api | DEBUG serializable.py 30 <data code="401" error="Unauthorized">
karrio.api | <Status>
karrio.api | <statusCode>401</statusCode>
karrio.api | <statusText>Unauthorized</statusText>
karrio.api | </Status>
karrio.api | </data>
The authentication in production is still returning Unauthorized error
Tested with 2023.1.10, unfortunately it is still not working. The displayed errors are still the same generic ones, but the Docker logs reveal slightly more now.
Wrong basic auth (App ID/password): Still generic error [ { "code": "failure" } ]
, no details in the dev log. Docker log showing:
karrio.api | DEBUG helpers.py 195 sending request (60affd63-2a49-4206-9fab-4c6eb0d38f71)...
karrio.api | INFO helpers.py 136 Request URL:: https://cig.dhl.de/services/production/soap
karrio.api | ERROR helpers.py 168 HTTP Error 401: Unauthorized
karrio.api | DEBUG helpers.py 178 Error content:: HTTP Error 401: Unauthorized
karrio.api | DEBUG serializable.py 30 <data code="401" error="Unauthorized">
karrio.api | <Status>
karrio.api | <statusCode>401</statusCode>
karrio.api | <statusText>Unauthorized</statusText>
karrio.api | </Status>
karrio.api | </data>
With correct basic auth and credentials (user/signature): Still getting generic error [ { "carrier_id": "DHL", "carrier_name": "dpdhl", "code": 4, "message": "Document is empty, line 1, column 1 (<string>, line 1)" } ]
, no details in the dev log. Docker log showing:
karrio.api | DEBUG helpers.py 195 sending request (e77211dc-650e-4fb0-a6b0-97aa0b8568bc)...
karrio.api | INFO helpers.py 136 Request URL:: https://cig.dhl.de/services/production/soap
karrio.api | ERROR helpers.py 168 HTTP Error 500: Server Error
karrio.api | DEBUG helpers.py 178 Error content:: HTTP Error 500: Server Error
karrio.api | DEBUG serializable.py 30
karrio.api | ERROR interface.py 64 Document is empty, line 1, column 1 (<string>, line 1)
XML request still seems to have differing schema version (3.0) from stated request version (3.4):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cis="http://dhl.de/webservice/cisbase" xmlns:ns="http://dhl.de/webservices/businesscustomershipping/3.0">
<soapenv:Header>
<cis:Authentification>
<cis:user>...</cis:user>
<cis:signature>...</cis:signature>
</cis:Authentification>
</soapenv:Header>
<soapenv:Body>
<ns:CreateShipmentOrderRequest>
<ns:Version>
<majorRelease>3</majorRelease>
<minorRelease>4</minorRelease>
</ns:Version>
...
The behavior is the same for production (as shown above) and sandbox (in test mode), where the request looks as follows:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cis="http://dhl.de/webservice/cisbase" xmlns:ns="http://dhl.de/webservices/businesscustomershipping/3.0">
<soapenv:Header>
<cis:Authentification>
<cis:user>2222222222_01</cis:user>
<cis:signature>pass</cis:signature>
</cis:Authentification>
</soapenv:Header>
<soapenv:Body>
<ns:CreateShipmentOrderRequest>
<ns:Version>
<majorRelease>3</majorRelease>
<minorRelease>4</minorRelease>
</ns:Version>
Server error 500 is caused by missing postfix in account number, see #333.
Please close this issue once the generic server errors are translated to a proper error (e.g. "Site-ID or Signature wrong" for error 401, "Check Account Number " for error 500).
Update: Label creation working, tracking still failing with original error of this issue "Log-in failed" for both sandbox and production:
It seems that for tracking in test mode, DHL expects the dev user ID + password in the xml part of the request, not the app-id + password. Swapping the credentials in karrio leads to the request looking correct, but results in a 401 Unauthorized error.
https://entwickler.dhl.de/group/ep/wsapis/sendungsverfolgung/authentifizierung
Weirdly, for tracking HTTP errors are reported in the dashboard logs, but they are still not appearing under request errors, plus the request is listed as "successful". For label creation, HTTP errors are not reported anywhere but the request is listed under "failed".
Hi @MarcoWel ,
I am hoping to get this fixed in the next patch. Could you please send me a concrete sample of the requests that you got working on your end:
Basic Auth: username:password => [DEVELOPER_ID]:[DEV_PORTAL_PASSWORD]
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<data appname="zt12345"
language-code="en"
password="geheim"
piece-code="00340434161094015902"
request="d-get-piece-detail"/>
This works ^
Basic Auth: username:password => [APP_ID]:[APP_TOKEN]
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<data appname="[WHAT_GOES_HERE?]"
language-code="en"
password="[WHAT_GOES_HERE?]"
piece-code="00340434161094015902"
request="d-get-piece-detail"/>
Basic Auth: username:password => [DEVELOPER_ID]:[DEV_PORTAL_PASSWORD]
+
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:cis="http://dhl.de/webservice/cisbase"
xmlns:ns="http://dhl.de/webservices/businesscustomershipping/3.0">
<soapenv:Header>
<cis:Authentification>
<cis:user>2222222222_01</cis:user>
<cis:signature>pass</cis:signature>
</cis:Authentification>
</soapenv:Header>
<soapenv:Body>
<ns:CreateShipmentOrderRequest>
<ns:Version>
<majorRelease>3</majorRelease>
<minorRelease>4</minorRelease>
</ns:Version>
<ShipmentOrder>
<sequenceNumber>1</sequenceNumber>
<Shipment>
<ShipmentDetails>
<product>V01PAK</product>
<cis:accountNumber>22222222220102</cis:accountNumber>
<ShipmentItem>
<weightInKG>1</weightInKG>
<lengthInCM>10</lengthInCM>
<widthInCM>33</widthInCM>
<heightInCM>18</heightInCM>
</ShipmentItem>
<Notification/>
</ShipmentDetails>
<Shipper>
<Name>
<cis:name1>Deut</cis:name1>
<cis:name2></cis:name2>
</Name>
<Address>
<cis:streetName>Römerberg</cis:streetName>
<cis:streetNumber>23</cis:streetNumber>
<cis:zip>60311</cis:zip>
<cis:city>Frankfurt</cis:city>
<cis:Origin>
<cis:country>Germany</cis:country>
<cis:countryISOCode>DE</cis:countryISOCode>
</cis:Origin>
</Address>
<Communication>
<cis:contactPerson>Deut</cis:contactPerson>
</Communication>
</Shipper>
<ShipperReference></ShipperReference>
<Receiver>
<cis:name1>Ana</cis:name1>
<Address>
<cis:streetName>Am Wall</cis:streetName>
<cis:streetNumber>207</cis:streetNumber>
<cis:zip>28195</cis:zip>
<cis:city>Bremen</cis:city>
<cis:Origin>
<cis:country>Germany</cis:country>
<cis:countryISOCode>DE</cis:countryISOCode>
</cis:Origin>
</Address>
<Communication>
<cis:contactPerson>Ana</cis:contactPerson>
</Communication>
</Receiver>
</Shipment>
</ShipmentOrder>
<labelResponseType>B64</labelResponseType>
<combinedPrinting>0</combinedPrinting>
</ns:CreateShipmentOrderRequest>
</soapenv:Body>
</soapenv:Envelope>
This works ^
Basic Auth: username:password => [APP_ID]:[APP_TOKEN]
+
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:cis="http://dhl.de/webservice/cisbase"
xmlns:ns="http://dhl.de/webservices/businesscustomershipping/3.0">
<soapenv:Header>
<cis:Authentification>
<cis:user>[EKP]_01</cis:user>
<cis:signature>[WHAT_GOES_HERE?]</cis:signature>
</cis:Authentification>
</soapenv:Header>
<soapenv:Body>
<ns:CreateShipmentOrderRequest>
<ns:Version>
<majorRelease>3</majorRelease>
<minorRelease>4</minorRelease>
</ns:Version>
<ShipmentOrder>
<sequenceNumber>1</sequenceNumber>
<Shipment>
<ShipmentDetails>
<product>V01PAK</product>
<cis:accountNumber>[EKP]0102</cis:accountNumber>
The challenge is I don't have an EKP
(DHL customer number) so I am unable to test the requests production
If you can sen me working request with clear indication of the [WHAT_GOES_HERE?]
(developer id? app id?...) indications, it would greatly help.
Thanks
Weirdly, for tracking HTTP errors are reported in the dashboard logs, but they are still not appearing under request errors, plus the request is listed as "successful". For label creation, HTTP errors are not reported anywhere but the request is listed under "failed".
This is by design. The idea is to create the tracker whether the tracking number returns a valid response or not. The use case is when you create or import shipments into Karrio that haven't been picked up by carriers yet, the tracking number might not be in the system yet but will be soon.
I agree that it might create confusion though. I am thinking of adding an API parameter to make that explicit. So basically:
POST /v1/trackers
with { tracking_number: 000, carrier_name: ___ } will return an error if tracking failsPOST /v1/trackers
with { tracking_number: 000, carrier_name: ___, pending_pickup: true } will create the tracker even if tracking failsLet me know what you think
For DHL, tracking should work immediately after label creation (so there should not be an HTTP error). In any case, HTTP errors should be properly displayed in the karrio logs IMO.
Please note the following:
Let me add in the correct bits for production.
Shipment
Basic Auth: username:password => [APP_ID]:[APP_TOKEN]
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:cis="http://dhl.de/webservice/cisbase"
xmlns:ns="http://dhl.de/webservices/businesscustomershipping/3.0">
<soapenv:Header>
<cis:Authentification>
<cis:user>[GKP_Username]</cis:user>
<cis:signature>[GKP_Password]</cis:signature>
</cis:Authentification>
</soapenv:Header>
<soapenv:Body>
<ns:CreateShipmentOrderRequest>
<ns:Version>
<majorRelease>3</majorRelease>
<minorRelease>4</minorRelease>
</ns:Version>
<ShipmentOrder>
<sequenceNumber>1</sequenceNumber>
<Shipment>
<ShipmentDetails>
<product>V01PAK</product>
<cis:accountNumber>[EKP]0102</cis:accountNumber>
Tracking
Basic Auth: username:password => [APP_ID]:[APP_TOKEN]
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<data appname="[ZT_ID]"
password="[ZT_Password]"
language-code="en"
piece-code="0034xxxxxxxxxxx"
request="d-get-piece-detail"/>
Tested with 2022.1.12.
The request looks like this:
<data appname="[ZT_ID]"
password="[ZT_Password]"
language-code="en"
piece-code="0034xxxxxxxxxxx"
request="d-get-piece-detail"/>
Could it be the header line is missing like follows?
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<data appname="[ZT_ID]"
password="[ZT_Password]"
language-code="en"
piece-code="0034xxxxxxxxxxx"
request="d-get-piece-detail"/>
@danh91 Tested with 2023.3. There seems to be a new bug so DPDHL is currently not working at all. karrio does not even get to send a request to DPDHL but throws an error before:
karrio.api | ERROR interface.py 64 'dict' object has no attribute 'cities'
karrio.api | Traceback (most recent call last):
karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/api/interface.py", line 62, in wrapper
karrio.api | return func(*args, **kwargs)
karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/api/interface.py", line 279, in process
karrio.api | response: lib.Deserializable = gateway.proxy.get_rates(request)
karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/mappers/dpdhl/proxy.py", line 17, in get_rates
karrio.api | return super().get_rates(request)
karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/universal/mappers/rating_proxy.py", line 48, in get_rates
karrio.api | response: typing.List[typing.Tuple[str, PackageRates]] = [
karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/universal/mappers/rating_proxy.py", line 51, in <listcomp>
karrio.api | get_available_rates(
karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/universal/mappers/rating_proxy.py", line 146, in get_available_rates
karrio.api | _cover_supported_cities = recipient.city in zone.cities or not any(
karrio.api | AttributeError: 'dict' object has no attribute 'cities'
@danh91 Tested with 2023.3. There seems to be a new bug so DPDHL is currently not working at all. karrio does not even get to send a request to DPDHL but throws an error before:
karrio.api | ERROR interface.py 64 'dict' object has no attribute 'cities' karrio.api | Traceback (most recent call last): karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/api/interface.py", line 62, in wrapper karrio.api | return func(*args, **kwargs) karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/api/interface.py", line 279, in process karrio.api | response: lib.Deserializable = gateway.proxy.get_rates(request) karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/mappers/dpdhl/proxy.py", line 17, in get_rates karrio.api | return super().get_rates(request) karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/universal/mappers/rating_proxy.py", line 48, in get_rates karrio.api | response: typing.List[typing.Tuple[str, PackageRates]] = [ karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/universal/mappers/rating_proxy.py", line 51, in <listcomp> karrio.api | get_available_rates( karrio.api | File "/karrio/venv/lib/python3.10/site-packages/karrio/universal/mappers/rating_proxy.py", line 146, in get_available_rates karrio.api | _cover_supported_cities = recipient.city in zone.cities or not any( karrio.api | AttributeError: 'dict' object has no attribute 'cities'
Benign changes at the last minute introduced this bug.
I just pushed a hot-fix 2023.3.01
Tested with 2022.1.12.
- Findings for Shipment are documented in DPDHL: Add postfix to account number depending on product #333.
- For tracking, we got our ZT-ID from DHL. Tracking auth works, but now there is a 400 "Bad request" when trying to add a DPDHL tracker.
The request looks like this:
<data appname="[ZT_ID]" password="[ZT_Password]" language-code="en" piece-code="0034xxxxxxxxxxx" request="d-get-piece-detail"/>
Could it be the header line is missing like follows?
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <data appname="[ZT_ID]" password="[ZT_Password]" language-code="en" piece-code="0034xxxxxxxxxxx" request="d-get-piece-detail"/>
Can you confirm whether your ZT credentials work when you make the request with insomnia?
From the tests we did <?xml version="1.0" encoding="UTF-8" standalone="no"?>
didn't make a difference for the tracking request in test mode
It seems to be an issue on DHL API side. Sandbox works flawlessly, the production endpoint is giving 400 responses no matter what (even with empty body). We opened a support ticket with DHL.
One improvement suggestion for karrio would be to display the full error details:
Got the DPDHL tracking to work now.
The request can be sent as follows:
GET: (Basic Auth: [APP_ID]:[APP_TOKEN])
https://cig.dhl.de/services/production/rest/sendungsverfolgung?xml=<?xml version="1.0" encoding="UTF-8" standalone="no"?> <data appname="zt000000" language-code="en" password="xxxxxx" piece-code="0034xxxxxxxxxxxxxxxx" request="d-get-piece-detail"/>
POST: (Basic Auth: [APP_ID]:[APP_TOKEN])
curl --location 'https://cig.dhl.de/services/production/rest/sendungsverfolgung' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic xxxxxxxxxxxxxxxxx' \
--data-urlencode 'xml=<?xml version="1.0" encoding="UTF-8" standalone="no"?> <data appname="zt000000" language-code="en" password="xxxxxx" piece-code="0034xxxxxxxxxxxxxxxx" request="d-get-piece-detail"/>'
Both production AND sandbox endpoints work well with above shown solution.
Strangely, the sandbox endpoint behaves differently and works well with the request sent by karrio (xml data as raw in POST body). The production endpoint throws a 400 error with the same request (yet adapted basic auth credentials).
So basically it needs the xml=
to work in both cases 😓
I test
Got the DPDHL tracking to work now.
The request can be sent as follows:
GET: (Basic Auth: [APP_ID]:[APP_TOKEN])
https://cig.dhl.de/services/production/rest/sendungsverfolgung?xml=<?xml version="1.0" encoding="UTF-8" standalone="no"?> <data appname="zt000000" language-code="en" password="xxxxxx" piece-code="0034xxxxxxxxxxxxxxxx" request="d-get-piece-detail"/>
POST: (Basic Auth: [APP_ID]:[APP_TOKEN])
curl --location 'https://cig.dhl.de/services/production/rest/sendungsverfolgung' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'Authorization: Basic xxxxxxxxxxxxxxxxx' \ --data-urlencode 'xml=<?xml version="1.0" encoding="UTF-8" standalone="no"?> <data appname="zt000000" language-code="en" password="xxxxxx" piece-code="0034xxxxxxxxxxxxxxxx" request="d-get-piece-detail"/>'
I updated the code to use this approach and tested it with sandbox. It seems to work well.
Thanks
@danh91 Tested with 2023.4.1.01. Confirm it still works with sandbox. For production, the request itself works now (getting the tracking data back from DPDHL in the response), but there is a parsing error now:
{
"messages": [
{
"carrier_id": "DHL",
"carrier_name": "dpdhl",
"code": "SHIPPING_SDK_INTERNAL_ERROR",
"message": "Requires integer value: invalid literal for int() with base 10: '' (element data/line 2)"
}
]
}
I can confirm that DPDHL tracking now finally works with 2023.4.2 🥳
Since DPDHL API migration, tracking is giving the following error (tested with karrio 2024.2.rc1)
{
"status": 401,
"title": "Unauthorized",
"detail": "Unauthorized for given resource."
}
Solution is to use GET request instead of POST (see here).
Since DPDHL API migration, tracking is giving the following error (tested with karrio 2024.2.rc1)
{ "status": 401, "title": "Unauthorized", "detail": "Unauthorized for given resource." }
Solution is to use GET request instead of POST (see here).
Hi @MarcoWel, I vaguely remember there was an issue with GET. What version did you upgrade from? Was it working on that version?
Upgraded from 2023.5 and it worked back then - did not test 2023.5 after API migration happened on DHL side though. It seems they shut down the POST endpoint and only allow GET requests now.
When setting up the Deutsche Post DHL carrier correctly, there will be the following errors:
Tracking: "Log-in failed"
Label creation: Encoding error