Handling the Create Package Event
CreatePackageEvent
https://{Partner Point of Sale Framework API root}/v1/packages
This endpoint must be built to listen for package creation events from our Delivery Partner Framework for your eClose packages. Your integration must include steps to: validate → process → respond.
Performance Considerations
This is a synchronous webhook to the package creation process and must be executed in a timely fashion. It is expected that the Partner-side processing will complete in under 1 second. Additional time will be given for possible latency or intermittent issues to avoid impacting the customer with failures. There will be a hard timeout that may be adjusted but will not be below 5 seconds.
Validate the Request
Before any data is processed, the request, source, and contents should be confirmed by validating the request signature. See Flow for Validating a Request for details and examples.
Process Request Details
You will need to extract the information from the payload that you are interested in for your user interface and bind recipients to your entity and identity systems before moving on to the next steps. Nothing heavy should be done here in order to meet the performance requirements; defer as much as possible to a later time using the data you persisted.
Build Response
You must provide each recipient's email content and portal link in your response.
The email content will be sent to the recipients when the package is released and when it is ready to sign. If these dates are the same, only one email will be sent. It is generally expected that a link will be in the email allowing the recipient to directly click and log in to your portal. The email content is expected to be in HTML.
We also need a portal URL that will function for non-email cases, such as the closing room application integration. This allows the borrower to directly navigate from the closing room to your portal for signing/reviewing anything that had not been completed earlier. The portal link is expected to have the HTTPS scheme.
Error Handling
Details should contain information on what exactly went wrong without exposing technical details, like stack traces. “POSF” will be the system prefix for Point of Sale Framework representing the Partner Point of Sale system.
Categorization and usage:
- Runtime - Issues we know happen even if the implementation of the integration is correct.
- Implementation - Refers to all issues relating to logic, including the code and configuration of the system.
The implementation issues are not expected to occur in production and represent a bug or misconfiguration of the system. Unfortunately, we cannot positively identify which it is generally: e.g. the request is not signed correctly because a bug in the base64 encoding (a code issue) or because the signing key was put in the system incorrectly (a configuration issue).
Error Scenarios
These errors can also be seen in the createPackageEvent response examples. See Create Package Event API for details.
Runtime Errors
Scenario |
Description |
Status/Code |
Summary |
Example Details |
Unexpected Error |
Something happened that has not been explicitly handled. |
500 / POSF-0000 |
Unexpected error |
|
Maintenance Window |
The system will be unavailable intentionally. |
503 / POSF-0001 |
Service is down for maintenance |
The system is down for planned maintenance and is expected to be back at 2 am Pacific. |
System Outage |
An error occurred internally that causes the system to be unavailable. |
503 / POSF-0002 |
Service Unavailable |
Dependent system is unavailable reference {id}. |
Already executed |
Message was already executed successfully. Special handling - return success payload by regenerating appropriate. This allows retries in case of an intermittent issue. |
200 / NA |
NA |
NA |
Implementation Errors
Scenario |
Description |
Status/Code |
Summary |
Example Details |
Bad Request Input |
Input in the request could not be processed because the format or structure was invalid. |
400 / POSF-0003 |
Bad format - failed input validation |
group.id is required. |
Environment Mismatch |
The elli-environment header value did not match executing environment. |
400 / POSF-0004 |
The environment provided in the request must match execution environment. |
Request Elli-Environment: {expectedEnvironment} is different from executing environment: {actualEnvironment}. |
Missing Required Authentication Header |
One or more of the authentication headers was missing. Header names should be treated as case insensitive. |
401 / POSF-0005 |
Required signing header(s) are missing. |
Elli-SigningKeyId |
Subscription Not Found |
The value provided in the subscription id header is not a recognized Partner Integration id. |
401 / POSF-0006 |
SubscriptionId provided is not authorized for access. |
Elli-SubscriptionId does not exist for Id {subscriptionId}. |
Signing Key Not Found |
The signing key id passed was not found in the provided integration. |
401 / POSF-0007 |
SigningKeyId provided does not exist for integration. |
Elli-SigningKeyId does not exist for Id {signingKeyIdId}. |
Invalid Authentication |
The signature provided does not match that calculated by the resolved signing key. |
401 / POSF-0008 |
Invalid authorization. |
Invalid Elli-Signature. |
Invalid Instance |
The customer instance is not recognized as one supported. |
403 / POSF-0009 |
Instance not supported by integration. |
Instance {instance id} is not supported by subscription {subscription id}. |
Entity Not Found |
An entity referenced in the payload does not exist as expected. In entities being referenced / validated during processing will ideally be shared with IMT during implementation to be documented for diagnostic purposes. |
400 / POSF-0010 |
A referenced entity does not exist. |
The entity {field value} referenced in {field name} cannot be found as expected. |
Already executed |
Message was already executed but should not proceed for some reason. One example would be if you know it was already completed. |
409 / POSF-0011 |
Entity has already been executed and cannot proceed. |
The package {id} on {group.namespace} entity with id of {group.id} has already been completed. |
Delivery Sessions
In order to have a recipient execute a package, you will need to create a Delivery Room session. Creating a Delivery Room session returns a URL you will integrate into your portal.
When processing the event, the data necessary to create a session will need to be stored. The table below shows the mapping of Package Events to Create Session attributes.
Mapping
Package Event |
Create Session |
group.instanceId |
instanceId |
group.namespace |
groupNamespace |
group.id |
groupId |
id |
packageId |
recipients[#].id |
recipientId |
For information about creating a Delivery Room Session, see the Create Session API section.
Request Signing
The Point of Sale Framework must verify the identity of the sender and the integrity of the message. To achieve this, the Delivery Partner needs to validate the signature headers provided on incoming requests. Partners provide the integration signing key when creating a new Point of Sale Delivery Partner integration or updating an existing one.
Symmetric Encryption with a Shared Secret
Partners provide their integration signing key via a manual onboarding process by contacting ICE Mortgage Technology. This enables Partners to establish a shared secret with the POINT OF SALE Framework, with which all inbound and outbound requests for the Partner integration are signed/verified. This mechanism enables Partner integrations to be certain of both the origin of the message (Partner/Point of Sale Framework) and its integrity.
Signing Key
When creating a signing key for an integration, ensure it meets the following complexity requirements:
- A minimum of 32 and a maximum of 64 characters
- At least 1 uppercase letter and 1 lowercase letter
- At least 1 number
- At least 1 special character
Here is the regular expression you can use to test if a signing key meets the complexity requirements mandated above:
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$^&*])([A-Za-z0-9!@#$^&*]){32,64}$
Headers
Partner integrations are expected to sign requests with a valid Elli-Signature and Elli-SigningKeyId, and provide the correct Elli-SubscriptionId and Elli-Environment in their headers. This is how integrations can validate that the webhook message was not tampered with while on route to its destination.
Header |
Description |
Elli-SubscriptionId |
The unique integration Id provided to you during onboarding. |
Elli-SigningKeyId |
Unique Id provided for the key during onboarding or rotation. |
Elli-Signature |
The Base64 encoded SHA256 HMAC that was generated by signing the request body with the signing key, which must be validated as described below to guarantee message integrity. |
Elli-Environment |
The ICE Mortgage Technology software environment from which the request is intended. This will always be “prod” for Partner applications unless otherwise indicated when working with ICE Mortgage Technology engineering. |
Flow for Signing a Request
1. Determine the subscriptionid based on the context.
2. Lookup signingkey and Id, newest key, for the subscription based on the subscriptionid. These values must be stored in a secure location.
3. Build request content.
4. Generate signature value.
· Hash request content using HMAC SHA256 with signingkey from Step 2.
· Encode hash as base64 for final signature value.
· Add custom headers with signed/tracking request properties.
5. Add Elli-SubscriptionId with subscriptionid, from Step 1, as the value.
6. Add Elli-Environment with standard environment token as the value.
7. Add Elli-SigningKeyId header with signingkey id, from Step 2.
8. Add Elli-Signature header with the final encoded hash, from Step 3, as the value.
9. Send the request.
Flow for Validating a Request
1. Validate that all four expected headers exist on the request: Elli-Environment, Elli-SubscriptionId, Elli-SigningKeyId, and Elli-Signature.
2. Extract the Elli-Environment header from the request and validate the environment matches your execution environment.
3. Extract the Elli-SubscriptionId header from the request and validate that it is one of the IntegrationIds given during onboarding, and retrieve the data associated with it such as the signing keys and signing key ids.
4. Extract the Elli-SigningKeyId and use it to look up the appropriate signingkey in your integration (see Step 3).
5. Extract the content from the request and sign it using the key, and apply the signing key using the HMAC SHA256 algorithm to get the 'calculated signature'.
6. Extract the Elli-Signature header and decode to the 'provided signature'. Decode the base64 value to get its numeric representation. If the 'provided signature' and the 'calculated signature' do not match, fail the response.
Examples
CSharp |
byte[] keyByte = encoding.GetBytes(secret); byte[] messageBytes = encoding.GetBytes(message); using (var hmacsha256 = new HMACSHA256(keyByte)) { byte[] hashmessage = hmacsha256.ComputeHash(messageBytes); return Convert.ToBase64String(hashmessage); } |
Node |
var CryptoJS = require(\"crypto-js\");
const
signature = (body, signingKey) => { const hmac = CryptoJS.HmacSHA256(body,
signingKey); const computedSignature =
CryptoJS.enc.Base64.stringify(hmac); return computedSignature; } |
Flow for Signing a Request
- Determine the subscriptionid based on the context.
- Lookup signingkey and Id, newest key, for the subscription based on the subscriptionid. These values must be stored in a secure location.
- Build request content.
- Generate signature value.
Hash request content using HMAC SHA256 with signingkey from Step 2.
Encode hash as base64 for final signature value.
* Add custom headers with signed/tracking request properties. - Add Elli-SubscriptionId with subscriptionid, from Step 1, as the value.
- Add Elli-Environment with standard environment token as the value.
- Add Elli-SigningKeyId header with signingkey id, from Step 2.
- Add Elli-Signature header with the final encoded hash, from Step 3, as the value.
- Send the request.
Flow for Validating a Request
- Validate that all four expected headers exist on the request: Elli-Environment, Elli-SubscriptionId, Elli-SigningKeyId, and Elli-Signature.
- Extract the Elli-Environment header from the request and validate the environment matches your execution environment.
- Extract the Elli-SubscriptionId header from the request and validate that it is one of the IntegrationIds given during onboarding, and retrieve the data associated with it such as the signing keys and signing key ids.
- Extract the Elli-SigningKeyId and use it to look up the appropriate signingkey in your integration (see Step 3.
- Extract the content from the request and sign it using the key, and apply the signing key using the HMAC SHA256 algorithm to get the 'calculated signature'.
- Extract the Elli-Signature header and decode to the 'provided signature'. Decode the base64 value to get its numeric representation. If the 'provided signature' and the 'calculated signature' do not match, fail the response.
Examples
var encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
return Convert.ToBase64String(hashmessage);
}
var CryptoJS = require(\"crypto-js\");
const signature = (body, signingKey) => {
const hmac = CryptoJS.HmacSHA256(body, signingKey);
const computedSignature = CryptoJS.enc.Base64.stringify(hmac);
return computedSignature;
}
Updated about 1 year ago