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


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);

}

 

 

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

  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

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;
}