Verify with GoPay
Verify with GoPay Request
The verify flow is initiated by calling FeatureManager.verify() with a FeatureRequest built via the Builder API.
let request = FeatureRequest.Builder()
.requestId(UUID().uuidString)
.userCorrelationId("corr-5678")
.token("linking-token-xyz")
.build()| Field name | Description |
|---|---|
| requestId | Unique identifier for the request, generated by the client. Required — callback.onError(GPE-2206) is called if blank. |
| userCorrelationId | Identifier linking the client user to GoPay. Required — callback.onError(GPE-2206) is called if blank. |
| token | The linking token for the user. Provide a short-term linking token when using .exchange, or a long-term token when using .none. |
Note:
FeatureRequest.Builder.build()does not validate fields. Validation happens insideverify()— missing required fields result incallback.onErrorbeing called withGPE-2206, not a thrown error.
Verify with GoPay Response
callback.onComplete is called with a VerifyResult upon successful completion.
public struct VerifyResult {
public let submissionId: String
}| Field | Description |
|---|---|
| submissionId | Submission identifier for the KYC flow, returned by the backend. |
FeatureRequest
FeatureRequest is constructed via its Builder. requestId and userCorrelationId are validated inside verify() — if either is blank, callback.onError is called with GPE-2206 rather than throwing.
public struct FeatureRequest {
public let requestId: String
public let featureId: String?
public let userCorrelationId: String
public let token: String?
public final class Builder {
public init()
@discardableResult public func requestId(_ id: String) -> Builder
@discardableResult public func featureId(_ id: String?) -> Builder
@discardableResult public func userCorrelationId(_ id: String) -> Builder
@discardableResult public func token(_ t: String?) -> Builder
public func build() -> FeatureRequest
}
}Fields
| Field name | Type | Required | Description |
|---|---|---|---|
| requestId | String | Yes | Unique identifier for the request, generated by the client (e.g. a UUID). Validated inside verify(); error returned if blank. |
| featureId | String? | No | Reserved for internal use. Do not set this field for the verify flow. |
| userCorrelationId | String | Yes | Identifier linking the client user to GoPay. Validated inside verify(); error returned if blank. |
| token | String? | Yes | The linking token for the user. Pass a short-term linking token when using .exchange, or a long-term token when using .none. |
Usage Notes
build()performs no validation — a request with blankrequestIdoruserCorrelationIdwill build successfully but triggercallback.onError(GPE-2206)when passed toverify().requestIdmust be unique per flow and is used for state correlation during the handshake.- Generate a fresh
requestIdfor everyverifycall — do not reuse across calls.
GoPayCredential
Represents the authentication credential issued by the SDK to the client during the auth-code exchange.
public enum GoPayCredential {
case authCode(code: String)
}| Case | Description |
|---|---|
| authCode | The one-time authentication code to exchange server-side for a user correlation ID. |
CredentialReceiver
Controls how the SDK delivers a GoPayCredential to the client during a flow requiring an auth-code handshake.
public enum CredentialReceiver {
case exchange(handler: CredentialExchangeHandler)
case none
}
public struct CredentialExchangeHandler {
public let handle: (
_ credential: GoPayCredential,
_ requestId: String,
_ completion: @escaping (ExchangeResult) -> Void
) -> Void
public init(handle: @escaping (
_ credential: GoPayCredential,
_ requestId: String,
_ completion: @escaping (ExchangeResult) -> Void
) -> Void)
}| Case | Description |
|---|---|
| exchange | Use when the user has a short-term linking token. The SDK calls the handler with an auth code; the client exchanges it server-side and calls completion with the result. |
| none | Use when the user has a long-term token that is still valid. No auth-code exchange is required. |
Usage Notes
- Use
.exchangewhen the user has a short-term linking token that requires a backend exchange. - Use
.nonewhen the user has a long-term token and no exchange is required. - The
handleclosure may be invoked on a background thread — do not perform UI operations directly inside it. - Always call the
completionclosure exactly once per handler invocation. Do not throw or return without calling it.
ExchangeResult
Returned via the completion closure of CredentialExchangeHandler to signal the outcome of the backend credential exchange.
public enum ExchangeResult {
case success(userCorrelationId: String)
case failure(reason: String)
}| Case | Associated Value | Description |
|---|---|---|
| success | userCorrelationId | The unique user identifier returned from the client's backend after exchanging the auth code. |
| failure | reason | A human-readable description of why the exchange failed. The SDK propagates this in GPE-2208. |
Usage Notes
- Call
completion(.success(userCorrelationId:))after a successful backend call that returns theuserCorrelationId. - Call
completion(.failure(reason:))if your backend call fails. The SDK stops the flow and callscallback.onErrorwith codeGPE-2208. - Never throw from inside the handler — always call
completion.
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.
let request = FeatureRequest.Builder()
.requestId(UUID().uuidString)
.userCorrelationId("corr-5678")
.token("short-term-linking-token")
.build()
let credentialReceiver = CredentialReceiver.exchange(
handler: CredentialExchangeHandler { credential, requestId, completion in
switch credential {
case .authCode(let code):
myBackend.exchangeAuthCode(code, requestId: requestId) { result in
switch result {
case .success(let correlationId):
completion(.success(userCorrelationId: correlationId))
case .failure(let error):
completion(.failure(reason: error.localizedDescription))
}
}
}
}
)
let callback = VerifyFeatureCallback { result in
print("Submission ID: \(result.submissionId)")
} onError: { error in
print("Error [\(error.code)]: \(error.title) — \(error.message)")
}
self.verifyCallback = callback // retain strongly
do {
try sdk.getFeatureManager().verify(
viewController: self,
request: request,
credentialReceiver: credentialReceiver,
callback: AnyFeatureCallback(wrapping: callback)
)
} catch {
print("verify threw: \(error)")
}Without credential exchange (long-term token)
Use this when the user already has a long-term token. No auth-code exchange is required.
let request = FeatureRequest.Builder()
.requestId(UUID().uuidString)
.userCorrelationId("corr-5678")
.token("long-term-token")
.build()
let callback = VerifyFeatureCallback { result in
print("Submission ID: \(result.submissionId)")
} onError: { error in
print("Error [\(error.code)]: \(error.message)")
}
self.verifyCallback = callback
do {
try sdk.getFeatureManager().verify(
viewController: self,
request: request,
credentialReceiver: .none,
callback: AnyFeatureCallback(wrapping: callback)
)
} catch {
print("verify threw: \(error)")
}Usage Notes
- Always call
verify()on the main thread. verify()is markedthrows— wrap it in ado-catchblock.build()does not throw — validation is performed insideverify(). Ensure bothrequestIdanduserCorrelationIdare non-blank before calling.- Pass
.exchangewhen the user has a short-term linking token. The SDK invokes the handler with an auth code; your backend exchanges it and returns theuserCorrelationIdviacompletion. - Pass
.nonewhen the user has a long-term token that is still valid. - Call
completion(.failure(reason:))— never throw — from inside the handler if your backend call fails. The SDK invokescallback.onErrorwithGPE-2208. - The
dataparameter inonCompletemay carry additional SDK metadata and can safely be ignored if not needed. - Keep a strong reference to your
FeatureCallbackinstance for the duration of the flow.AnyFeatureCallbackholds it weakly.
Updated about 13 hours ago