Advanced Identity Cloud

PingOne Verify Completion Decision node

The PingOne Verify Evaluation node determines the completion status of the most recent identity verification transaction for a PingOne user.

The node checks the previous identity verification transaction for the user and returns an outcome based on the verification status.

You can use this node to prevent users from repeatedly having to verify their identity by checking their most recent verification transaction. You can also determine if a transaction is already in progress, to prevent multiple ongoing transactions.

For further customization of behavior, use a PingOne Verify Completion Decision script to evaluate the verification transactions started for the specified PingOne user, and the associated metadata. The script can then add additional context to the journey, or perform additional business logic, dependent on the verification metadata.

Compatibility

Product Compatible?

Advanced Identity Cloud

Yes 1

PingAM (self-managed)

Yes

Ping Identity Platform (self-managed)

Yes

1 Currently available only in the rapid release channel.

Inputs

This node requires that the user has an account in the PingOne environment. It requires that the journey stores the PingOne user ID for the account in the shared state variable named pingOneUserId.

Use a PingOne Identity Match node to populate the shared state with the user’s PingOne ID.

Dependencies

This node requires a PingOne Worker Service configuration so that it can connect to your PingOne instance and send it the necessary data to perform PingOne Verify evaluations as part of the journey.

You can find information on the properties used by the service in PingOne Worker service.

Configuration

Property Usage

PingOne Worker Service ID

The ID of the PingOne worker service for connecting to PingOne.

Use a Script to process Verify Transactions

When enabled, use a PingOne Verify Completion Decision script to process verification transaction data relating to the user.

