# Verify with GoPay
# Verify with GoPay Request
The verify flow is initiated by calling `FeatureManager.verify()` with a `FeatureRequest` built via the Builder API.
```kotlin
val request = FeatureRequest.Builder()
.requestId("REQ-${System.currentTimeMillis()}")
.userCorrelationId("corr-5678")
.token("linking-token-xyz")
.build()
```
| Field name | Description |
| :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| requestId | Unique identifier for the request, generated by the client. Required — `FeatureCallback.onError(GPE-2206)` is invoked if blank. |
| userCorrelationId | Identifier linking the client user to GoPay. Required — `FeatureCallback.onError(GPE-2206)` is invoked if blank. |
| token | The linking token for the user. Provide a short-term linking token when using `CredentialReceiver.Exchange`, or a long-term token when using `CredentialReceiver.None`. |
> **Note:** `FeatureRequest.build()` does not validate fields. Validation happens inside `verify()` — missing required fields result in `FeatureCallback.onError` being called with `GPE-2206`, not an exception.
# Verify with GoPay Response
`FeatureCallback.onComplete` is invoked with a `VerifyResult` upon completion of the flow.
```kotlin
data class VerifyResult(val submissionId: String)
```
| Field | Description |
| :----------- | :--------------------------------------------------------------- |
| submissionId | Submission identifier for the KYC flow, returned by the backend. |
# Example Usage
## With credential exchange (short-term linking token)
Use this when the user has a short-term linking token. The SDK invokes the exchange handler with an auth code; your backend exchanges it for the user's correlation ID.
```kotlin
val request = FeatureRequest.Builder()
.requestId("REQ-${System.currentTimeMillis()}")
.userCorrelationId("corr-5678")
.token("short-term-linking-token")
.build()
val credentialReceiver = CredentialReceiver.Exchange { credential, requestId ->
if (credential is GoPayCredential.AuthCode) {
val correlationId = userService.exchangeAuthCode(credential.code, requestId)
ExchangeResult.Success(userCorrelationId = correlationId)
} else {
ExchangeResult.Failure(reason = "Unexpected credential type")
}
}
sdk.getFeatureManager().verify(
activity = this,
request = request,
credentialReceiver = credentialReceiver,
callback = object : FeatureCallback {
override fun onComplete(result: VerifyResult, data: Map) {
// result.submissionId is the KYC submission reference
}
override fun onError(error: GoPayEnterpriseError) {
// See GoPayEnterpriseError for codes
}
}
)
```
## Without credential exchange (long-term token)
Use this when the user already has a long-term token. No auth-code exchange is required.
```kotlin
sdk.getFeatureManager().verify(
activity = this,
request = FeatureRequest.Builder()
.requestId("REQ-${System.currentTimeMillis()}")
.userCorrelationId("corr-5678")
.token("long-term-token")
.build(),
credentialReceiver = CredentialReceiver.None,
callback = object : FeatureCallback {
override fun onComplete(result: VerifyResult, data: Map) {
Log.d(TAG, "submissionId: ${result.submissionId}")
}
override fun onError(error: GoPayEnterpriseError) {
Log.e(TAG, "${error.code}: ${error.message}")
}
}
)
```
# Usage Notes
* `build()` does not throw — validation is performed inside `verify()`. Ensure both `requestId` and `userCorrelationId` are non-blank before calling `verify()`.
* Pass `CredentialReceiver.Exchange` when the user has a **short-term linking token**. The SDK invokes the handler with an auth code; your backend exchanges it and returns the `userCorrelationId`.
* Pass `CredentialReceiver.None` when the user has a **long-term token** that is still valid.
* Return `ExchangeResult.Failure` (never throw) from the exchange handler if your backend call fails. The SDK invokes `FeatureCallback.onError` with `GPE-2208`.
* The exchange handler runs on a background coroutine dispatcher — do not update UI inside it.
* The `data` parameter in `onComplete` may carry additional SDK metadata; it can safely be ignored if not needed.
* Always call `verify()` from the main thread.