DPD Web服务:如何为拆分货件生成多页面标签
解决DPD API多包裹同一货件的多页标签生成问题
DPD Web服务API完全支持同一货件拆分多包裹并生成多页标签的需求,核心是在同一个订单实例下添加多个包裹对象,并调整打印配置,以下是具体实现步骤和代码修改:
核心修改点
- 添加多个包裹到同一订单:在
ShipmentServiceData中多次调用addParcel(),每个包裹设置独立重量和参考号,但共用同一个货件ID(通过GeneralShipmentData的identificationNumber绑定)。 - 调整打印选项:将
PrintOptions的splitByParcel设为false,DPD会把同一货件的所有包裹标签合并成一个多页PDF文件;若设为true则生成单个包裹的独立PDF,可按需选择。 - 响应处理适配:合并后的多页PDF会在响应的
OutputType中返回完整内容,直接保存即可;若为拆分模式,则需要循环处理每个包裹的标签内容。
修改后的示例代码
public function getLabel(string $serviceMode, int $orderId, int $shippingServiceId): StoreOrdersResponseType { if (Configure::read('override.service_mode')) { Api::dev(); } else { switch ($serviceMode) { case 'live': Api::prod(); break; case 'sandbox': Api::dev(); break; } } $shippingService = $this->shippingServicesTable->get($shippingServiceId); $order = $this->ordersTable->get($orderId); $recipientNames = $this->prepareDpdRecipientNames($order); $authentication = (new Authentication()) ->setDelisId($shippingService->username) ->setAuthToken($shippingService->auth_token) ->setMessageLanguage('de_DE'); // 创建多包裹订单 $storeOrders = (new StoreOrders()) ->setPrintOptions( (new PrintOptions()) ->addPrintOption( (new PrintOption()) ->setPaperFormatA6() ->setOutputFormat(OutputFormatType::pdf()) ) // 关键:设为false合并成多页PDF,设为true则拆分单个包裹PDF ->setSplitByParcel(false) ) ->addOrder( (new ShipmentServiceData()) ->setGeneralShipmentData( (new GeneralShipmentData()) ->setProduct($shippingService->shipping_service_code) ->setSendingDepot($shippingService->depot) // 设置总重量(部分DPD服务要求) ->setMpsWeight(5.5) ->setSender( (new AddressWithType()) ->setAddressTypeCommercial() ->setName1($shippingService->company) ->setName2($shippingService->name) ->setStreet($shippingService->street) ->setHouseNo($shippingService->house_no) ->setCountry($shippingService->country_code) ->setZipCode($shippingService->postcode) ->setCity($shippingService->city) ) ->setRecipient( (new AddressWithType()) ->setAddressType((isset($order->company) ? 'COM' : 'PRV')) ->setName1($recipientNames['name1']) ->setName2($recipientNames['name2']) ->setStreet($order->street) ->setHouseNo($order->house_no) ->setCountry($order->country_code) ->setZipCode($order->postcode) ->setCity($order->city) ) // 共用货件ID:绑定订单ID,确保多包裹属于同一货件 ->setIdentificationNumber((string)$order->id) ) // 添加第一个包裹 ->addParcel( (new Parcel()) ->setWeight(2.5) ->setCustomerReferenceNumber1($order->customer_reference_number1) ->setCustomerReferenceNumber2($order->customer_reference_number2 ?? ' ') ->setAddServiceParcelBox() ) // 添加第二个包裹(可继续添加更多) ->addParcel( (new Parcel()) ->setWeight(3.0) ->setCustomerReferenceNumber1($order->customer_reference_number1) ->setCustomerReferenceNumber2($order->customer_reference_number2 ?? ' ') ->setAddServiceParcelBox() ) ->setProductAndServiceData( (new ProductAndServiceData()) ->setOrderTypeConsignment() ->setFood(false) ) ); $response = Api::me()->storeOrders($authentication, $storeOrders); if ($response instanceof AuthenticationFault) { Log::error('LabelService() Authentication Fault: ' . print_r($response, true), ['scope' => 'dpd']); } elseif ($response instanceof StoreOrdersResponseType) { $currentYear = date('Y'); $currentMonth = date('m'); $baseDir = WWW_ROOT . 'shipping-labels' . DS . $currentYear . DS . $currentMonth; if (!file_exists($baseDir)) { mkdir($baseDir, 0755, true); } $shipmentResponse = $response->getShipmentResponses()[0]; if ( $shipmentResponse instanceof ShipmentResponse && $shipmentResponse->getParcelInformation() instanceof ParcelInformationType && $shipmentResponse->getParcelInformation()->getOutput() instanceof OutputType && $shipmentResponse->getParcelInformation()->getOutput()->getContent() ) { $format = $shipmentResponse->getParcelInformation()->getOutput()->getFormat(); // 用货件ID(订单ID)命名文件,方便识别多包裹标签 $shipmentId = $order->id; $content = $shipmentResponse->getParcelInformation()->getOutput()->getContent(); if ($format == OutputFormatType::TYPE_PDF) { $suffix = ($serviceMode === 'live' ? '' : '_sandbox'); $filePath = $baseDir . DS . 'shipment_' . $shipmentId . $suffix . '.pdf'; file_put_contents($filePath, $content); } // 单独保存每个包裹的追踪号(关联到订单记录) if (method_exists($shipmentResponse, 'getParcelInformationList')) { foreach ($shipmentResponse->getParcelInformationList() as $parcelInfo) { if ($parcelInfo instanceof ParcelInformationType) { $trackingNumber = $parcelInfo->getParcelLabelNumber(); // $this->orderParcelsTable->saveTrackingNumber($orderId, $trackingNumber); } } } } } return $response; }
关键说明
- 货件关联:通过
setIdentificationNumber设置的ID会被DPD用于关联同一货件下的所有包裹,在DPD追踪系统中可通过该ID查询所有包裹状态。 - 打印选项:
splitByParcel参数控制标签生成方式,false生成合并多页PDF,true生成单个包裹独立PDF。 - 追踪号获取:每个包裹有独立追踪号,可通过
ParcelInformationType的getParcelLabelNumber()获取,建议保存到订单关联的包裹记录中,方便后续查询。
内容的提问来源于stack exchange,提问作者magic.77
相关产品推荐
相关产品推荐