Example verification transaction data
{
    "_links": {
        "self": {
            "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/36ff33da-cba7-4d46-bedc-8b242889d461/verifyTransactions"
        }
    },
    "_embedded": {
        "verifyTransactions": [
            {
                "_links": {
                    "self": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/36ff33da-cba7-4d46-bedc-8b242889d461/verifyTransactions/029ea878-2618-4067-b7e3-922591e6b55f"
                    },
                    "environment": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
                    },
                    "user": {
                        "href": "https://api.pingone.com/v1/users/36ff33da-cba7-4d46-bedc-8b242889d461"
                    }
                },
                "id": "029ea878-2618-4067-b7e3-922591e6b55f",
                "transactionStatus": {
                    "status": "APPROVED_NO_REQUEST"
                },
                "createdAt": "2022-02-17T20:32:22.052Z",
                "updatedAt": "2022-02-17T20:32:58.711Z",
                "expiresAt": "2022-02-17T21:02:58.711Z"
            },
            {
                "_links": {
                    "self": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/36ff33da-cba7-4d46-bedc-8b242889d461/verifyTransactions/cca479e7-d130-4e3c-b888-74ba1920f59a"
                    },
                    "environment": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
                    },
                    "user": {
                        "href": "https://api.pingone.com/v1/users/36ff33da-cba7-4d46-bedc-8b242889d461"
                    }
                },
                "id": "cca479e7-d130-4e3c-b888-74ba1920f59a",
                "transactionStatus": {
                    "status": "REQUESTED"
                },
                "qrUrl": "https://api.pingone.com/v1/idValidations/shortcode/086645084110/qr",
                "verificationCode": "086645084110",
                "createdAt": "2022-02-17T20:23:58.662Z",
                "updatedAt": "2022-02-17T20:23:58.662Z",
                "expiresAt": "2022-02-17T20:53:58.662Z"
            },
            {
                "_links": {
                    "self": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/36ff33da-cba7-4d46-bedc-8b242889d461/verifyTransactions/52c9bf9a-0687-4e01-85d1-9caa9bb387ee"
                    },
                    "environment": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
                    },
                    "user": {
                        "href": "https://api.pingone.com/v1/users/36ff33da-cba7-4d46-bedc-8b242889d461"
                    }
                },
                "id": "52c9bf9a-0687-4e01-85d1-9caa9bb387ee",
                "transactionStatus": {
                    "status": "REQUESTED"
                },
                "qrUrl": "https://api.pingone.com/v1/idValidations/shortcode/008299320746/qr",
                "verificationCode": "008299320746",
                "createdAt": "2022-02-17T20:23:08.887Z",
                "updatedAt": "2022-02-17T20:23:08.887Z",
                "expiresAt": "2022-02-17T20:53:08.887Z"
            },
            {
                "_links": {
                    "self": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/36ff33da-cba7-4d46-bedc-8b242889d461/verifyTransactions/dd5a6d4f-a999-4819-b107-85a0a10138c6"
                    },
                    "environment": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
                    },
                    "user": {
                        "href": "https://api.pingone.com/v1/users/36ff33da-cba7-4d46-bedc-8b242889d461"
                    }
                },
                "id": "dd5a6d4f-a999-4819-b107-85a0a10138c6",
                "transactionStatus": {
                    "status": "REQUESTED"
                },
                "createdAt": "2021-12-09T13:45:34.882Z",
                "updatedAt": "2021-12-09T13:45:34.882Z",
                "expiresAt": "2022-12-09T14:15:34.882Z"
            },
            {
                "_links": {
                    "self": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/36ff33da-cba7-4d46-bedc-8b242889d461/verifyTransactions/bfc414cb-a1b4-46b8-b622-3d806a85002f"
                    },
                    "environment": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
                    },
                    "user": {
                        "href": "https://api.pingone.com/v1/users/36ff33da-cba7-4d46-bedc-8b242889d461"
                    }
                },
                "id": "bfc414cb-a1b4-46b8-b622-3d806a85002f",
                "transactionStatus": {
                    "status": "REQUESTED"
                },
                "createdAt": "2021-12-08T21:34:52.424Z",
                "updatedAt": "2021-12-08T21:34:52.424Z",
                "expiresAt": "2022-12-08T22:04:52.424Z"
            },
            {
                "_links": {
                    "self": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/36ff33da-cba7-4d46-bedc-8b242889d461/verifyTransactions/b21db4c4-01c5-47b5-a2a9-3d8df21d189b"
                    },
                    "environment": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
                    },
                    "user": {
                        "href": "https://api.pingone.com/v1/users/36ff33da-cba7-4d46-bedc-8b242889d461"
                    }
                },
                "id": "b21db4c4-01c5-47b5-a2a9-3d8df21d189b",
                "transactionStatus": {
                    "status": "APPROVED_NO_REQUEST"
                },
                "createdAt": "2021-12-07T21:33:22.088Z",
                "updatedAt": "2021-12-07T21:45:22.944Z",
                "expiresAt": "2022-12-07T22:15:22.944Z"
            },
            {
                "_links": {
                    "self": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/36ff33da-cba7-4d46-bedc-8b242889d461/verifyTransactions/e44ebfe2-6a76-4ffa-ac35-d71ee9365e57"
                    },
                    "environment": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
                    },
                    "user": {
                        "href": "https://api.pingone.com/v1/users/36ff33da-cba7-4d46-bedc-8b242889d461"
                    }
                },
                "id": "e44ebfe2-6a76-4ffa-ac35-d71ee9365e57",
                "transactionStatus": {
                    "status": "APPROVED_NO_REQUEST"
                },
                "createdAt": "2021-12-07T19:55:16.630Z",
                "updatedAt": "2021-12-07T21:31:26.835Z",
                "expiresAt": "2022-12-07T22:01:26.835Z"
            },
            {
                "_links": {
                    "self": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/36ff33da-cba7-4d46-bedc-8b242889d461/verifyTransactions/fc695b11-93a4-48bb-9ec3-ff5738e3818c"
                    },
                    "environment": {
                        "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
                    },
                    "user": {
                        "href": "https://api.pingone.com/v1/users/36ff33da-cba7-4d46-bedc-8b242889d461"
                    }
                },
                "id": "fc695b11-93a4-48bb-9ec3-ff5738e3818c",
                "transactionStatus": {
                    "status": "REQUESTED"
                },
                "createdAt": "2021-12-07T18:36:48.156Z",
                "updatedAt": "2021-12-07T18:36:48.156Z",
                "expiresAt": "2021-12-07T19:06:48.153Z"
            }
        ]
    },
    "size": 8
}

For more information on verification transaction data, refer to Read All Verify Transactions.

Manage Verify Transactions Script

The name of the script to process the JSON containing verification transactions relating to the user.

The script must be of type PingOne Verify Completion Decision.

Refer to Example scripts.

Capture failure

Capture the details in shared state if a failure occurs.

The node stores the details in a variable named pingOneVerifyCompletionFailureReason.

Default: False

Example:

