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

> Reference to integrate the Widget as a WebView on your mobile application

## Integration

To integrate the Widget using a WebView on iOS and Android, you must use the following HTML:

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

The widget configuration needs to be passed through a *querystring* instead of using client side JavaScript.

<Info>
  **Using React Native?**

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

## How it works

When including the Fintoc WebView in your mobile application, you need to pass the following *query params* to configure it, depending on the product that 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` | The `public_key` is used to identify your web application or web page within Fintoc. Links created with a `public_key` will get assigned to the organization or user that owns said `public_key`.<br />This token will determine whether you're using the sandbox or the production environment. Remember that the `public_key` of the sandbox starts with `pk_test_`, while the production one starts with `pk_live_`. |
| `holder_type`   | `string` | The `holder_type` parameter can be `business` or `individual`, and determines the type of account that will be connected to Fintoc.<br /><br />\* \*This parameter is not required for the Payment Initiation product\*\*.                                                                                                                                                                                              |
| `product`       | `string` | The `product` parameter can be `movements`, `subscriptions`, `invoices`,  or `payments`, and determines the product and type of **Link** that will be created.                                                                                                                                                                                                                                                          |
| `country`       | `string` | The `country` parameter must be the `ISO 3166-1 alfa-2` code of the country to which you're trying to connect. It can be `cl` or `mx`. Defaults to `cl`. **This parameter is not required for the Payment Initiation product**.                                                                                                                                                                                         |
| `webhook_url`   | `string` | \* \*Only used for `movements` and `invoices` products\*\*, if you are integrating `payments` or `subscriptions` you don't need this.<br /><br />The `webhook_url` parameter corresponds to the URL that will get a request with the new **Link** after its successful creation, including its **link\_token**.                                                                                                         |
| `session_token` | `string` | **Only used for the Payment Initiation product**<br />The `sessionToken` parameter corresponds to the token created by the backend when creating a [Checkout Session](https://dash.readme.com/go/fintoc?redirect=%2Fv2023-11-15%2Freference%2Fcreate-checkout-session)  and it is used to deploy and configure the Widget.                                                                                              |
| `widget_token`  | `string` | The `widget_token` parameter corresponds to the token created by the backend that initializes and configures the widget for the Subscriptions product.<br /><br />Right now, only the `subscriptions` product uses a `widget_token` parameter.                                                                                                                                                                          |

You can also include nested parameters in your query by using the following query string format:

```text theme={null}
queryString = "
  public_key=pk_live_XXX
  &holder_type=individual
  &product=movements
  &country=cl
  &link_token=pi_XXX
"
```

## Usage Example

Here are some *snippets* to get you started as quickly as humanly possible:

```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("product", "payments")
    .appendQueryParameter("public_key", "pk_live_INSERT_YOUR_API_KEY")
    .appendQueryParameter("session_token", "pi_INSERT_YOUR_sec_SESSION_TOKEN")
    return builder.build()
}
```

```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)
      }
}
```

Notice that the Swift example has a `webView` method. This method defines what happens when a user clicks on a link inside the WebView. On the example, the link gets opened in Safari, but you can customize this behaviour at will (links could be opened inside the same application, for example). This is important because, when using the [Payment Initiation](/v2023-11-15/docs/payments/overview-payment-initiation) product, after finishing the payment flow the user can click a link to download the transaction voucher. **You should allow links to be opened**.

## WebView Redirections

Once the WebView is integrated, you can interact with its events using redirections.

| Method      | Redirect URL                                            | Description                                                                                                                                                              |
| :---------- | :------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onSuccess` | fintocwidget://succeeded                                | This event will occur after the flow finishes successfully.                                                                                                              |
| `onExit`    | fintocwidget://exit                                     | This event will occur after a user closes the Widget prematurely.                                                                                                        |
| `onEvent`   | fintocwidget://event/\{event\_name}?queryparam=\{value} | This event will occur in every event available on the widget. More information about these events can be found [here](/v2023-11-15/docs/resources/widget/widget-events). |

<Warning>
  **onEvent (WebView)**

  The `onEvent` event for WebView is disabled by default and can be enabled by passing the *queryparam* `_on_event={any_value}` as a parameter of `https://webview.fintoc.com/widget.html` (e.g.: `https://webview.fintoc.com/widget.html?[...]&_on_event=true`). Once enabled, it will be possible to receive `onEvent` events. Starting **May 1st, 2023**, this functionality will be enabled by default, so it is necessary to handle the `onEvent` redirection before this date to avoid breaking the integration with the Widget.
</Warning>

To use these methods on Android and iOS, you can use the following *snippets*:

```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
  }
}
```

```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
      }
    }
  }
}
```

```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>
  **iOS - adding fintocwidget URL Scheme**

  Before integrating the Fintoc widget with your iOS app, it's important to add **fintocwidget** as a permitted URL scheme inside the app's Info.plist file. This is required for security reasons.
</Warning>

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