2. HaynesPro Integration
HaynesPro has rich* SOAP APIs with various end points. To make the journey seamless with VISN for labour time, HaynesPro have made changes to their API.
2.1 HaynesPro web service endpoint
https://uk.haynespro-services.com/Technical/v4/TechnicalProxy.asmx
2.2 HaynesPro sandbox environment
HaynesPro does not have a sandbox environment! We are using a partially-stubbed (only the endppoints we consume) set-up to mimic HaynesPro service. Since HaynesPro web service is SOAP based, it was decided not to create a web service type stub service for a legacy technology. More details about the stub can be found in further sections
2.3 Integration Prerequisites
2.3.1 Hashing payload
Payload passed to HaynesPro has to be hashed using RSA Cryptography. The algorithm is provided by HaynesPro in their technical documentation. This is implemented using dot-net core in VISN. Dotnet was chosen as there is differences in the hashed value that is NOT compatible between nodejs and dotnet. The code for cipher function is in repo repair-serve-dotnet-functions
2.3.2 Machine token
The security of the system is built around allowing only authorised machines to access the data. Consequently each machine is recognised by a unique generated machine token - This is a one off procedure.
- Build request XML data
- hash XML string by using
getCipher
method
<MachineTokenRequestData>
<Username>******</Username>
<Password>******</Password>
<UniqueKey>machine name</UniqueKey>
<RequestedDateTime>date and time</RequestedDateTime>
<ParentDetails>
<Username></Username>
<Password></Password>
<UniqueKey></UniqueKey>
</ParentDetails>
</MachineTokenRequestData>
username
andpassword
can be requested from HaynesPro- date and time is in
roundtrip
format (e.g. 2010-08-15T13:45:30.0900000) - Pass hashed value of MachineTokenRequestData and send it in 'machineTokenRequestKey' as part of the SOAP request
SOAP request
Machine token can be generated by calling GetMachineToken
endpoint
https://uk.haynespro-services.com/Technical/v4/TechnicalProxy.asmx?op=GetMachineToken
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetMachineToken xmlns="http://ws.carwebuk.com/technicalproxyservice/">
<machineTokenRequestKey>string</machineTokenRequestKey>
<clientReference>string</clientReference>
<clientDescription>string</clientDescription>
</GetMachineToken>
</soap:Body>
</soap:Envelope>
clientReference
is digitalINNKclientDescription
any string
SOAP response
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<GetMachineTokenResponse xmlns="http://ws.carwebuk.com/technicalproxyservice/">
<GetMachineTokenResult>string</GetMachineTokenResult>
</GetMachineTokenResponse>
</soap12:Body>
</soap12:Envelope>
2.3.3 Session Token
Before making any further calls to the API, a valid session token is required. Session token should not be used between enquiries. A new session token will be generated and saved for every new enquiry created in VISN.
- Build request XML data
- hash XML string with using
getCipher
method
<SessionTokenRequestData>
<UniqueKey>*machine name*</UniqueKey>
<MachineToken>*machine token generated above*</MachineToken>
<SessionCount>0</SessionCount>
<RequestedDateTime>date and time</RequestedDateTime>
</SessionTokenRequestData>
- Pass hashed value of SessionTokenRequestData and send it in 'sessionTokenRequestKey' as part of the SOAP request
SOAP request
Session token can be generated by calling GetSessionToken
endpoint
https://uk.haynespro-services.com/Technical/v4/TechnicalProxy.asmx?op=GetSessionToken
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetSessionToken xmlns="http://ws.carwebuk.com/technicalproxyservice/">
<sessionTokenRequestKey>string</sessionTokenRequestKey>
<clientReference>string</clientReference>
<clientDescription>string</clientDescription>
<countryCode>string</countryCode>
</GetSessionToken>
</soap:Body>
</soap:Envelope>
SOAP response
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetSessionTokenResponse xmlns="http://ws.carwebuk.com/technicalproxyservice/">
<GetSessionTokenResult>string</GetSessionTokenResult>
</GetSessionTokenResponse>
</soap:Body>
</soap:Envelope>
2.3.4 Get RepairTimeTypeId
For every vehicle specification that HaynesPro hold, an internal identifier is created. This Id will be used for future calls for queries related to this vehicle.
Build request XML data
hash XML string by using
getCipher
method<CallRequestData>
<MachineToken>${machineInfo.token}</MachineToken>
<SessionToken>${sessionToken}</SessionToken>
<RequestedDateTime>${new Date().toISOString()}</RequestedDateTime>
</CallRequestData>
RepairTimeTypeId is obtained by calling GetRepairtimeTypes
endpoint
https://uk.haynespro-services.com/Technical/v4/TechnicalProxy.asmx?op=GetRepairtimeTypes
SOAP request
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetRepairtimeTypes xmlns="http://ws.carwebuk.com/technicalproxyservice/">
<callRequestKey>string</callRequestKey>
<clientReference>string</clientReference>
<clientDescription>string</clientDescription>
<lookupType>VRM or VIN or TechnicalId</lookupType>
<identifierValue>string</identifierValue>
<countryCode>string</countryCode>
<languageCode>string</languageCode>
</GetRepairtimeTypes>
</soap:Body>
</soap:Envelope>
Key | Value |
---|---|
callRequestKey | hashed CallRequestData |
clientReference | digitalINNK |
clientDescription | brief description |
lookupType | VRM |
identifierValue | VRM of the vehicle |
countryCode | GBR |
languageCode | EN |
SOAP response
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetRepairtimeTypesResponse xmlns="http://ws.carwebuk.com/technicalproxyservice/">
<GetRepairtimeTypesResult />
</GetRepairtimeTypesResponse>
</soap:Body>
</soap:Envelope>
Following two are the possible scenarios
- Vehicle is found in HaynesPro
When HaynesPro has the details of the vehicle, a response with vehicle details is returned like make, model, type etc. We will need repairtimeTypeId (a unique identifier for this spec). This value is nested in the response. response > data > GetRepairtimeTypesResult > TechnicalData > repairtimeTypeId
- Vehicle is NOT found in HaynesPro
When HaynesPro does not have details of the vehicle (this may happen when the vehicle is very new or data is not available from the OEMs), an error response is returned. The details of the error can be obtained from error > data > message
2.3.5 Save Session token and RepairTimeTypeId
Since we have the Session token and RepairTimeTypeId that we will use this for all the future calls, it is a good idea to store it for this enquiry.
- Save GetSessionTokenResult value (a guid) in
/ancillary/enquiries/sessionTokens
collection - Create a new document with enquiryId as the document Id and save the the value in a document
/ancillary/enquiries/sessionTokens/{enquiryId}
{
repairtimeTypeId: integer value
sessionHash: GUID obtained by GetSessionToken request
}
2.3.6 getRepairRenewalNodes
For every vehicle specification that HaynesPro holds, it assigns an internal identifier which is integrated into visn by fetching (section 2.3.4 ) and saving (section #235-save-session-token-and-repairtimetypeid).
Read unique vehicle identifier (repairtimeTypeId)
Read Session Token
Build request XML data
hash XML string with using
getCipher
method<CallRequestData>
<MachineToken>${machineInfo.token}</MachineToken>
<SessionToken>${sessionToken}</SessionToken>
<RequestedDateTime>${new Date().toISOString()}</RequestedDateTime>
</CallRequestData>
RepairRenewalNodes are obtained by calling GetRepairRenewalNodes
endpoint
https://uk.haynespro-services.com/Technical/v4/TechnicalProxy.asmx?op=GetRepairRenewalNodes
SOAP request
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetRepairRenewalNodes xmlns="http://ws.carwebuk.com/technicalproxyservice/">
<callRequestKey>string</callRequestKey>
<clientReference>string</clientReference>
<clientDescription>string</clientDescription>
<lookupType>VRM or VIN or TechnicalId</lookupType>
<identifierValue>string</identifierValue>
<countryCode>string</countryCode>
<languageCode>string</languageCode>
<typeId>int</typeId>
</GetRepairRenewalNodes>
</soap:Body>
</soap:Envelope>
Key | Value |
---|---|
callRequestKey | hashed CallRequestData |
clientReference | digitalINNK |
clientDescription | brief description |
lookupType | VRM |
identifierValue | VRM of the vehicle |
countryCode | GBR |
languageCode | EN |
typeId | repairtimeTypeId |
SOAP response
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetRepairRenewalNodesResponse xmlns="http://ws.carwebuk.com/technicalproxyservice/">
<GetRepairRenewalNodesResult>
<RepairNode>
<Description xmlns="http://ws.carweb.com/technicalservice/">string</Description>
<RepairNodeId xmlns="http://ws.carweb.com/technicalservice/">string</RepairNodeId>
</RepairNode>
<RepairNode>
<Description xmlns="http://ws.carweb.com/technicalservice/">string</Description>
<RepairNodeId xmlns="http://ws.carweb.com/technicalservice/">string</RepairNodeId>
</RepairNode>
</GetRepairRenewalNodesResult>
</GetRepairRenewalNodesResponse>
</soap:Body>
</soap:Envelope>
Following two are the possible result
- Descriptions are found in HaynesPro
When HaynesPro has the nodes for the identifier, a response with nodes is returned as an array with elements with values description, node id etc. We need RepairNode collection which is nested in the response. response > data > GetRepairRenewalNodesResult > RepairNode
The collection obtained may also be empty if Haynes has vehicle data but repair descriptions are yet to be added. We need to treat them as empty
- Descriptions are NOT found in HaynesPro
When HaynesPro does not have descriptions for the vehicle (this may happen when the vehicle is very new or data is not available from OEMs), an error response is returned. The details of the error can be obtained from error > root > Envelope > Body > Fault > detail > Error
2.3.7 getMaintenanceSystemsV5
For every vehicle specification that HaynesPro hold, it assigns an internal identifier which is integrated into visn by fetching (section 2.3.4) and saving (section 2.3.5).
Read unique vehicle identifier (repairtimeTypeId)
Read Session Token
Build request XML data
hash XML string with using
getCipher
method<CallRequestData>
<MachineToken>${machineInfo.token}</MachineToken>
<SessionToken>${sessionToken}</SessionToken>
<RequestedDateTime>${new Date().toISOString()}</RequestedDateTime>
</CallRequestData>
Maintenance Systems are obtained by calling GetMaintenanceSystemsV5
endpoint
https://uk.haynespro-services.com/Technical/v4/TechnicalProxy.asmx?op=GetMaintenanceSystemsV5
SOAP request
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetMaintenanceSystemsV5 xmlns="http://ws.carwebuk.com/technicalproxyservice/">
<callRequestKey>string</callRequestKey>
<clientReference>string</clientReference>
<clientDescription>string</clientDescription>
<lookupType>VRM or VIN or TechnicalId</lookupType>
<identifierValue>string</identifierValue>
<countryCode>string</countryCode>
<languageCode>string</languageCode>
<measurementType>Metric or Imperial</measurementType>
<includeServiceTimes>boolean</includeServiceTimes>
<repairTypeID>int</repairTypeID>
<vehicleType>CAR or TRUCK</vehicleType>
</GetMaintenanceSystemsV5>
</soap:Body>
</soap:Envelope>
Key | Value |
---|---|
callRequestKey | hashed CallRequestData |
clientReference | digitalINNK |
clientDescription | brief description |
lookupType | VRM |
identifierValue | VRM of the vehicle |
countryCode | GBR |
languageCode | EN |
measurementType | Imperial |
includeServiceTimes | true |
vehicleType | CAR |
SOAP response
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetMaintenanceSystemsV5Response xmlns="http://ws.carwebuk.com/technicalproxyservice/">
<GetMaintenanceSystemsV5Result />
</GetMaintenanceSystemsV5Response>
</soap:Body>
</soap:Envelope>
Following two are the possible result
- Maintenance Descriptions are found in HaynesPro
When HaynesPro has the nodes for the identifier, a response with maintenance descriptions are returned as array whose contents are like id, name, generalCriterias,maintenancePeriods, status etc. We need ExtMaintenanceSystemV5 collection which is nested in the response. response > data > GetMaintenanceSystemsV5Result > TechnicalData > ExtMaintenanceSystemV5
The collection obtained may also be empty, if haynes has vehicle data but repair descriptions are yet to be added. we need to treat them as empty
- Maintenance Descriptions are NOT found in HaynesPro
When HaynesPro does not have maintenance descriptions for the vehicle (this may happen when the vehicle is very new or data is not available from OEMs), an error response is returned. The details of the error can be obtained from error > root > Envelope > Body > Fault > detail > Error
Status: Accepted
Category: Protected
Authored By: Vishwa on Mar 22, 2023