{
  "code": "VERIFY_COMPLETION_SCRIPT_ERROR",
  "message": "Error evaluating the verify completion decision script.",
  "exception": "",
}

Outputs

The node is non-interactive and does not send a callback to the client.

If the node discovers that the user’s most recent Verify transaction is not yet complete, it adds the ID of the transaction to the shared state, in a variable named pingOneVerifyTransactionId. The PingOne Verify Evaluation node can use this value to continue the existing Verify evaluation, rather than start a brand new one.

If you select Capture failure, the node stores any error response in a shared state variable named pingOneVerifyCompletionFailureReason.

If you enable the Use a Script to process Verify Transactions property, the script you specify can add values to the shared state, as required.

Outcomes

Success

The user successfully completed their most recent PingOne Verify evaluation.

Failure

The user did not successfully complete their most recent PingOne Verify evaluation, or an error occurred.

Expired

The user’s most recent PingOne Verify evaluation timed out. Usually this happens when a user starts a verification transaction, but does not complete it within the time limit.

Not Started

The user’s most recent PingOne Verify evaluation has not yet started.

Not Completed

The user’s most recent PingOne Verify evaluation has started, but not yet completed.

Examples

Example journey

The following example journey leverages PingOne Verify to perform user identity verification.

Example PingOne Verify journey
Figure 1. Example PingOne Verify journey
  • The user enters their credentials, which the Data Store Decision node then verifies against the identity store.

  • 1 The PingOne Identity Match node checks PingOne for a matching user.

  • 2 If a user is found, the PingOne Verify Completion Decision node checks the user’s most recent verification transaction to determine the status:

    Success

    The user successfully completed the most recent PingOne Verify transaction, so continue directly to the Success node, completing the authentication journey.

    Not Completed

    The user has an existing PingOne Verify transaction in progress, so continue the journey to resume the existing verification transaction.

    The node adds the user’s existing transaction ID to the shared node state in a variable named pingOneVerifyTransactionId.

    Not Started / Failure / Expired

    The user either does not have an existing transaction (Not Started), or did not successfully complete the most recent PingOne Verify transaction, or it expired, so continue the journey to start a new verification transaction.

  • 3 If a user is not found, the PingOne Create User node creates a new user in PingOne.

  • 4 The PingOne Verify Evaluation node starts a new PingOne Verify evaluation, or continues an existing one if pingOneVerifyTransactionId is present in the shared node state, and either completes or fails the journey based on the result.

Example scripts

The following example PingOne Verify Completion Decision scripts demonstrate some use cases for this node:

Example 1

Check the status of the user’s most recent Verify transaction and that the ID used was a driving license.

Show example script
/** ******************************************************************
 *
 * The following script checks the status of the user's most recent
 * identity check, and ensures the ID used was a driver's license.
 *
 * Global node variables accessible within this scope:
 * 1. `sharedState` provides access to auth tree state attributes
 * 2. `verifyTransactionsHelper` provides access to verify transactions
 * 3. `outcome` variable maps to auth tree node outcomes; values are
 *    'successOutcome', 'notStartedOutcome', 'notCompletedOutcome',
 *    'expiredOutcome', or 'failureOutcome'.
 * ******************************************************************/

// Retrieve the user's latest verified transaction.
var result = verifyTransactionsHelper.getLastVerifyTransaction();
if (result != null) {
    var lastTransaction = JSON.parse(result);
    if (lastTransaction.hasOwnProperty("transactionStatus")) {
        // Get the status of the transaction.
        var status = lastTransaction.transactionStatus.status;
        // Determine the document type and verify if it is a Driver's License.
        var verifiedDocuments = lastTransaction.verifiedDocuments;
        if (status == "SUCCESS" && verifiedDocuments.includes("driver_license")) {
            outcome = "successOutcome";
        } else {
            outcome = "failureOutcome";
        }
    } else {
        outcome = "notStartedOutcome";
    }
}
Example 2

Check the ID used in the user’s most recent Verify transaction and that their age is 18 or over.

This data is available for a short timeframe after the verification.

Usually 30 minutes after PingOne Verify reaches its verification decision.

