Home / Blogs

How to Integrate DHL Shipping Service in Django in 2024

Django
·

December 28, 2023

how-to-integrate-dhl-shipping-service-in-django

In the fast-paced global landscape of today, efficient and reliable shipping services play a pivotal role in connecting businesses and individuals worldwide. One such prominent player in the logistics and courier industry is DHL, a company that has earned its stripes as a leader in international shipping and express mail services.

Speed and Timeliness:

DHL Express is renowned for its commitment to swift and timely deliveries. With an emphasis on speed, it ensures that parcels and shipments reach their destinations in the shortest possible time.

Global Coverage:

DHL Express provides a truly global shipping solution, reaching over 220 countries and territories. This extensive network facilitates seamless international shipping, making it a preferred choice for businesses with a worldwide reach.

Real-Time Tracking:

DHL provides an efficient tracking system with the help of it the customers and shipper can track their packages.

Flexible Shipping Options:

DHL Express understands the importance of flexibility in shipping. It offers a range of shipping options, including same-day delivery, next-business-day delivery, and standard express services, catering to the diverse needs of customers.

Customs Expertise:

DHL Express excels in customs clearance, leveraging its expertise to ensure smooth passage through customs, minimizing delays, and ensuring compliance.

Proactive Customer Service:

DHL Express provides responsive and proactive customer service. With dedicated support teams, customers can get assistance with queries, concerns, and logistics advice, ensuring a positive shipping experience.

Packaging Solutions:

DHL offers guidance on effective packaging to ensure the safety and security of shipments during transit. This includes recommendations for packaging materials and techniques to protect items in transit.

GoGreen Initiative:

As part of DHL’s commitment to sustainability, DHL Express contributes to the GoGreen program. This initiative focuses on minimizing the environmental impact of express shipping operations through eco-friendly practices.

Risk Management:

DHL has an efficient risk management system and it will reduce the risk of parcel damage and loss of package. The company’s commitment to the safe and secure delivery of parcels enhances customer confidence.

Requirements :

  • python-dhl-api==2.1
  • Django==4.2.1
  • djangorestframework==3.14.0

To read more about using the UPS express API in Django DRF, refer to our blog How to Use the UPS Express API in Django DRF in 2024

Workflow of DHL Express.

Address Validation:

Address validation can be used to check if DHL Express is available at that address and any service can be used to send parcels to that address so before creating a shipment we can use address validation.

Shipping Rates and Quotes:

DHL offers tools on its website that allow users to calculate shipping rates and obtain quotes based on factors such as package dimensions, weight, destination, and service level.

Shipping:

DHL Express is known for its express shipping services, providing fast and reliable delivery options for international and domestic shipments.

Standard Shipping:

In addition to express services, DHL provides standard shipping options for less time-sensitive shipments.

Pickup:

DHL Express offers scheduled pickup services, allowing customers to arrange for the collection of their shipments from their locations. This service adds convenience for businesses and individuals.

Email and SMS Notifications:

Customers can opt to receive email or SMS notifications about the status of their shipments, including delivery updates and any potential issues.

How to implement these services in Django?

First, create a Django project set your basic workflow, and install the DHL package

pip install python-dhl-api

1. Address Validation:

First, we can validate that the address we want to ship is available for shipment using DHL address validation Django URLs:

urlpatterns = [
    path('dhl-address-validation',views.DhlAddressValidationView.as_view()),
      ]

Django views:

class DhlAddressValidationView(APIView):
    def post(self, request):
        if settings.DHL_TEST:
            test = '/test'
        url = f'https://express.api.dhl.com/mydhlapi{test}/address-validate'
        api_key = settings.DHL_API_KEY
        api_secret = settings.DHL_API_SECRET
        type = request.data.get('type', None)
        county_code = request.data.get('country_code', None)
        pin_code = request.data.get('pin_code', None)
        response = requests.get(
            url, params=f"type={type}&countryCode={county_code}&postalCode={pin_code}", auth=(api_key, api_secret))
        if response.status_code == 200:
            response = {'success': True, **response.json}
        else:
            response = response.json()
        return Response(response)

Request body:

{
  type : delivery or pickup,
  country_code :IN,
  pin_code: 124454
}

2. DHL Rates :

To check the services available in DHL and their rates we can use DHL rates API it will give available services to the shipping location and rates of those services.

Django URLs:

urlpatterns = [
    path('dhl-rates',views.DhlratesView.as_view()),
] 

Django Views:

class DhlratesView(APIView):
    def get(self, request):
        serializer = DHLRateRequestSerializer(data=request.data)
        if serializer.is_valid():
            url = 'https://express.api.dhl.com/mydhlapi/rates'
            username = 'almaffrobotRO'
            password = 'H@0eL^1oH$5bX$5e'
            response = requests.get(
                url, params=serializer.data, auth=(username, password))
            if response.status_code == 200:
                data = response.json()
                estimated_time = data['products'][0]['deliveryCapabilities']
                price = data['products'][0]['totalPrice']
                response_data = {
                    'estimated_delivery_time': estimated_time, 'delivery_price': price}
                return Response(response.json())
            else:
                return Response(f"Request failed with status code {response.text}")
        else:
            return Response(serializer.errors, status=400)

Request body:

{
    "ship_from": {
        "street_line1": "Via Maestro Zampieri, 14",
        "postal_code": "36016",
        "province_code": "VI",
        "country_code": "IT",
        "city_name": "Thiene"
    },
    "ship_to": {
        "street_line1": "Rue Poncelet, 17",
        "postal_code": "75017",
        "province_code": "VI",
        "country_code": "FR",
        "city_name": "Paris"
    },
    "package": {
        "weight": 10,
        "length": 20,
        "width": 15,
        "height": 8
    }
}

3. DHL Shipment

Once we check the rates and then we can create a shipment based on the service we choose.

Django URLs:

urlpatterns = [
    path('dhl-shipment',views.DhlShippingCreateView.as_view()),
]

Django views :

class DhlShippingCreateView(APIView):


    def post(self, request):


        product_info = request.data.get("product_info", {})
        receiver_info = request.data.get("receiver_info", {})
        sender_info = request.data.get("sender_info", {})
        receiver_address_data = request.data.get("receiver_address_data", {})
        sender_address_data = request.data.get("sender_address_data", {})
        tax_info = request.data.get("tax_info", {})
        service_code = request.data.get('service_code', '')
        product_code = request.data.get('product_code', '')
        uom = request.data.get('uom', '')
        declared_value_currency = request.data.get(
            'declared_value_currency', '')
        is_custom_declarable = request.data.get('is_custom_declarable', '')
        service = DHLService(api_key=settings.DHL_API_KEY, api_secret=settings.DHL_API_SECRET,
                             account_number=settings.DHL_ACCOUNT_EXPORT,
                             test_mode=False)


        accounts = [
            shipment.DHLAccountType(
                type_code=AccountType.SHIPPER, number=settings.DHL_ACCOUNT_EXPORT),
        ]


        sender_contact = address.DHLContactInformation(
            **sender_info
        )
        sender_address = address.DHLPostalAddress(
            **sender_address_data
        )
        registration_numbers = [address.DHLRegistrationNumber(
            type_code=TypeCode.VAT.name,
            number='42342423423',
            issuer_country_code='IT'
        )]


        receiver_contact = address.DHLContactInformation(
            **receiver_info
        )
        receiver_address = address.DHLPostalAddress(
            **receiver_address_data
        )


        packages = [shipment.DHLProduct(
            **product_info
        )]


        shipment_date = next_business_day()
        shipment_date = shipment_date.replace(
            hour=14, minute=0, second=0, microsecond=0)
        shipment_date = shipment_date.replace(tzinfo=ZoneInfo('Europe/Rome'))


        added_service = [shipment.DHLAddedService(
            service_code=service_code
        )]


        content = shipment.DHLShipmentContent(
            packages=packages,
            is_custom_declarable=False,
            description='Shipment test',
            incoterm_code=IncotermCode.DAP.name,
            unit_of_measurement=MeasurementUnit.METRIC.value,
            product_code=ProductCode.EUROPE.value
        )
        output = shipment.DHLShipmentOutput(
            dpi=300,
            encoding_format='pdf',
            logo_file_format='png',
            logo_file_base64=LOGO_BASE64
        )


        customer_references = ['id1', 'id2']


        """
        Shipment
        """
        s = shipment.DHLShipment(
            accounts=accounts,
            sender_contact=sender_contact,
            sender_address=sender_address,
            sender_registration_numbers=registration_numbers,
            receiver_contact=receiver_contact,
            receiver_address=receiver_address,
            ship_datetime=shipment_date,
            added_services=added_service,
            product_code=ProductCode.EUROPE.value,
            content=content,
            output_format=output,
            customer_references=customer_references,
        )


        ship = service.ship(dhl_shipment=s)


        """                
        Pickup if needed
        """
        if ship.success:


            p = shipment.DHLPickup(
                accounts=accounts,
                sender_contact=sender_contact,
                sender_address=sender_address,
                sender_registration_numbers=registration_numbers,
                receiver_contact=receiver_contact,
                receiver_address=receiver_address,
                pickup_datetime=shipment_date + timedelta(days=1),
                content=content,
            )


            pickup = service.pickup(dhl_pickup=p)
        response_list = []
        if ship.error_title:
            error_response = {'shipment': False, 'Error title: ': ship.error_title,
                              'Error detail: ': ship.error_detail, "details": ship.additional_error_details}
            return Response([error_response])


        else:
            if pickup.success == False:
                error_response = {'pickup': False, 'Error title: ': pickup.error_title,
                                  'Error detail: ': pickup.error_detail, "details": pickup.additional_error_details}
                response_list.append(error_response)
            else:
                pickup_response = {
                    "pickup": True, "dispatch_confirmation_numbers": pickup.dispatch_confirmation_numbers}
                response_list.append(pickup_response)
            ship_response = {"shipment": True,
                             "tracking_number": ship.tracking_number, "lables": ship.documents_bytes}
            response_list.append(ship_response)
            return Response(response_list)

