Dieser Artikel baut auf dem Leitfaden „Zugriff auf Sendungsinformationen und Ereignisse über die Shipment Data API“ auf und konzentriert sich speziell auf das Abrufen von Preisinformationen, die in den API-Antworten eingebettet sind.
Wir werden untersuchen, wie man zwei Hauptkategorien von Preisinformationen findet und extrahiert:
Vom Frachtführer berechnete und sendungsbezogene Buchungspreise („Preis 1“ und „Preis 2“).
1. Verständnis der verschiedenen Preisquellen in der API-Antwort
Die Shipment Data API liefert Preisinformationen aus verschiedenen Quellen und zu unterschiedlichen Zeitpunkten im Lebenszyklus der Sendung.
-
Vom Frachtführer berechneter Paketpreis (innerhalb von
latestStatuses): Dieser Preis wird typischerweise vom Frachtführer nach der Bearbeitung der Sendung bereitgestellt. Er basiert oft auf tatsächlichen Maßen, Gewicht oder anderen frachtführerspezifischen Preisregeln. Dieser Preis befindet sich im ArraylatestStatusesim AbschnittadditionalInformation. Er stellt einen potenziell genaueren und aktuelleren Preis dar, der häufig die endgültige Gebühr des Frachtführers widerspiegelt. Dieser Preis ist mit einem bestimmten Paket-Barcode verknüpft. -
Sendungsbezogene Buchungspreise („Preis 1“ und „Preis 2“ innerhalb von
shipment.moneyAmounts): Diese Preise, „Preis 1“ und „Preis 2“, werden in der Regel zum Zeitpunkt der Buchung oder Erstellung der Sendung im nShift-System berechnet und festgelegt. Sie stellen eine erste Preisschätzung oder einen vereinbarten Tarif zum Buchungszeitpunkt dar. Diese Preise befinden sich im Objektshipmentinnerhalb des ArraysmoneyAmounts.
Die Struktur mit einem Beispielausschnitt der Antwort, der diese verschiedenen Preispositionen hervorhebt:
[
{
"shipment": {
// ... weitere Sendungsdetails ...
"moneyAmounts": [
{
"currencyCode": "DKK",
"value": 32.69,
"typeId": 1,
"typeName": "Price 1",
"dateCreated": "2025-01-21T11:04:48.747+01:00"
},
{
"currencyCode": "DKK",
"value": 49.69,
"typeId": 2,
"typeName": "Price 2",
"dateCreated": "2025-01-21T11:04:48.747+01:00"
}
],
// ... weitere Sendungsdetails ...
},
"additionalInformation": {
// ... weitere Informationen ...
"latestStatuses": [
{
"shipmentUuid": "65a8c9c7-dd01-41d9-8d10-e7afac963d6a",
"shipmentNumber": "K2211973258",
"moneyAmounts": [
{
"currencyCode": "DKK",
"value": 71.7700,
"typeId": 0,
"dateCreated": "0001-01-01T00:00:00+00:00"
}
],
"status": {
"normalizedStatusName": "Delivered",
"date": "0001-01-01T00:00:00+00:00"
}
},
{
"shipmentUuid": "65a8c9c7-dd01-41d9-8d10-e7afac963d6a",
"shipmentNumber": "K2211973258",
"packageUuid": "814fe967-fca6-45e6-9c8f-03efeb079b09",
"packageNumber": "00370733741672161236",
"moneyAmounts": [
{
"currencyCode": "DKK",
"value": 71.7700,
"typeId": 0,
"dateCreated": "0001-01-01T00:00:00+00:00"
}
],
"status": {
"normalizedStatusName": "Delivered",
"date": "0001-01-01T00:00:00+00:00"
}
}
]
}
}
]
2. Codebeispiele (Python) – Extrahieren verschiedener Preistypen
# --- Pseudocode for accessing nShift Shipment Data API ---
import requests
import json
# --- Configuration ---
CLIENT_ID = "YOUR_CLIENT_ID"
CLIENT_SECRET = "YOUR_CLIENT_SECRET"
TOKEN_ENDPOINT = "https://account.nshiftportal.com/idp/connect/token"
SHIPMENT_DATA_ENDPOINT_AGGREGATED = "https://api.nshiftportal.com/track/shipmentdata/Operational/Shipments/Aggregated/ByBarcode"
BARCODE_TO_TRACK = "YOUR_BARCODE"
START_DATE = "2025-01-26T06:49:59.773Z"
END_DATE = "2025-01-27T23:59:59.773Z"
def get_access_token():
"""Retrieves an access token using Client Credentials grant."""
data = {
"grant_type": "client_credentials",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET
}
headers = {"Content-Type": "application/x-www-form-urlencoded"}
response = requests.post(TOKEN_ENDPOINT, headers=headers, data=data)
response.raise_for_status()
return response.json()["access_token"]
def get_shipment_data(access_token, barcode, start_date, end_date, endpoint_url):
"""Retrieves shipment data from the specified endpoint and extracts price information."""
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
"Accept": "application/json"
}
payload = {
"query": barcode,
"startDate": start_date, # Example date range
"endDate": end_date, # Example date range
"pageSize": 1, # Adjust page size for your needs
"pageIndex": 0
}
response = requests.post(endpoint_url, headers=headers, json=payload)
response.raise_for_status()
return response.json()
if __name__ == "__main__":
try:
token = get_access_token()
print("Access Token obtained successfully.")
aggregated_data = get_shipment_data(token, BARCODE_TO_TRACK, START_DATE, END_DATE, SHIPMENT_DATA_ENDPOINT_AGGREGATED)
if aggregated_data and aggregated_data[0]: # Check if data is returned and not empty
shipment_data = aggregated_data[0]
additional_info = shipment_data.get("additionalInformation", {})
shipment_details = shipment_data.get("shipment", {})
# --- Extract Carrier-Calculated Package Price from latestStatuses ---
carrier_package_price = None
carrier_price_currency = None
for status_entry in additional_info.get("latestStatuses", []):
if status_entry.get("packageNumber") == BARCODE_TO_TRACK:
for money_amount in status_entry.get("moneyAmounts", []):
carrier_package_price = money_amount.get("value")
carrier_price_currency = money_amount.get("currencyCode")
break # Assuming only one price per package status - adjust if needed
if carrier_package_price is not None:
break # Found the price for the barcode, exit loop
if carrier_package_price is not None:
print(f"\nCarrier-Calculated Package Price for barcode {BARCODE_TO_TRACK}: {carrier_package_price} {carrier_price_currency}")
else:
print(f"\nCarrier-Calculated Package Price for barcode {BARCODE_TO_TRACK} not found in latestStatuses.")
# --- Extract Shipment Booking Prices (Price 1 and Price 2) ---
booking_price_1 = None
booking_price_2 = None
booking_price_currency_1 = None
booking_price_currency_2 = None
for money_amount in shipment_details.get("moneyAmounts", []):
if money_amount.get("typeName") == "Price 1":
booking_price_1 = money_amount.get("value")
booking_price_currency_1 = money_amount.get("currencyCode")
elif money_amount.get("typeName") == "Price 2":
booking_price_2 = money_amount.get("value")
booking_price_currency_2 = money_amount.get("currencyCode")
if booking_price_1 is not None:
print(f"Shipment Booking Price 1: {booking_price_1} {booking_price_currency_1}")
else:
print("Shipment Booking Price 1 not found.")
if booking_price_2 is not None:
print(f"Shipment Booking Price 2: {booking_price_2} {booking_price_currency_2}")
else:
print("Shipment Booking Price 2 not found.")
else:
print("No shipment data returned for the barcode.")
except requests.exceptions.HTTPError as e:
print(f"HTTP Error: {e}")
print(f"Response Status Code: {e.response.status_code}")
print(f"Response Body: {e.response.text}")
except Exception as e:
print(f"An error occurred: {e}")