Show example script
/** ******************************************************************
 *
 * The following script checks the ID used in the user's most recent
 * identity check, and that their age is 18 or over.
 *
 * Note:
 * This data is available for a short timeframe after the verification.
 * Usually 30 minutes after a verification decision is reached.
 *
 * Global node variables accessible within this scope:
 * 1. `sharedState` provides access to auth tree state attributes
 * 2. `verifyTransactionsHelper` provides access to verify transactions
 * 3. `outcome` variable maps to auth tree node outcomes; values are
 *    'successOutcome', 'notStartedOutcome', 'notCompletedOutcome',
 *    'expiredOutcome', or 'failureOutcome'.
 * ******************************************************************/

// Retrieve the user's latest verified transaction.
var result = verifyTransactionsHelper.getLastVerifyTransaction();
if (result != null) {
    var lastTransaction = JSON.parse(result);
    if (lastTransaction.hasOwnProperty("id")) {
        // Obtain the ID of the last transaction.
        var lastTransactionId = lastTransaction.id;
        // Get the verified data for the Government ID provided by the user.
        var verifiedDataResult = verifyTransactionsHelper.getVerifiedDataByType(lastTransactionId, "GOVERNMENT_ID");
        // Determine the age of the user.
        if (verifiedDataResult != null) {
            var verifiedData = JSON.parse(verifiedDataResult);
            var dateString = verifiedData._embedded.verifiedData[0].data.birthDate;
            if (dateString != null && dateString.trim() != "") {
                var birthDate = new Date(dateString + "T00:00:01");
                var currentDate = new Date().getTime();
                var difference = currentDate - birthDate;
                var currentAge = Math.floor(difference / (1000 * 60 * 60 * 24 * 365.25));
                if (currentAge >= 18) {
                    outcome = "successOutcome";
                } else {
                    outcome = "failureOutcome";
                }
            } else {
                outcome = "failureOutcome";
            }
        } else {
            outcome = "notCompletedOutcome";
        }
    } else {
        outcome = "notStartedOutcome";
    }
} else {
    outcome = "notStartedOutcome";
}
Example 3

Check the user’s most recent Verify transaction to obtain the expiration date for the Government ID provided.

The node stores this information in a variable named governmentIdExpireDate in the shared state, but you could also store it in a user attribute to determine when to perform the next identity verification.

This data is available for a short timeframe after the verification.

Usually 30 minutes after PingOne Verify reaches its verification decision.

Show example script
/** ******************************************************************
 *
 * The following script checks the user's most recent Verify transaction
 * to obtain the expiration date for the Government ID provided.
 *
 * This information is stored in a variable named `governmentIdExpireDate`
 * in the shared state, but could also be stored as a user attribute
 * to determine when to perform the next identity verification.
 *
 * Note:
 * This data is available for a short timeframe after the verification.
 * Usually 30 minutes after a verification decision is reached.
 *
 * Global node variables accessible within this scope:
 * 1. `sharedState` provides access to auth tree state attributes
 * 2. `verifyTransactionsHelper` provides access to verify transactions
 * 3. `outcome` variable maps to auth tree node outcomes; values are
 *    'successOutcome', 'notStartedOutcome', 'notCompletedOutcome',
 *    'expiredOutcome', or 'failureOutcome'.
 * ******************************************************************/

// Retrieve the user's latest verified transaction.
var result = verifyTransactionsHelper.getLastVerifyTransaction();
if (result != null) {
    var lastTransaction = JSON.parse(result);
    if (lastTransaction.hasOwnProperty("id")) {
        // Obtain the ID of the last transaction.
        var lastTransactionId = lastTransaction.id;
        // Get the verified data for the Government ID provided by the user.
        var verifiedDataResult = verifyTransactionsHelper.getVerifiedDataByType(lastTransactionId, "GOVERNMENT_ID");
        // Get the expire date and set on shared state.
        if (verifiedDataResult != null) {
            var verifiedData = JSON.parse(verifiedDataResult);
            var expireDate = verifiedData._embedded.verifiedData[0].data.expirationDate;
            if (expireDate != null && expireDate.trim() != "") {
                sharedState.put("governmentIdExpireDate", expireDate);
                outcome = "successOutcome";
            } else {
                outcome = "failureOutcome";
            }
        } else {
            outcome = "notCompletedOutcome";
        }
    } else {
        outcome = "notStartedOutcome";
    }
} else {
    outcome = "notStartedOutcome";
}
Example 4

Check that the user has at least one successful identity verification in the past 365 days.

