### IPification Authentication Setup and Start Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/im/android/README.md Configure IPification settings and initiate the authentication process with callbacks. ```kotlin val callback = object : VerifyCompleteListener { override fun onSuccess(state: String) { Log.d("DemoActivity", "state:" + state) // TODO: Call your backend with {state} to check the auth result } override fun onFail(error: String) { Log.e("DemoActivity", "" + error) // TODO: Fall back to OTP } override fun onOpenedLink() { // TODO: Hide loading Log.d("DemoActivity", "opened IM app" ) } } IPConfiguration.getInstance().ENV = IPEnvironment.SANDBOX IPConfiguration.getInstance().CLIENT_ID = "your-client-id" IPConfiguration.getInstance().REDIRECT_URI = Uri.parse("your-redirect-uri") IPConfiguration.getInstance().currentState = IPConfiguration.getInstance().generateState() IPConfiguration.getInstance().IM_PRIORITY_APP_LIST = arrayOf("wa", "telegram", "viber") IMServices.startAuthentication(this@activity, callback) ``` -------------------------------- ### Android IM Authentication Setup and Start Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Configure IPification for IM authentication and initiate the process. Ensure your AndroidManifest.xml includes necessary activity configurations and package queries for IM apps. ```kotlin // Android (Kotlin) — IM authentication setup and start IPConfiguration.getInstance().ENV = IPEnvironment.SANDBOX IPConfiguration.getInstance().CLIENT_ID = "your-client-id" IPConfiguration.getInstance().REDIRECT_URI = Uri.parse("yourapp://callback") IPConfiguration.getInstance().currentState = IPConfiguration.getInstance().generateState() IPConfiguration.getInstance().IM_PRIORITY_APP_LIST = arrayOf("wa", "telegram", "viber") val callback = object : VerifyCompleteListener { override fun onSuccess(state: String) { Log.d("IM", "Authenticated! state=$state") // Send `state` to backend to verify the session } override fun onFail(error: String) { Log.e("IM", "Failed: $error") // Fallback to OTP } override fun onOpenedLink() { // IM app was launched — hide loading spinner Log.d("IM", "IM app opened") } } IMServices.startAuthentication(this, callback) ``` ```kotlin // In your Activity — handle return from IM app: override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) onNewIntent = true IMServices.checkAndFinishSession() // triggers onSuccess callback after 1s delay } override fun onResume() { super.onResume() if (!onNewIntent) IMServices.checkAndFinishSession() onNewIntent = false } ``` ```xml // AndroidManifest.xml — required activity config for IM: // // // // // // ``` -------------------------------- ### Authorization Request Example Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/ios_sdk_core_document.md This is an example of an HTTP GET request to initiate the authorization process. It includes parameters like client_id, redirect_uri, and scope for phone number verification. The response can be a direct redirect_uri with a code or a 30x redirect. ```http GET https://api.ipification.com/auth/realms/ipification/protocol/openid-connect/auth?response_type=code& client_id={client-id}& redirect_uri={client-callback-uri}& scope=openid ip:phone_verify& state={state}& login_hint={login_hint} ``` -------------------------------- ### Authorization Response Examples Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/android_sdk_core_document.md Illustrates the two possible response types from the Authorization API: a direct success response with a code, or a redirect response requiring further URL following. ```http Response: (1) 200 - redirect_uri?code=abcxyz&state={state} (2) 302 - url redirection (ex: https://mnv.telco.com/webhook/api/webhook/auth?state=xyzabc) ``` -------------------------------- ### Handle HTTP Redirects with Custom Interceptor (OkHttp) Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/android_sdk_core_document.md An OkHttp Interceptor to specifically handle HTTP redirects (3xx status codes). It checks if the redirect location starts with a predefined redirect URI and returns a 200 OK response if it matches, otherwise, it proceeds with the default redirect behavior. ```kotlin import android.content.Context import android.os.Build import android.util.Log import okhttp3.* import okhttp3.ResponseBody.Companion.toResponseBody class HandleRedirectInterceptor(ctx: Context, requestUrl: String, redirect_uri: String) : Interceptor { private var redirectUri: String = redirect_uri private var url: String = requestUrl override fun intercept(chain: Interceptor.Chain): Response { val request: Request = chain.request() val response: Response = chain.proceed(request) // check and return success response if location match with defined redirect-uri if (response.code in 300.. 399){ if ((response.headers["location"] != null && response.headers["location"]!!.startsWith(redirectUri)) || (response.headers["Location"] != null && response.headers["Location"]!!.startsWith(redirectUri))) { val builder: Response.Builder = Response.Builder().request(request).protocol(Protocol.HTTP_1_1) val contentType: MediaType? = response.body!!.contentType() val locationRes = response.headers["location"] ?: response.headers["Location"] ?: "" val body = locationRes.toResponseBody(contentType) builder.code(200).message("success").body(body) // close the response body to avoid exception response.body?.close() return builder.build() } } return response } } ``` -------------------------------- ### Authorization API — Authenticate via Cellular Network Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Initiates the IPification authentication flow. The SDK builds the authorization URL and sends the GET request **exclusively over the cellular interface**, following any telco-side HTTP redirects (301/302/303) until the final `redirect_uri` is reached. The resulting `code` query parameter must be exchanged server-to-server for a token. ```APIDOC ## Authorization API — Authenticate via Cellular Network ### Description Initiates the IPification authentication flow. The SDK builds the authorization URL and sends the GET request **exclusively over the cellular interface**, following any telco-side HTTP redirects (301/302/303) until the final `redirect_uri` is reached. The resulting `code` query parameter must be exchanged server-to-server for a token. ### Method ```kotlin // Android (Kotlin) — full authorization request with URL construction val authCallback = object : IPCallback { override fun onSuccess(response: String) { // response = "yourapp://callback?code=abc123&state=ip-sdk-xyz" val code = Uri.parse(response).getQueryParameter("code") val state = Uri.parse(response).getQueryParameter("state") Log.d("IPification", "Auth code: $code | state: $state") // TODO: Send `code` to your backend for S2S token exchange } override fun onFailure(error: String) { Log.e("IPification", "Auth failed: $error") // Fallback to OTP / alternative authentication } } ``` ### Endpoint ``` // Authorization endpoint (constructed internally by the SDK) // GET https://api.ipification.com/auth/realms/ipification/protocol/openid-connect/auth // ?response_type=code // &client_id=your-client-id // &redirect_uri=yourapp%3A%2F%2Fcallback // &scope=openid%20ip%3Aphone_verify // &state=ip-sdk-AbCdEfGh12345678 // &login_hint=19876543210 // &consent_id=ipconsent001eng (optional, carrier-specific) // &consent_timestamp=1700000000 (optional, UNIX seconds) // // Success response (HTTP 200 after redirect chain): // yourapp://callback?code=AbCdEfGh&state=ip-sdk-AbCdEfGh12345678 ``` ``` -------------------------------- ### IPification Integration (iOS Objective-C) Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Demonstrates how to consume the Swift SDK from Objective-C projects by using a bridging header and @objc annotations. Covers configuration, coverage checks, and initiating authorization. ```objective-c // Objective-C — import bridging header (ProductModuleName-Swift.h) #import "YourAppName-Swift.h" // Configure IPification [IPConfiguration sharedInstance].ENV = IPEnvironmentPRODUCTION; [IPConfiguration sharedInstance].CLIENT_ID = @"your-prod-client-id"; [IPConfiguration sharedInstance].REDIRECT_URI = @"yourapp://callback"; // Check Coverage CoverageService *coverageService = [[CoverageService alloc] init]; [coverageService setCallbackSuccess:^(CoverageResponse *response) { if ([response isAvailable]) { // Supported telco — start authorization AuthorizationService *authService = [[AuthorizationService alloc] init]; [authService setCallbackSuccess:^(AuthorizationResponse *resp) { NSLog(@"Auth code: %@", [resp getCode]); // Send code to backend for token exchange }]; [authService setCallbackFailed:^(IPificationException *error) { NSLog(@"Auth error: %@", [error localizedDescription]); }]; AuthorizationRequestBuilder *builder = [[AuthorizationRequestBuilder alloc] init]; [builder setScopeWithValue:@"openid ip:phone_verify"]; [builder addQueryParamWithKey:@"login_hint" value:@"19876543210"]; [authService startAuthorization:[builder build]]; } else { NSLog(@"Telco not supported — fallback to OTP"); } }]; [coverageService setCallbackFailed:^(IPificationException *error) { NSLog(@"Coverage error: %@", [error localizedDescription]); }]; [coverageService checkCoverageWithPhoneNumberWithPhone:@"19876543210" :nil]; ``` -------------------------------- ### Objective-C Calling Swift Methods Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/ios_Objective-C_Guideline.md Demonstrates how to initialize and use Swift classes and call their methods from Objective-C. This includes setting configuration, checking coverage, and initiating authentication flows. ```objective-c // Init [IPConfiguration sharedInstance].ENV = IPEnvironmentPRODUCTION; // IPEnvironmentSANDBOX [IPConfiguration sharedInstance].CLIENT_ID = @"your-prod-client-id"; [IPConfiguration sharedInstance].REDIRECT_URI = @"your-prod-redirect-uri"; // CheckCoverage CoverageService *coverageService = [[CoverageService alloc] init]; [coverageService setCallbackSuccess:^(CoverageResponse *response) { if([response isAvailable]){ // supported Telco. Call Authorization API }else{ // unsupported Telco, fallback to another auth service flow } }]; [coverageService setCallbackFailed:^(IPificationException *error) { // error, fallback to another auth service flow NSLog(@"Coverage error: %@", [error localizedDescription]); }]; [coverageService checkCoverageWithPhoneNumberWithPhone:@"999123456789" :nil]; // Do Authentication AuthorizationService *authorizationService = [[AuthorizationService alloc] init]; [authorizationService setCallbackSuccess:^(AuthorizationResponse *response) { // Handle successful response here NSLog(@"Authorization success: %@", [response getCode]); }]; [authorizationService setCallbackFailed:^(IPificationException *error) { // error, fallback to another auth service flow NSLog(@"Authorization error: %@", [error localizedDescription]); }]; AuthorizationRequestBuilder *authBuilder = [[AuthorizationRequestBuilder alloc] init]; [authBuilder setScopeWithValue:@"openid ip:phone_verify"]; [authBuilder addQueryParamWithKey:@"login_hint" value: @"999123456789"]; AuthorizationRequest *authRequest = [authBuilder build]; [authorizationService startAuthorization:authRequest]; ``` -------------------------------- ### Execute Network Request with OkHttp Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/android_sdk_core_document.md Demonstrates how to build and execute an HTTP request using OkHttp, including handling responses and errors. ```java val httpClient = httpBuilder.build() val okHttpRequestBuilder = Request.Builder() //url okHttpRequestBuilder.url(authRequest.getUrl()) val okHttpRequest: Request = okHttpRequestBuilder .build() httpClient.newCall(okHttpRequest).enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { // handle the response Log.i("CellularConnection", "callAPIonCellularNetwork RESULT:${response.body?.string()}") } override fun onFailure(call: Call, e: IOException) { e.printStackTrace() } }) ``` -------------------------------- ### Initialize IPification SDK for Android Staging Environment (Java) Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/custom_urls.md This Java method initializes the IPification SDK for the staging environment, setting custom URLs and staging endpoints. Client credentials should be added as needed. ```java private void initIPification() { IPConfiguration.getInstance().setENV(IPEnvironment.SANDBOX); // for stage only - start IPConfiguration.getInstance().setCustomUrls(true); IPConfiguration.getInstance().setCOVERAGE_URL(Uri.parse("https://api.stage.ipification.com/auth/realms/ipification/coverage")); IPConfiguration.getInstance().setAUTHORIZATION_URL(Uri.parse("https://api.stage.ipification.com/auth/realms/ipification/protocol/openid-connect/auth")); // TODO: your client credential on stage // IPConfiguration.getInstance().setCLIENT_ID(); // IPConfiguration.getInstance().setREDIRECT_URI(); } ``` -------------------------------- ### Request and Launch Phone Number Hint Picker Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/android-phone-number-hint.md Initiates the system dialog for the user to select a phone number. Requires the `GetPhoneNumberHintIntentRequest` and `Identity.getSignInClient`. ```kotlin val request = GetPhoneNumberHintIntentRequest.builder().build() val signInClient = Identity.getSignInClient(this) signInClient.getPhoneNumberHintIntent(request) .addOnSuccessListener { result: PendingIntent -> try { phoneNumberHintIntentResultLauncher.launch( IntentSenderRequest.Builder(result).build() ) } catch (e: Exception) { Log.e("PhoneHint", "Launching PendingIntent failed", e) } } .addOnFailureListener { e -> Log.e("PhoneHint", "Phone Number Hint failed", e) } ``` -------------------------------- ### Configure IPification SDK for iOS Staging Environment Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/custom_urls.md Use this Swift code to set the IPification SDK to use the staging environment and custom URLs. Remember to uncomment and fill in your client credentials for staging. ```swift if (isProduction) { IPConfiguration.sharedInstance.ENV = IPEnvironment.PRODUCTION IPConfiguration.sharedInstance.customUrls = false // TODO: your client credential on live // IPConfiguration.sharedInstance.CLIENT_ID = // IPConfiguration.sharedInstance.REDIRECT_URL = } else { IPConfiguration.sharedInstance.ENV = IPEnvironment.SANDBOX IPConfiguration.sharedInstance.customUrls = true IPConfiguration.sharedInstance.COVERAGE_URL = "https://api.stage.ipification.com/auth/realms/ipification/coverage" IPConfiguration.sharedInstance.AUTHORIZATION_URL = "https://api.stage.ipification.com/auth/realms/ipification/protocol/openid-connect/auth" // TODO: your client credential on stage // IPConfiguration.sharedInstance.CLIENT_ID = // IPConfiguration.sharedInstance.REDIRECT_URL = } ``` -------------------------------- ### Configure IPification SDK for Android Staging Environment (Kotlin) Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/custom_urls.md This Kotlin code configures the IPification SDK for the staging environment, enabling custom URLs and specifying staging endpoints. Ensure your client credentials are set. ```kotlin if (isProduction) { IPConfiguration.getInstance().ENV = IPEnvironment.PRODUCTION IPConfiguration.getInstance().customUrls = false // TODO: your client credential on live // IPConfiguration.getInstance().CLIENT_ID = // IPConfiguration.getInstance().REDIRECT_URL = } else { IPConfiguration.getInstance().ENV = IPEnvironment.SANDBOX IPConfiguration.getInstance().customUrls = true IPConfiguration.getInstance().COVERAGE_URL = Uri.parse("https://api.stage.ipification.com/auth/realms/ipification/coverage") IPConfiguration.getInstance().AUTHORIZATION_URL = Uri.parse("https://api.stage.ipification.com/auth/realms/ipification/protocol/openid-connect/auth") // TODO: your client credential on stage // IPConfiguration.getInstance().CLIENT_ID = // IPConfiguration.getInstance().REDIRECT_URL = } ``` -------------------------------- ### Import Swift Header in Objective-C Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/ios_Objective-C_Guideline.md Use this syntax to import the generated Swift header file into your Objective-C code. The header name is typically your product module name followed by '-Swift.h'. ```objective-c #import "productModuleName-Swift.h" ``` -------------------------------- ### Initiate Cellular Network Authentication (Kotlin) Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Initiates the IPification authentication flow. The SDK constructs the authorization URL and sends the request over the cellular interface, handling telco redirects. The resulting `code` must be exchanged server-to-server for a token. ```kotlin val authCallback = object : IPCallback { override fun onSuccess(response: String) { // response = "yourapp://callback?code=abc123&state=ip-sdk-xyz" val code = Uri.parse(response).getQueryParameter("code") val state = Uri.parse(response).getQueryParameter("state") Log.d("IPification", "Auth code: $code | state: $state") // TODO: Send `code` to your backend for S2S token exchange } override fun onFailure(error: String) { Log.e("IPification", "Auth failed: $error") // Fallback to OTP / alternative authentication } } // Authorization endpoint (constructed internally by the SDK) // GET https://api.ipification.com/auth/realms/ipification/protocol/openid-connect/auth // ?response_type=code // &client_id=your-client-id // &redirect_uri=yourapp%3A%2F%2Fcallback // &scope=openid%20ip%3Aphone_verify // &state=ip-sdk-AbCdEfGh12345678 // &login_hint=19876543210 // &consent_id=ipconsent001eng (optional, carrier-specific) // &consent_timestamp=1700000000 (optional, UNIX seconds) // // Success response (HTTP 200 after redirect chain): // yourapp://callback?code=AbCdEfGh&state=ip-sdk-AbCdEfGh12345678 ``` -------------------------------- ### Handling IPification Authentication Result Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/im/android/README.md Override onNewIntent and onResume to check and finish the IPification authentication session. ```kotlin override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) // Set flag indicating new intent received onNewIntent = true // Call method to handle session check IMServices.checkAndFinishSession() } override fun onResume() { super.onResume() // Check if activity was launched from a new intent if (!onNewIntent) { // If not, call method to handle session check IMServices.checkAndFinishSession() } // Reset flag indicating new intent onNewIntent = false } ``` -------------------------------- ### Check Carrier Support with IPificationService (Kotlin) Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Use this to verify if the user's current carrier supports IPification before initiating authentication. Ensure the request is routed through the cellular interface. If the telco is not supported, fall back to an alternative method like SMS OTP. ```kotlin val ipService = IPificationService() ipService.performCoverageRequest( context = this, env = "live", // "live" or "sandbox" phoneNumber = "19876543210", // E.164 without leading + clientID = "your-client-id", redirectUri = "yourapp://callback", callback = object : IPCallback { override fun onSuccess(response: String) { // {"available": true} — telco is supported // Proceed to authentication ipService.performAuthenticationRequest( context = this@MainActivity, phoneNumber = "19876543210", clientID = "your-client-id", redirectUri = "yourapp://callback", callback = authCallback ) } override fun onFailure(error: String) { // Unsupported telco or network error — fallback to SMS Log.e("IPification", "Coverage failed: $error") } } ) ``` -------------------------------- ### iOS NWConnection State Handling Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/README.md Set up a stateUpdateHandler for the NWConnection to monitor its lifecycle, including ready, waiting, failed, and cancelled states. This allows for handling connection events and errors. ```swift connection.stateUpdateHandler = { (newState) in print("TCP state change to: \(newState)") switch newState { case .ready: print("ready") // self.delegate!.didConnect(socket: self) break case .waiting(let error): print("waiting error \(error.debugDescription ?? "")") break case .failed(let error): print("failed \(error.debugDescription ?? "")") // self.delegate?.didDisconnect(socket: self, error: error) break case .cancelled: print("cancelled" ) break default: print("default") break } } connection.start(queue: .main) ``` -------------------------------- ### Manifest Configuration for IM Apps Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/im/android/README.md Declare necessary IM app packages in AndroidManifest.xml for IPification to query. ```xml ``` -------------------------------- ### Coverage API — Check Carrier Support Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Before initiating authentication, call the Coverage API to verify the user's telco is supported. The request must be routed through the cellular interface. A `true` response in the `available` field means you can proceed to authorization; `false` means you should fall back to another authentication method (e.g., SMS OTP). ```APIDOC ## Coverage API — Check Carrier Support ### Description Before initiating authentication, call the Coverage API to verify the user's telco is supported. The request must be routed through the cellular interface. A `true` response in the `available` field means you can proceed to authorization; `false` means you should fall back to another authentication method (e.g., SMS OTP). ### Method ```kotlin // Android (Kotlin) — IPificationService.performCoverageRequest val ipService = IPificationService() ipService.performCoverageRequest( context = this, env = "live", // "live" or "sandbox" phoneNumber = "19876543210", // E.164 without leading + clientID = "your-client-id", redirectUri = "yourapp://callback", callback = object : IPCallback { override fun onSuccess(response: String) { // {"available": true} — telco is supported // Proceed to authentication ipService.performAuthenticationRequest( context = this@MainActivity, phoneNumber = "19876543210", clientID = "your-client-id", redirectUri = "yourapp://callback", callback = authCallback ) } override fun onFailure(error: String) { // Unsupported telco or network error — fallback to SMS Log.e("IPification", "Coverage failed: $error") } } ) ``` ### Endpoint ``` // Equivalent REST call (for reference / server-side testing) // GET https://api.ipification.com/auth/realms/ipification/coverage // ?client_id=your-client-id&phone=19876543210 // Response: {"available": true} ``` ``` -------------------------------- ### Handle Phone Number Hint Result Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/android-phone-number-hint.md Processes the result from the phone number hint picker. Extracts the phone number using `Identity.getSignInClient().getPhoneNumberFromIntent()` and handles success or cancellation. ```kotlin private val phoneNumberHintIntentResultLauncher = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result -> if (result.resultCode == Activity.RESULT_OK && result.data != null) { try { val phoneNumber = Identity.getSignInClient(requireActivity()) .getPhoneNumberFromIntent(result.data) val phone = detectCountryAndExtractNationalNumber(phoneNumber) binding.phoneCodeEditText.setText(phone.second) Log.d("PhoneHint", "Retrieved phone number: $phoneNumber") } catch (e: Exception) { Log.e("PhoneHint", "Failed to retrieve phone number: ${e.message}") Toast.makeText(requireContext(), "Failed to retrieve phone number", Toast.LENGTH_SHORT).show() } } else { Log.w("PhoneHint", "Hint cancelled or no result.") Toast.makeText(requireContext(), "Phone number hint cancelled", Toast.LENGTH_SHORT).show() } } ``` -------------------------------- ### Kotlin Implementation for Requesting Phone Permissions and Fetching Number Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/android-phone-number-hint.md This Kotlin code handles requesting multiple phone permissions and then fetching the phone number. It includes logic for permission grants and fallbacks to country code. ```kotlin val PHONE_PERMS = arrayOf( Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_PHONE_NUMBERS ) fun requestPermsThenFetch() { if (hasAllPhonePerms(context)) { fetchPhoneNumberNow(context) { msisdn -> if (!msisdn.isNullOrBlank()) { viewModel.onPhoneNumberFromHint(msisdn) Log.d("PhoneFetch", "Perm-accepted; fetched: $msisdn") } else { Log.d("PhoneFetch", "Cannot fetch the number") } } } else { permLauncher.launch(PHONE_PERMS) } } val permLauncher = rememberLauncherForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { grants -> val granted = PHONE_PERMS.all { grants[it] == true } if (granted) { fetchPhoneNumberNow(context) { msisdn -> if (!msisdn.isNullOrBlank()) { viewModel.onPhoneNumberFromHint(msisdn) } else { val dial = Util.getSystemDialCode(context) viewModel.onCountryCodeFromHint(dial) } } } else { val dial = Util.getSystemDialCode(context) viewModel.onCountryCodeFromHint(dial) } } private fun hasAllPhonePerms(ctx: Context): Boolean = ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_PHONE_NUMBERS) == PackageManager.PERMISSION_GRANTED private fun logPhoneFetch(message: String, level: String = "d") { when (level) { "e" -> Log.e("PhoneFetch", message) "w" -> Log.w("PhoneFetch", message) "i" -> Log.i("PhoneFetch", message) else -> Log.d("PhoneFetch", message) } } ``` -------------------------------- ### Android: Cellular-Bound DNS Resolution with OkHttpClient Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Configure OkHttpClient to use cellular network for DNS resolution, preventing leaks over Wi-Fi. Ensure the cellular network is active before setting it. ```kotlin val dns = NetworkDns.instance dns.setNetwork(network) // network = cellular Network from onAvailable callback val httpClient = OkHttpClient.Builder() .socketFactory(network.socketFactory) // bind socket to cellular interface .dns(dns) // resolve DNS via cellular .addNetworkInterceptor(HandleRedirectInterceptor("yourapp://callback")) .connectTimeout(10_000, TimeUnit.MILLISECONDS) .readTimeout(10_000, TimeUnit.MILLISECONDS) .build() val request = Request.Builder() .url("https://api.ipification.com/auth/realms/ipification/protocol/openid-connect/auth?...") .build() httpClient.newCall(request).enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { Log.i("IPification", "Response: ${response.body?.string()}") } override fun onFailure(call: Call, e: IOException) { Log.e("IPification", "Request failed: ${e.message}") } }) ``` -------------------------------- ### Add Dependencies for Phone Number Hint API Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/android-phone-number-hint.md Include the necessary Google Play Services Auth dependency and optionally the libphonenumber library for parsing phone numbers. ```groovy // app/build.gradle implementation 'com.google.android.gms:play-services-auth:21.3.0' // Optional: for parsing/formatting phone numbers implementation("com.googlecode.libphonenumber:libphonenumber:8.13.24") ``` -------------------------------- ### Authorization Request Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/ios_sdk_core_document.md Initiates the authorization process for IPification authentication. This request should be made via the cellular network. ```APIDOC ## GET https://api.ipification.com/auth/realms/ipification/protocol/openid-connect/auth ### Description Initiates the IPification authentication flow by requesting authorization. This endpoint should be called via the cellular network. ### Method GET ### Endpoint https://api.ipification.com/auth/realms/ipification/protocol/openid-connect/auth ### Parameters #### Query Parameters - **response_type** (string) - Required - Must be 'code'. - **client_id** (string) - Required - Unique identifier of the client provided by IPification. - **redirect_uri** (string) - Required - The client's callback URI to redirect back to after authentication. Must be pre-registered with IPification. - **scope** (string) - Required - Use 'openid ip:phone_verify' for phone number verification. - **state** (string) - Required - An opaque value used to maintain state between the request and callback. - **login_hint** (string) - Optional - End-user phone number in E.164 format without the leading '+'. - **mcc** (string) - Optional - Mobile Country Code. - **mnc** (string) - Optional - Mobile Network Code. - **consent_id** (string) - Optional - Unique ID for consent, if audit is required. - **consent_timestamp** (string) - Optional - The timestamp when consent was accepted by the end-user, in UNIX time format (seconds). ### Response #### Success Response (200) - **redirect_uri** (string) - Contains the callback URI with a 'code' and 'state' parameter upon successful authentication. #### Redirection Response (301, 302, 303) - The response will be a redirection URL to continue the authentication flow, potentially through a telco provider's service. ### Request Example ``` GET https://api.ipification.com/auth/realms/ipification/protocol/openid-connect/auth?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=openid ip:phone_verify&state=random_state_string&login_hint=16045551212 ``` ### Response Example (200 OK) ``` YOUR_REDIRECT_URI?code=abcxyz&state=random_state_string ``` ### Response Example (30x Redirection) ``` https://mnv.telco.com/webhook/api/webhook/auth?state=xyzabc ``` ``` -------------------------------- ### iOS: IPificationService Coverage and Auth Flow Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Initiates the IPification coverage check, which automatically chains into the authentication flow on success. Handles success callbacks to extract the authorization code and error callbacks for fallback mechanisms. ```swift let service = IPificationService() // Step 1: Check coverage (automatically chains into auth on success) service.performCheckCoverage( clientID: "your-client-id", redirectUri: "yourapp://callback", phoneNumber: "19876543210" // E.164 without leading + ) // IPificationService internally calls performAuth on coverage success: // service.performAuth(clientID:redirectUri:phoneNumber:) // // IPificationCoreService sets the required cellular interface: // let params = NWParameters(tls: tlsOptions, tcp: tcpOptions) // params.requiredInterfaceType = .cellular // connection = NWConnection(host: host, port: port, using: params) // // onSuccess callback receives the redirect_uri with code: // "yourapp://callback?code=AbCdEfGh&state=ip-sdk-AbCdEfGh12345678" // // Extract code from success response: let ipCore = IPificationCoreService(REDIRECT_URI: "yourapp://callback") ipCore.onSuccess = { response in if let code = ipCore.getCode(response: response) { print("Authorization code: \(code)") // Send `code` to backend for S2S token exchange } } ipCore.onError = { error in print("Error: \(error)") // Fallback to SMS / other auth } ipCore.connectTo(urlString: authUrl, requestType: .auth) ``` -------------------------------- ### Android OKHttp3 Dependency Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/README.md Include this dependency to use OKHttp3 version 5, which supports binding to cellular networks and targeting DNS for IPv6/v4 compatibility. ```groovy implementation 'com.squareup.okhttp3:okhttp:5.3.2' ``` -------------------------------- ### Custom DNS Resolver for Cellular Networks (Android) Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/android_sdk_core_document.md Implements a custom DNS resolver that prioritizes cellular network usage and IPv4 over IPv6 for hostname resolution. Requires Android Lollipop (API 21) or higher. ```kotlin import android.net.Network import android.os.Build import android.os.Build.VERSION_CODES import okhttp3.Dns import java.net.InetAddress import java.net.UnknownHostException class NetworkDns private constructor() : Dns { private var mNetwork: Network? = null fun setNetwork(network: Network?) { mNetwork = network } @Throws(UnknownHostException::class) override fun lookup(hostname: String): List { return if (mNetwork != null && Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { try { val inetAddressList: MutableList = ArrayList() val inetAddresses = mNetwork!!.getAllByName(hostname) for (inetAddress in inetAddresses) { if (inetAddress is Inet4Address) { inetAddressList.add(0, inetAddress) } else { inetAddressList.add(inetAddress) } } inetAddressList } catch (ex: NullPointerException) { try { Dns.SYSTEM.lookup(hostname) } catch (e: UnknownHostException) { Arrays.asList(*InetAddress.getAllByName(hostname)) } } catch (ex: UnknownHostException) { try { Dns.SYSTEM.lookup(hostname) } catch (e: UnknownHostException) { Arrays.asList(*InetAddress.getAllByName(hostname)) } } } else Dns.SYSTEM.lookup(hostname) } companion object { private var sInstance: NetworkDns? = null val instance: NetworkDns get() { if (sInstance == null) { sInstance = NetworkDns() } return sInstance!! } } } ``` -------------------------------- ### Show IM Push Notification (Android Java) Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Displays a system notification for IM authentication triggered by a push notification. The notification opens the IMVerificationActivity and uses SDK configuration for request codes and notification IDs. ```java // Android (Java) — show IPification IM notification public void showIPNotification(Context context, String title, String body, int icon) { Intent intent = new Intent(context, IMVerificationActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ? PendingIntent.getActivity(context, IPConfiguration.getInstance().getREQUEST_CODE(), intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE) : PendingIntent.getActivity(context, IPConfiguration.getInstance().getREQUEST_CODE(), intent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "ip_notification_cid") .setSmallIcon(icon) .setContentTitle(title) .setContentText(body) .setAutoCancel(true) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) .setPriority(Notification.PRIORITY_MAX) .setContentIntent(pendingIntent); NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel ch = new NotificationChannel( "ip_notification_cid", "ip_notification", NotificationManager.IMPORTANCE_HIGH); ch.enableVibration(true); nm.createNotificationChannel(ch); } nm.notify(IPConfiguration.getInstance().getNOTIFICATION_ID(), builder.build()); } ``` -------------------------------- ### Android Request Network via ConnectivityManager Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/README.md Use the ConnectivityManager to request a network using the previously built NetworkRequest and provide the NetworkCallback to handle the connection lifecycle. ```kotlin val manager = mContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager manager.requestNetwork( builder.build(), mNetworkCallBack) ``` -------------------------------- ### Android Phone Number Hint API Integration Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Use Google's Phone Number Hint API to retrieve the user's phone number without manual entry. This requires Play Services and does not need special permissions. Ensure you have the correct Gradle dependency. ```kotlin // Android (Kotlin) — Option 1: Google Phone Number Hint API (no permissions) // build.gradle: implementation 'com.google.android.gms:play-services-auth:21.3.0' val request = GetPhoneNumberHintIntentRequest.builder().build() Identity.getSignInClient(this) .getPhoneNumberHintIntent(request) .addOnSuccessListener { pendingIntent -> phoneNumberHintIntentResultLauncher.launch( IntentSenderRequest.Builder(pendingIntent).build() ) } .addOnFailureListener { e -> Log.e("PhoneHint", "Hint failed: $e") } ``` ```kotlin private val phoneNumberHintIntentResultLauncher = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result -> if (result.resultCode == Activity.RESULT_OK && result.data != null) { val phoneNumber = Identity.getSignInClient(this) .getPhoneNumberFromIntent(result.data) // phoneNumber = "+19876543210" // Strip the '+' and pass to IPification: val msisdn = phoneNumber.trimStart('+') ipService.performCoverageRequest(this, "live", msisdn, CLIENT_ID, REDIRECT_URI, authCallback) } } ``` -------------------------------- ### Perform Cellular Network Request (Android) Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/android_sdk_core_document.md Initiates a network request, prioritizing cellular data if Wi-Fi is unavailable. Handles different Android versions for network request timeouts. ```kotlin import android.annotation.TargetApi import android.content.Context import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkRequest import android.os.Build import android.util.Log import com.ipification.mobile.sdk.android.interceptor.HandleRedirectInterceptor import com.ipification.mobile.sdk.android.request.AuthRequest import com.ipification.mobile.sdk.android.utils.LogUtils import com.ipification.mobile.sdk.android.utils.NetworkUtils import com.ipification.mobile.sdk.android.utils.debug import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response import java.util.* // Manifest.xml: required permission: INTERNET, ACCESS_WIFI_STATE, ACCESS_NETWORK_STATE, CHANGE_NETWORK_STATE, android:usesCleartextTraffic="true" // external library: OkHttp : com.squareup.okhttp3:okhttp 5.x class CellularConnection { @TargetApi(Build.VERSION_CODES.LOLLIPOP) fun performRequest(context: Context, authRequest: AuthRequest) { // wifi is OFF, DATA is ON -> request with current network interface if (NetworkUtils.isMobileDataEnabled(context) && !NetworkUtils.isWifiEnabled(context)) { processRequest(context, null, authRequest) } else { requestCellularNetwork(context, authRequest) } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private fun requestCellularNetwork(context: Context, authRequest: AuthRequest) { // 1. force network connection via cellular interface // If your app supports Android 21+, you need to implement handling timeout manually. // Android 21++ support requestNetwork (NetworkRequest request, // ConnectivityManager.NetworkCallback networkCallback) // Android 26++ support requestNetwork(NetworkRequest request, // ConnectivityManager.NetworkCallback networkCallback, // int timeoutMs) // https://developer.android.com/reference/android/net/ConnectivityManager#requestNetwork(android.net.NetworkRequest,%20android.net.ConnectivityManager.NetworkCallback) val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val request = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { connectivityManager.requestNetwork( request, object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { processRequest(context, network, authRequest) } override fun onUnavailable() { // cellular network is not available, call the callback error Log.e("TestAPI", "cellular network is not available") } }, 5000 // CONNECT_NETWORK_TIMEOUT ) } else { // manual adding timeout connectivityManager.requestNetwork( request, object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { isReceiveResponse = true processRequest(context, network, authRequest) } override fun onUnavailable() { isReceiveResponse = true // cellular network is not available, callback Log.e("CellularConnection", "cellular network is not available") } } ) Timer().schedule(object : TimerTask() { override fun run() { LogUtils.debug("timeout isReceiveResponse=${isReceiveResponse} ") if (!isReceiveResponse) { handleUnAvailableCase(cellularCallback) } } }, 5000) } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private fun processRequest(context: Context, network: Network?, authRequest: AuthRequest) { // using OkHTTP library to make the connection val httpBuilder =OkHttpClient.Builder() // add dns if needed if (network != null) { // enable socket for network httpBuilder.socketFactory(network.socketFactory) // enable DNS resolver with cellularnetwork val dns = NetworkDns.instance dns.setNetwork(network) httpBuilder.dns(dns) } //check and handle the response with redirect_uri httpBuilder.addNetworkInterceptor( HandleRedirectInterceptor( ``` -------------------------------- ### Expose Swift Class to Objective-C Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/ios_Objective-C_Guideline.md Annotate Swift classes extending NSObject with @objc to make them accessible from Objective-C. Ensure public or open modifiers for methods and properties intended for Objective-C use. ```swift @objc public class AuthorizationService: NSObject { public override init() { } @objc public var callbackFailed: ((_ response: IPificationException) -> Void)? @objc public var callbackSuccess: ((_ response: AuthorizationResponse) -> Void)? @objc public func startAuthorization(_ authRequest : AuthorizationRequest? = nil){ ... } } ``` -------------------------------- ### Android: IPificationCoreService Cellular Binding with OkHttp Source: https://context7.com/bvantagelimited/ipification-mobile-sdk-code-snippet/llms.txt Performs low-level cellular network binding using Android's ConnectivityManager and OkHttp. Handles the authentication redirect chain and extracts the authorization code upon successful redirection to the specified URI. ```kotlin val ipCore = IPificationCoreService(redirectUri = "yourapp://callback") ipCore.connectTo( context = this, urlString = "https://api.ipification.com/auth/realms/ipification/protocol/openid-connect/auth" + "?response_type=code&client_id=your-client-id" + "&redirect_uri=yourapp%3A%2F%2Fcallback" + "&scope=openid%20ip%3Aphone_verify&state=ip-sdk-test123" + "&login_hint=19876543210", apiType = APIType.AUTH, callback = object : IPCallback { override fun onSuccess(response: String) { // response contains the full redirect_uri with code val code = Uri.parse(response).getQueryParameter("code") // Exchange code on your backend } override fun onFailure(error: String) { Log.e("IPification", error) } } ) // Internal network binding (simplified): // val request = NetworkRequest.Builder() // .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) // .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build() // connectivityManager.requestNetwork(request, networkCallback, 5000 /*ms timeout*/) // // HandleRedirectInterceptor intercepts 3xx responses: // if (response.code in 300..399 && locationHeader.startsWith(redirectUri)) { // return 200 response with locationHeader as body // } ``` -------------------------------- ### iOS NWConnection Cellular Interface Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/README.md Configure NWParameters to require the cellular interface for establishing an NWConnection. This ensures the connection is attempted over the mobile network. ```swift let tcpOptions = NWProtocolTCP.Options() let params = NWParameters(tls: enableTLS ? options : nil, tcp: tcpOptions) params.requiredInterfaceType = .cellular self.connection = NWConnection.init(host: host , port: port, using: params) ``` -------------------------------- ### Android ConnectivityManager NetworkCallback Source: https://github.com/bvantagelimited/ipification-mobile-sdk-code-snippet/blob/main/README.md Implement this callback to handle network availability, unavailability, and loss events. The onAvailable callback provides the Network instance to process the connection. ```kotlin val mNetworkCallBack = object: ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { super.onAvailable(network) // TODO: process the connection via this network instance ${network} } override fun onUnavailable() { super.onUnavailable() } override fun onLost(network: Network) { super.onLost(network) } } ```