# Plugin Response

### Response States

`SUCCESS`: Process finished successfully

`EXIT`: Process terminated by the user with no errors

`FAILURE`: Process finished with the user's failure to pass the service requirements

`ERROR` : Process terminated due to an error in the builder

{% hint style="info" %}
Note: In the case of`ERROR`, please check your configurations
{% endhint %}

### Document verification plus - Case Handling

When using `VIDVOCRResult.getData()`, the returned `ocrResult` may include a `documentVerificationPlus` object.\
This object contains validation flags and quality signals that help you determine whether the document should be accepted, reviewed, recaptured, or rejected.

***

#### Fields Returned Under `documentVerificationPlus`

| Field               | Type          | Meaning                                                                           |
| ------------------- | ------------- | --------------------------------------------------------------------------------- |
| `frontDataValidity` | boolean       | Overall validity of the front side based on greyscale flags + invalid fields list |
| `backDataValidity`  | boolean       | Overall validity of the back side based on greyscale flags + invalid fields list  |
| `isFrontGreyscale`  | boolean       | Indicates whether the front side is greyscale                                     |
| `isBackGreyscale`   | boolean       | Indicates whether the back side is greyscale                                      |
| `expired`           | boolean       | Whether the document is recognized as expired                                     |
| `reviewRequired`    | List\<String> | Fields that require attention (e.g. Nid, gender, expirydate…)                     |

***

#### How to Read These Values

* `frontDataValidity` and `backDataValidity` act as **parent flags**\
  → You can take action directly based on them if you want a simple validation flow.
* For more control, you can check detailed signals:
  * use greyscale flags if you want to **reject black-and-white copies**
  * use `reviewRequired`to apply different logic per field\
    e.g. reject if nid is invalid but allow if *gender* is inconsistent

This allows fully customizable decision logic depending on your business rules.

#### **Example Handling Logic**

```swift
/// Note:
/// - All actions here are only example handlers.
/// - Functions like showRetryDialog(), requestRecapture(), showError(), startOCR()
///   are placeholder functions you must implement based on your UI flow.

final flags = result.data?nameValuePairs.ocrResult?.ocrResult?.documentVerificationPlus;

if (flags != null) {

  // --------------------- GENERIC VALIDATION RESULTS --------------------- //

  // Global document validity
  if (flags.frontDataValidity == false || flags.backDataValidity == false) {
    showRetryDialog(
      title: "Document failed validation checks.",
      message: "Please try again.",
      onConfirm: () => startOCR(), // Restart logic - implement
    );
  }

  // Greyscale detection
  else if (flags.isFrontGreyscale == true || flags.isBackGreyscale == true) {
    requestRecapture("Document appears to be black & white."); 
    // Custom function for recapture action
  }

  // Expired document
  else if (flags.isExpired == true) {
    showRetryDialog(
      title: "OCR",
      message: "Expired ID, Please try again with your recent National ID.",
      onConfirm: () => startOCR(),
    );
  }

  // One or more fields need review
  else if (flags.reviewRequired?.isNotEmpty == true) {
    showError("Some fields require manual review.");
  }


  // --------------------- FIELD-LEVEL VALIDATION CASES --------------------- //

  final review = flags.reviewRequired ?? [];

  if (review.contains("serial_number")) {
    showRetryDialog(
      title: "OCR",
      message: "Serial number is incorrect. Please try again.",
      onConfirm: () => startOCR(),
    );
  }

  if (review.contains("back_nid") || review.contains("front_nid")) {
    requestRecapture("NID Mismatch");
  }

  if (review.contains("date_of_birth")) showError("Date of birth could not be verified.");
  if (review.contains("street")) showError("Street address is empty.");
  if (review.contains("police_station")) showError("Police station field needs review.");
  if (review.contains("governorate")) showError("Governorate value could not be verified.");
  if (review.contains("birth_governorate")) showError("Birth governorate requires review.");
  if (review.contains("expiry_date")) showError("Expiry date is missing or invalid.");
  if (review.contains("release_date")) showError("Release date did not pass validation.");

  else {
    // DEFAULT — document accepted successfully
  }
}

```

