Dit artikel bouwt voort op de "Toegang tot Verzendinginformatie en Gebeurtenissen via de Shipment Data API" gids en richt zich specifiek op het ophalen van prijsgegevens die in de API-responses zijn ingebed.
We zullen onderzoeken hoe we twee hoofdtypen prijsinformatie kunnen vinden en extraheren:
Door de vervoerder berekende en boekingsprijzen op verzendniveau ("Prijs 1" en "Prijs 2").
1. Begrijpen van Verschillende Prijsbronnen in de API-Response
De Shipment Data API biedt prijsinformatie uit verschillende bronnen en op verschillende momenten in de levenscyclus van de zending.
-
Door vervoerder berekende prijs op pakketniveau (binnen
latestStatuses): Deze prijs wordt doorgaans door de vervoerder na verwerking van de zending verstrekt. Het is vaak gebaseerd op daadwerkelijke metingen, gewicht of andere vervoerderspecifieke prijsregels. Deze prijs bevindt zich binnen delatestStatusesarray in deadditionalInformationsectie. Het vertegenwoordigt een mogelijk nauwkeurigere en meer actuele prijs, vaak de uiteindelijke kosten van de vervoerder. Deze prijs is gekoppeld aan een specifieke pakketbarcode. -
Boekingsprijzen op verzendniveau ("Prijs 1" en "Prijs 2" binnen
shipment.moneyAmounts): Deze prijzen, "Prijs 1" en "Prijs 2", worden doorgaans berekend en vastgesteld op het moment dat de zending aanvankelijk wordt geboekt of aangemaakt binnen het nShift-systeem. Ze vertegenwoordigen een initiële prijsinschatting of overeengekomen tarief op het moment van boeken. Deze prijzen zijn te vinden in hetshipmentobject, binnen demoneyAmountsarray.
De structuur met een voorbeeld van een responsefragment, waarbij deze verschillende prijslocaties worden benadrukt:
[
{
"shipment": {
// ... andere verzendgegevens ...
"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"
}
],
// ... andere verzendgegevens ...
},
"additionalInformation": {
// ... andere informatie ...
"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. Voorbeelden van Code (Python) - Extractie van Verschillende Prijstypen
# --- 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}")