Show example script
/** ******************************************************************
 *
 * The following script checks that the user has at least one successful
 * identity verification in the past 365 days.
 *
 * Global node variables accessible within this scope:
 * 1. `sharedState` provides access to auth tree state attributes
 * 2. `verifyTransactionsHelper` provides access to verify transactions
 * 3. `outcome` variable maps to auth tree node outcomes; values are
 *    'successOutcome', 'notStartedOutcome', 'notCompletedOutcome',
 *    'expiredOutcome', or 'failureOutcome'.
 * ******************************************************************/

// Retrieve all transactions for the user
var result = verifyTransactionsHelper.getAllVerifyTransactions();
if (result != null) {
    var allTransactions = JSON.parse(result);
    if (allTransactions != null && allTransactions.length > 0) {
        // Loop through the transactions to find a successful verification within the last 12 months.
        var verifyTransactions = allTransactions._embedded.verifyTransactions;
        var found = false;
        for (var i = 0; i < verifyTransactions.length; i++) {
            var transaction = verifyTransactions[i];
            // Get the status of the transaction.
            var status = transaction.transactionStatus.status;
            // If status is success, verify if it is still valid
            if (status == "SUCCESS") {
                // Calculate the number of days
                var dateString = transaction.createdAt;
                var createdDate = new Date(dateString);
                var currentDate = new Date().getTime();
                var difference = Math.abs(createdDate - currentDate);
                var numDaysBetween = difference / (1000 * 60 * 60 * 24);
                if (numDaysBetween <= 365) {
                    outcome = "successOutcome";
                    break;
                } else {
                    outcome = "expiredOutcome";
                }
                found = true;
            }
        }
        // No successful transaction found
        if (found == false) {
            outcome = "failureOutcome";
        }
    } else {
        outcome = "notStartedOutcome";
    }
} else {
    outcome = "notStartedOutcome";
}
Example 5

Check the user’s most recent Verify transaction to review the biographic match results.

The script uses the Failure outcome if the match confidence for any attribute is anything other than HIGH.

Show example script
/** ******************************************************************
 *
 * The following script checks the user's last identity verification to
 * review the "Biographic Match" results.
 *
 * The script uses the failure outcome if the match confidence for any
 * attribute is below `HIGH`.
 *
 * Global node variables accessible within this scope:
 * 1. `sharedState` provides access to auth tree state attributes
 * 2. `verifyTransactionsHelper` provides access to verify transactions
 * 3. `outcome` variable maps to auth tree node outcomes; values are
 *    'successOutcome', 'notStartedOutcome', 'notCompletedOutcome',
 *    'expiredOutcome', or 'failureOutcome'.
 * ******************************************************************/

// Retrieve the user's latest verified transaction.
var result = verifyTransactionsHelper.getLastVerifyTransaction();
if (result != null) {
    var lastTransaction = JSON.parse(result);
    if (lastTransaction.hasOwnProperty("id")) {
        // Obtain the ID of the last transaction.
        var lastTransactionId = lastTransaction.id;
        // Get all the metadata.
        var allMetadataResult = verifyTransactionsHelper.getAllMetadata(lastTransactionId);
        // Loop through the metadata to find the biographic match results.
        var biographicMatchResults;
        if (allMetadataResult != null) {
            var allMetadataJson = JSON.parse(allMetadataResult);
			var allMetadata = allMetadataJson._embedded.metaData;
            for (var i = 0; i < allMetadata.length; i++) {
                var metadata = allMetadata[i];
                var type = metadata.type;
                var status = metadata.status;
                if (type == "BIOGRAPHIC_MATCH" && status == "SUCCESS") {
                    biographicMatchResults = metadata.data.biographic_match_results;
                    break;
                }
            }
        } else {
            outcome = "failureOutcome";
        }
        // Validate the biographic match results
        if (biographicMatchResults != null && biographicMatchResults.length > 0) {
            var success = true;
            for (var j = 0; j < biographicMatchResults.length; j++) {
                var match = biographicMatchResults[j].match;
                if (match != "HIGH") {
					success = false;
					break;
                }
            }
            if (success) {
                outcome = "successOutcome";
            } else {
                outcome = "failureOutcome";
            }
        } else {
            outcome = "failureOutcome";
        }
    } else {
        outcome = "notStartedOutcome";
    }
} else {
    outcome = "notStartedOutcome";
}
Copyright © 2010-2024 ForgeRock, all rights reserved.