### Advance confidence  - Case Handling

When using `VIDVOCRResult.getData()`, the returned `ocrResult` may include a `advancedConfidence` object.\
This object contains manipulation flags that help you determine whether the document should be accepted, reviewed, recaptured, or rejected.

***

#### Fields Returned Under `advanceConfidence`

| Field                      | Type | Meaning                                                          |
| -------------------------- | ---- | ---------------------------------------------------------------- |
| fraudDetectionZone         | int  | Parent zone flag → Result of face + image manipulation combined  |
| faceFraudZone              | int  | Fraud confidence specifically related to face physical tampering |
| frontImageManipulationZone | int  | Indicates signs of front image physical manpulation              |

#### Zone Meaning

| Value | Color  | Meaning                                   |
| ----- | ------ | ----------------------------------------- |
| 0     | Green  | No manipulation detected                  |
| 1     | Yellow | Requires human review (suspicious)        |
| 2     | Red    | Strong indicators of fraud / manipulation |

***

#### **Example Handling Logic**

```dart
//Note that all decisions taken in this code are just an example of how you can handle
//the logic and that you can take the preferred action according to your business needs
final fraud = result.data?.ocrResult?.advancedConfidence;

// Parent Zone
if (fraud?.fraudDetectionZone == 1) showWarning("Review required"); // Replace with custom handling
if (fraud?.fraudDetectionZone == 2) requestRecapture("Fraud suspected"); // Developer replaces with custom retry logic

// Detailed Checks
if (fraud?.faceFraudZone == 1 || fraud?.faceFraudZone == 2) {
  showError("Face manipulation detected"); // Replace with custom handling
}
if (fraud?.frontImageManipulationZone == 1 || fraud?.frontImageManipulationZone == 2) {
  showError("ID surface manipulation detected"); // Replace with custom handling
}
```

### Primary Response Object

`nameValuePairs`&#x20;

{% hint style="info" %}
Note: All SDK responses are returned in JSON format
{% endhint %}

{% hint style="info" %}
Note: This is the first-level object
{% endhint %}

### `nameValuePairs` Object Body

* `state` \<string>
* `errorCode` \<string>
* `errorMessage` \<string>
* `ocrResult` \<object>
* `capturedImages` list\<object>
* `events` list\<object>
* `errors` list\<object>

#### `ocrResult` Object Body

{% hint style="info" %}
Note: This is the second-level object that contains all third-level objects
{% endhint %}

* `sessionID` \<string>

<details>

<summary><code>ocrResult</code> &#x3C;sub-object></summary>

* `firstName` \<string>
* `fullName` \<string>
* `religion` \<string>
* `gender` \<string>
* `dateOfBirth` \<string>
* `age` \<int>
* `maritalStatus` \<string>
* `husbandName` \<string>
* `street` \<string>
* `birthGovernorate` \<string>
* `policeStation` \<string>
* `governorate` \<string>
* `profession` \<string>
* `releaseDate` \<string>
* `expiryDate` \<string>
* `expired` \<boolean>
* `serialNumber` \<string>
* `frontNid` \<string>
* `backNid` \<string>
* `isRootOfTrustCompatible` \<boolean>
* `transactionIdFront` \<string>
* `transactionIdBack` \<string>
* `combinationID` \<string>
* `documentVerificationPlus` \<sub-object>
  * `expired` \<bool>
  * `frontDataValidity` \<bool>
  * `backDataValidity` \<bool>
  * `isFrontGreyscale` \<bool>
  * `isBackGreyscale` \<bool>
  * `reviewRequired` \<bool>
* `advancedConfidence` \<sub-object>
  * `fraudDetectionZone` \<int>
  * `fraudDetectionDetails` \<sub-object>
    * `faceFraudZone` \<int>
    * `faceFraudConfidence` \<double>
    * `frontImageManipulationZone` \<int>
    * `frontImageManipulationConfidence` \<double>