Request body :

{
    "is_custom_declarable": true,
    "uom": "metric",
    "product_code": "",
    "declared_value_currency": "EUR",
    "service_code": "PT",
    "product_info": {
        "weight": 1,
        "length": 35,
        "width": 28,
        "height": 8
    },
    "sender_info": {
        "company_name": "Test Co.",
        "full_name": "Name and surname",
        "phone": "+39000000000",
        "email": "matteo.munaretto@innove.it",
        "contact_type": "BUSINESS"
    },
    "receiver_info": {
        "company_name": "Test Co.",
        "full_name": "Name and surname",
        "phone": "+39000000000",
        "email": "matteo.munaretto@innove.it",
        "contact_type": "BUSINESS"
    },
    "tax_info": {
        "type_code": "VAT",
        "number": "42342423423",
        "issuer_country_code": "IT"
    },
    "receiver_address_data": {
        "street_line1": "Via Maestro Zampieri, 14",
        "postal_code": "36016",
        "province_code": "VI",
        "country_code": "IT",
        "city_name": "Thiene"
    },
    "sender_address_data": {
        "street_line1": "Sos odai 93 101 sector 1",
        "postal_code": "013601",
        "province_code": "VI",
        "country_code": "RO",
        "city_name": "Bucharest"
    }
}

4. DHL Pickup:

Once the shipment is created we can create pickup for the shipment we can create pickup for shipment.

Django URLs:

urlpatterns = [
    path('dhl-pickup',views.DhlPickup.as_view()),
]

Django views:

class DhlPickup(APIView):
    def post(self, request):
        import requests
        url = f'https://express.api.dhl.com/mydhlapi/test/pickups'
        payload = request.data
        response = requests.post(url, json=payload, auth=(
            settings.DHL_API_KEY, settings.DHL_API_SECRET))
        if response.status_code == 201:
            pickup_response = {
                "pickup": True, "dispatch_confirmation_numbers": response.json()['dispatchConfirmationNumbers']}
        else:
            pickup_response = {
                "pickup": False, **response.json()
            }


        return Response(pickup_response)

5. DHL Tracking

Once we create shipment and pickups in the response there will be a tracking number with the tracking number we can track our shipment. 

Django URLs

urlpatterns = [
    path('dhl-tracking/',views.DhlTracking.as_view()),
]

Django views

class DhlTracking(APIView):
    def get(self, track_num):


        url = f'https://express.api.dhl.com/mydhlapi/test/shipments/{track_num}/tracking'
        api_key = settings.DHL_API_KEY
        api_secret = settings.DHL_API_SECRET
        response = requests.get(
            url, auth=(api_key, api_secret))
        if response.status_code == 200:
            response = {'success': True, **response.json()}
        else:
            response = {'success': False, **response.json()}


        return Response(response)

To read more about setting up a currency converter in Django, refer to our blog How to Set Up a Currency Converter in Django

Conclusion : 

In this blog, we have discussed all the basic workflows to implement the DHL Express services in the Django rest framework. I hope it helps you.

Horilla Editorial Team Author

Horilla Editorial Team is a group of experienced writers and editors who are passionate about HR software. We have a deep understanding of the HR landscape and are committed to providing our readers with the most up-to-date and informative content. We have written extensively on a variety of HR software topics, including applicant tracking systems, performance management software, and payroll software etc. We are always looking for new ways to share our knowledge with the HR community. If you have a question about HR software, please don't hesitate to contact us.