Skip to content

Developer notes

Technical reference for developers who customize DPD Shipping Labels & Pickup Points. Every operation and field below is taken from the official WSDL / XSD files saved in tests/fixtures/wsdl (downloaded from the DPD stage system, 7 November 2026). What the documentation does not state is marked unverified; see Conformance.

Item Value
Add-on id kv_dpd
Function prefix fn_kv_dpd_
Language variables kv_dpd.*
CSS scope .kv-dpd, .kv-dpdp (checkout picker)
PHP namespace Tygh\Addons\KvDpd
Preset shipping (generated by kv new --kind integration)
Class Role
Client\BaseClient HTTP (cURL, TLS verification, timeouts), error mapping (decodeError hook), masked logging
Client\Soap SOAP 1.1 envelope builder (ordered arrays, schema order) and parser (namespace prefixes removed, repeated elements as lists), fault decoding
Client\Api The five services: token() (LoginService), storeOrders(), findParcelShops(), findByGeo(), track(), ping()
Client Client per company, the connection test
Accounts, Secret Credentials (test and live) sealed with AES-256-GCM; one account per store owner or per vendor; token cache with the depot of the login
Config, Access Settings, owner mode, who may see and manage what
Shipments Payload mapping order -> storeOrders, label storage, return label, tracking mapping, local cancel
Points Parcel shop of an order: search, normalise, validate, store
Installer, RateCalculator Shipping services (7) and the merchant’s own rates (the web services have no price operation)
Queue, Jobs, JobException, Log Job queue (back-off 5 min / 15 min / 1 h / 3 h / 12 h), recurring tracking, log

All calls are POST <services root>/<Service>/<Version> with Content-Type: text/xml; charset=utf-8 and SOAPAction: "http://dpd.com/common/service/<Service>/<major.minor>/<operation>". Body elements are in the namespace http://dpd.com/common/service/types/<Service>/<major.minor>; children are unqualified. The header authentication is in http://dpd.com/common/service/types/Authentication/2.0.

Operation Request fields used Response fields used
LoginService/V2_0 getAuth delisId, password, messageLanguage (en_US) return.authToken (max 64), return.depot, return.customerUid, return.delisId
ShipmentService/V4_5 storeOrders printOptions.printOption(outputFormat, paperFormat); order.generalShipmentData(mpsCustomerReferenceNumber1, identificationNumber, sendingDepot, product, mpsWeight, mpsExpectedSendingDate, sender, recipient, softwareVersion); order.parcels(customerReferenceNumber1, volume, weight, returns); order.productAndServiceData(orderType, parcelShopDelivery(parcelShopId, parcelShopPudoId, parcelShopNotification(channel, value, language)), predict(channel, value, language), international(parcelType, customsAmount, customsCurrency, customsInvoice, customsInvoiceDate, numberOfArticle, reasonForExport, additionalInvoiceLines(customsInvoicePosition, quantityItems, customsContent, customsAmountLine, customsOriginAlphanumeric, customsGrossWeight))); addresses: name1, name2, street, houseNo, state, country, zipCode, city, customerNumber, contact, phone, email, addressType, additionalInfo2 orderResult.output(format, content), shipmentResponses(identificationNumber, mpsId, parcelInformation(parcelLabelNumber, dpdReference, output(format, content)), faults(faultCode, message))
ParcelShopFinderService/V5_0 findParcelShops country, zipCode, city, street, limit, availabilityDate, hideClosed parcelShop(parcelShopId, pudoId, company, street, houseNo, country, zipCode, city, latitude, longitude, openingHours(weekday, openMorning, closeMorning, openAfternoon, closeAfternoon))
ParcelShopFinderService/V5_0 getAvailableServices none (connection test) services
ParcelShopFinderService/V5_0 findParcelShopsByGeoData longitude, latitude, limit (Api::findByGeo, not used by the checkout) as findParcelShops
ParcelLifeCycleService/V2_0 getTrackingData parcelLabelNumber trackingresult.statusInfo(status, label, location, date, statusHasBeenReached, isCurrentStatus, normalItems, importantItems, errorItems), shipmentInfo

SOAP faults (HTTP 500) are decoded from detail: authenticationFault(errorCode -1 | -2, errorMessage), LoginException(errorCode, message), dataFault / systemFault(errorCode, message). The exact fault encoding is read from the XSD; no fault was captured from the real service (unverified). An authentication fault leads to one new login and one repeat of the call.

Topic Rule
Products dpd_classic and dpd_pickup -> CL; dpd_830 -> E830; dpd_1200 -> E12; dpd_1800 -> E18; dpd_max -> MAX; dpd_express -> IE2
Weight Parcel::units() = kg x 100 (units of 10 g, per the example “300 equals 3kg”); unverified, see Conformance
Volume Parcel::volume() = LLLWWWHHH, minimum 1001001
Money Parcel::cents() = amount x 100 without separator (customsAmount, customsAmountLine), invoice currency EUR
Element order XSD sequences are ordered: Parcel::sortAddress() orders the address fields; the payload arrays are written in schema order. The unit tests validate every request against the XSD
Cash on delivery no field exists since 4.4: refused, never sent
Cancel no operation exists: local only
Table Purpose
?:kv_dpd_accounts Credentials per company (password sealed), last connection check, token cache (with depot)
?:kv_dpd_log Log
?:kv_dpd_jobs Queue
?:kv_dpd_shipments Labels and tracking (provider_ref and tracking_number = parcel label number, courier_number = mpsId, extra_docs = return label)
?:kv_dpd_points Parcel shop per order (carrier_id = parcelShopId, point_id = pudoId)

PHP: change_order_status_post (label at status), get_order_info (attaches the parcel shop), place_order / place_suborders (store the shop), delete_order, template_document_order_context_init (shop in order documents). Templates: backend orders:tabs_extra, addons:manage, addons:tabs_content, index:styles; storefront checkout:shipping_method (picker), orders:totals_shipping (shop on the order page), index:scripts, index:styles. The picker is an AJAX POST only (kv_dpd.locations, kv_dpd.point_select) and never cached, so the full page cache stays safe.

The base URL can be overridden for tests in config.local.php (development only; the add-on appends /services):

$config['kv_dpd_base_url'] = 'http://127.0.0.1:11852';

php -S 127.0.0.1:11852 tests/mock-server/server.php starts a local stand-in that validates every request against the official XSD files; node tests/e2e/e2e.mjs runs the HTTP end-to-end test against it; php tests/unit.php runs the unit tests (also on php81 and php83). This proves the add-on against the specification, not against DPD.

Admin templates live in design/backend/templates/addons/kv_dpd/. Do not edit them in a store; they are replaced on update.