Denna artikel bygger vidare på guiden "Åtkomst till försändelseinformation och händelser via Shipment Data API" och fokuserar specifikt på att hämta prisuppgifter inbäddade i API-svaren.
Vi kommer att utforska hur man hittar och extraherar två huvudkategorier av prisinformation:
Transportörsberäknade och bokningspriser på försändelsenivå ("Pris 1" och "Pris 2").
1. Förstå olika prisers källor i API-svaret
Shipment Data API tillhandahåller prisinformation från olika källor och i olika skeden av försändelsens livscykel.
-
Transportörsberäknat pris på paketnivå (inom
latestStatuses): Detta pris tillhandahålls vanligtvis av transportören efter att försändelsen har hanterats. Det baseras ofta på faktiska mått, vikt eller andra transportörsspecifika prissättningsregler. Detta pris finns inomlatestStatuses-arrayen i avsnittetadditionalInformation. Det representerar ett potentiellt mer exakt och uppdaterat pris, ofta som speglar den slutgiltiga avgiften från transportören. Detta pris är kopplat till en specifik paketstreckkod. -
Bokningspriser på försändelsenivå ("Pris 1" och "Pris 2" inom
shipment.moneyAmounts): Dessa priser, "Pris 1" och "Pris 2", beräknas och sätts vanligtvis vid den tidpunkt då försändelsen initialt bokas eller skapas inom nShift-systemet. De representerar en initial prisuppskattning eller överenskommen taxa vid bokningstillfället. Dessa priser finns ishipment-objektet, inommoneyAmounts-arrayen.
Strukturen med ett exempel på svarssnutt som belyser dessa olika prisplatser:
[
{
"shipment": {
// ... andra försändelsedetaljer ...
"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"
}
],
// ... andra försändelsedetaljer ...
},
"additionalInformation": {
// ... annan information ...
"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. Kodexempel (Python) - Extrahera olika prisetyper
# --- 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}")