</details>

<details>

<summary><code>documentVerificationResult</code> &#x3C;sub-object></summary>

* `success` \<boolean>

</details>

<details>

<summary><code>captures</code> &#x3C;sub-object></summary>

* `nationalIdFront` \<base64-string>
* `nationalIdBack` \<base64-string>

</details>

{% hint style="info" %}
Note: `captures` object contains the latest images used for the OCR service
{% endhint %}

<details>

<summary><code>hmacDataList</code> &#x3C;list></summary>

* `serviceID:` ocr
* `hmacDigest` \<string>
* `rawResponse` \<string>

</details>

{% hint style="info" %}
The raw response in `hmacDataList` should be mapped to the result object as per the [HMAC Validation Documentation ](https://valify.gitbook.io/documentation/response-data-validation)
{% endhint %}

<details>

<summary><code>decryptionKeys</code> &#x3C;sub-object></summary>

* `nationalIdFrontRequestKey` \[UInt8]
* `nationalIdBackRequestKey` \[UInt8]
* `combineResponseKey` \[UInt8]

</details>

#### Review Required Feature Breakdown:

The following are possible values that could come in the review required list along with their triggers

<details>

<summary>Review Required Possible Values</summary>

* date\_of\_birth triggered by an invalid date or incorrect format
* street when the field value is missing from the response
* police\_station when the field value is missing from the response
* governorate when the field value is missing from the response
* birth\_governorate triggered by an invalid field format
* back\_nid triggered by an invalid field format
* front\_nid triggered by an invalid field format
* serial\_number triggered by an invalid field format
* full\_name triggered when the field value is missing from the response
* first\_name triggered when the field value is missing from the response
* expiry\_date triggered by an invalid date or incorrect format
* release\_date triggered by an invalid date or incorrect format
* front\_img triggered when is\_front\_greyscale is true
* back\_img triggered when is\_back\_greyscale is true

</details>

#### `capturedImages` Object Body

* `nationalIDLabel` \<string>
* `nationalIdImage` \<base64-string>

{% hint style="info" %}
Note: `capturedImages` is a list of objects that contains all images captured throughout the experience
{% endhint %}

#### `events` Object Body

* `date` \<string>
* `key`\<string>
* `screen` \<string>
* `timestamp` \<string>
* `type` \<string>

#### `errors` Object Body

* `code`\<string>
* `message`\<base64-string>
* `date` \<string>
* `screen` \<string>
* `timestamp` \<string>
* `type` \<string>&#x20;

{% hint style="info" %}
Note: `events` and `errors` objects are only returned if `enable_logging` is set to true from the plugin configuration
{% endhint %}

### State Responses

<mark style="color:blue;">`SUCCESS`</mark>

* `nameValuePairs` \<object>
  * `state` \<string>&#x20;
  * `ocrResult` \<sub-object>
  * `capturedImages` \<sub-object>
  * `events` \<sub-object>
  * `errors` \<sub-object>

<mark style="color:blue;">`EXIT`</mark>

* `nameValuePairs` \<object>
  * `state` \<string>
  * `ocrResult` \<sub-object>
  * `capturedImages` \<sub-object>
  * `step` \<string>
  * `events` \<sub-object>
  * `errors` \<sub-object>

{% hint style="info" %}
Note: step \<string> identifies the point where the user chose to exit the SDK
{% endhint %}

<mark style="color:red;">`FAILURE`</mark>

* `nameValuePairs` \<object>
  * `state` \<string>
  * `errorCode` \<int>
  * `errorMessage` \<string>
  * `capturedImages` \<sub-object>
  * `ocrResult` \<sub-object>
  * `events` \<sub-object>
  * `errors` \<sub-object>

<mark style="color:red;">`ERROR`</mark>

* `nameValuePairs` \<object>
  * `state` \<string>
  * `errorCode` \<int>
  * `errorMessage` \<string>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://valify.gitbook.io/valify-ios-sdk-documentation/document-capture/flutter-plugin/plugin-response.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
