> For the complete documentation index, see [llms.txt](https://valify.gitbook.io/valify-ios-sdk-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://valify.gitbook.io/valify-ios-sdk-documentation/document-capture/flutter-plugin/plugin-response.md).

# 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>
