> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fintoc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# WebView integration (old)

> Integrate the Widget as a WebView in your mobile application

## Integration

To integrate the Widget in an iOS or Android WebView, load the following URL:

```text theme={null}
https://webview.fintoc.com/widget.html
```

Pass the widget configuration through the query string instead of client-side JavaScript.

<Info>
  **Using React Native?**

  Use the [`@fintoc/fintoc-react-native`](https://github.com/fintoc-com/fintoc-react-native) npm library to integrate the WebView into your application.
</Info>

## How it works

Pass query parameters to configure the Fintoc WebView for the product you want to use:

```text Text theme={null}
https://webview.fintoc.com/widget.html
  ?public_key=pk_live_00000
  &holder_type=individual
  &product=payments
  &country=cl
  &widget_token=pi_XXXXXX_sec_YYYYYYYY
```

| Parameter        | Type                 | Description                                                                                                                                                                                                                                                                    |
| ---------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `public_key`     | `string`             | Public key that identifies your web application or page in Fintoc. Fintoc assigns each `Link` to the organization or user that owns the public key.<br />The prefix determines the environment: sandbox keys start with `pk_test_`, and production keys start with `pk_live_`. |
| `holder_type`    | `string`             | Type of account to connect to Fintoc. One of `business` or `individual`. Payment initiation requires `individual`.                                                                                                                                                             |
| `product`        | `string`             | Product and type of `Link` to create. One of `movements`, `subscriptions`, `invoices`, or `payments`.                                                                                                                                                                          |
| `country`        | `string`             | Two-letter ISO 3166-1 alpha-2 country code. One of `cl` or `mx`. Defaults to `cl`.                                                                                                                                                                                             |
| `institution_id` | `string`             | Identifier of [a financial institution](/v2023-11-15/guides/movements/overview-data-aggregation/products-and-institutions-movements). When provided, the widget preselects the institution. For example, `mx_banco_banamex` opens the widget with Banamex selected.            |
| `username`       | `string` or `object` | Username to prefill when making a payment. See the [username object attributes](#username-object). If you provide a string, the `editable` attribute uses the default value.                                                                                                   |
| `webhook_url`    | `string`             | URL that receives a request containing the new `Link` and its `link_token` after successful creation. Used only with `movements` and `invoices`; you do not need this parameter for `payments` or `subscriptions`.                                                             |
| `widget_token`   | `string`             | Token created by your backend to initialize and configure the widget. Only `payments` and `subscriptions` use this parameter.                                                                                                                                                  |

### Username object

To prefill a username and override the default values, send an object with these attributes:

```
username = {
  value: "123456789",
  editable: true
}
```

Use the following query-string format to include nested parameters:

```text theme={null}
queryString = "
  public_key=pk_live_XXX
  &holder_type=individual
  &product=payments
  &username[value]=12345678-9
  &username[editable]=false
  &country=cl
  &widget_token=pi_XXX
"
```

Libraries such as [qs](https://www.npmjs.com/package/qs) can format a nested object for you.

| Attribute  | Type      | Description                                                                                                               |
| :--------- | :-------- | :------------------------------------------------------------------------------------------------------------------------ |
| `value`    | `string`  | Username to prefill in the widget. In Chile, use the user's Chilean tax ID (RUT). In Mexico, use the user's phone number. |
| `editable` | `boolean` | Whether the user can edit the field in the widget. Defaults to `true`.                                                    |

## Usage example

Use the following client-side examples to integrate the WebView on Android and iOS.

Android client:

```kotlin theme={null}
override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_main)
  supportActionBar?.hide()
    
  val widgetInitizalizationUrl = generateWidgetInitializationUrl()
  
  // Modify Webview settings - all of these settings may not be applicable
  // or necessary for your integration.
  val fintocWebview = findViewById<WebView>(R.id.webview)
  val webSettings = fintocWebview.settings
  webSettings.javaScriptEnabled = true
  webSettings.javaScriptCanOpenWindowsAutomatically = true
  webSettings.domStorageEnabled = true
  webSettings.cacheMode = WebSettings.LOAD_NO_CACHE
  webSettings.useWideViewPort = true
  WebView.setWebContentsDebuggingEnabled(true)

  fintocWebview.loadUrl(widgetInitizalizationUrl.toString())
}

private fun generateWidgetInitializationUrl() : Uri {
  val builder = Uri.parse("https://webview.fintoc.com/widget.html")
    .buildUpon()
    .appendQueryParameter("holder_type", "individual")
    .appendQueryParameter("product", "payments")
    .appendQueryParameter("public_key", "pk_live_INSERT_YOUR_API_KEY")
    .appendQueryParameter("widget_token", "pi_INSERT_YOUR_sec_WIDGET_TOKEN")
    return builder.build()
}
```

iOS client:

```swift theme={null}
import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, UIScrollViewDelegate, WKUIDelegate {

    private var webView: WKWebView!

    override func loadView() {
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        webView.navigationDelegate = self
        webView.allowsBackForwardNavigationGestures = false
        webView.scrollView.bounces = false
        webView.isMultipleTouchEnabled = false
       	webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true

        // zoom
        webView.scrollView.delegate = self
        webView.scrollView.minimumZoomScale = 1.0
        webView.scrollView.maximumZoomScale = 1.0

        let url = generateInitializationURL()
        webView.load(URLRequest(url: url))
    }

    override var prefersStatusBarHidden : Bool {
        return true
    }

    @objc(scrollViewWillBeginZooming:withView:) func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
        scrollView.pinchGestureRecognizer?.isEnabled = false
    }

  	func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }
        if let url = navigationAction.request.url {
            UIApplication.shared.open(url)
        }
        return nil
    }

    func generateInitializationURL() -> URL {
        let params = [
            "holder_type": "individual",
            "product": "payments",
            "public_key": "pk_live_INSERT_YOUR_API_KEY",
            "widget_token": "pi_INSERT_YOUR_sec_WIDGET_TOKEN",
        ]
        var components = URLComponents()
        components.scheme = "https"
        components.host = "webview.fintoc.com"
        components.path = "/widget.html"
        let queryItems = params.map { URLQueryItem(name: $0, value: $1) }
        components.queryItems = queryItems
        return components.url!
    }
  
    func webView(
      _ webView: WKWebView,
      decidePolicyFor navigationAction: WKNavigationAction,
      decisionHandler: @escaping ((WKNavigationActionPolicy) -> Void)
    ) {
      guard let url = navigationAction.request.url else {
        decisionHandler(.allow)
        return
      }
      let linkScheme = "fintocwidget";
      let actionScheme = url.scheme;
      let actionType = url.host ?? "";
      if actionScheme == linkScheme {
        switch actionType {
          case "succeeded":
          	print("Succeeded!")
          	break
          case "exit":
          	print("Exited")
          	break
          default:
          	print("Another widget action detected: \(actionType)")
          	break
        }
        decisionHandler(.cancel)
        return
      } else {
        decisionHandler(.allow)
      }
}
```

The Swift example uses the `webView` method to handle links from the WebView. The example opens links in Safari, but you can open them inside your application instead. With [Payment Initiation](/v2023-11-15/guides/payments/overview-payment-initiation), the customer can download the transaction receipt after completing the payment flow. Allow the WebView to open these links.

## WebView redirections

After integrating the WebView, handle its events through these redirects:

| Event       | Redirect URL                                              | Description                                                                                                                         |
| :---------- | :-------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------- |
| `onSuccess` | `fintocwidget://succeeded`                                | Occurs after the flow finishes successfully.                                                                                        |
| `onExit`    | `fintocwidget://exit`                                     | Occurs after the customer closes the Widget before completing the flow.                                                             |
| `onEvent`   | `fintocwidget://event/\{event\_name}?queryparam=\{value}` | Occurs for each event available in the widget. See [Widget events](/v2023-11-15/guides/resources/widget/widget-events) for details. |

<Warning>
  **`onEvent` (WebView)**

  The WebView sends `onEvent` redirects by default. Handle these redirects to prevent them from interrupting your Widget integration. You can also pass the `_on_event` query parameter to `https://webview.fintoc.com/widget.html`, for example, `https://webview.fintoc.com/widget.html?[...]&_on_event=true`.
</Warning>

Use the following client-side examples to handle these redirects on Android and iOS.

Android client (Kotlin):

```kotlin theme={null}
webview.webViewClient = object : WebViewClient() {
  override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
    val parsedUri = Uri.parse(url)
    if (parsedUri.scheme.equals("fintocwidget")) {
      val action: String? = parsedUri.host
      val linkData: HashMap<String, String?>? = parseLinkUriData(parsedUri)
      if (action.equals("succeeded")) {
        // onSuccess
      }
      if (action.equals("exit")) {
        // onExit
      }
    }
    return true
  }
}
```

Android client (Java):

```java theme={null}
webview.setWebViewClient(new WebViewClient() {
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
    Uri parsedUri = Uri.parse(url);
    if (parsedUri.getScheme().equals("fintocwidget")) {
      String action = parsedUri.getHost();
      HashMap<String, String> linkData = parseLinkUriData(parsedUri);
      if (action.equals("succeeded")) {
        // onSuccess
      }
      if (action.equals("exit")) {
        // onExit
      }
    }
  }
}
```

iOS client:

```swift theme={null}
func webView(
          _ webView: WKWebView,
          decidePolicyFor navigationAction: WKNavigationAction,
          decisionHandler: @escaping ((WKNavigationActionPolicy) -> Void)
        ) {
          guard let url = navigationAction.request.url else {
            decisionHandler(.allow)
            return
          }
          let linkScheme = "fintocwidget";
          let actionScheme = url.scheme;
          let actionType = url.host ?? "";
          if actionScheme == linkScheme {
            switch actionType {
            case "succeeded":
              // onSuccess
              break
            case "exit":
              // onExit
              break
            default:
              print("Widget action detected: \(actionType)")
              break
            }
            decisionHandler(.cancel)
            return
          } else {
            decisionHandler(.allow)
          }
    }
```

<Warning>
  **Add the `fintocwidget` URL scheme on iOS**

  Before integrating the Fintoc Widget with your iOS application, register `fintocwidget` as a URL scheme in the application's `Info.plist` file. This registration allows the application to handle Widget redirects.
</Warning>

iOS client configuration:

```xml theme={null}
<key>CFBundleURLTypes</key>
	<array>
		<dict>
			<key>CFBundleURLSchemes</key>
			<array>
				<string>fintocwidget</string>
			</array>
			<key>CFBundleURLName</key>
			<string>your.bundle.id</string>
		</dict>
	</array>
```
