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

# Integración con WebView (ANTIGUA)

> Referencia para integrar el Widget como un WebView en tu aplicación móvil

## Integración

Para integrar el Widget mediante un WebView en iOS y Android, debes usar la siguiente URL:

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

La configuración del widget se debe pasar a través de un *querystring* en lugar de usar JavaScript del lado del cliente.

<Info>
  **¿Usas React Native?**

  ¡Revisa nuestra librería de npm [`@fintoc/fintoc-react-native`](https://github.com/fintoc-com/fintoc-react-native) para integrar el WebView a tu aplicación rápidamente!
</Info>

## Cómo funciona

Al incluir el WebView de Fintoc en tu aplicación móvil, debes pasar los siguientes *query params* para configurarlo, según el producto que quieras usar:

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

| Parámetro        | Tipo                | Descripción                                                                                                                                                                                                                                                                                                                                                                                                        |
| ---------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `public_key`     | `string`            | El `public_key` se usa para identificar tu aplicación o página web dentro de Fintoc. Los Links creados con un `public_key` se asignarán a la organización o usuario propietario de dicho `public_key`.<br />Este token determinará si estás usando el entorno de sandbox o de producción. Recuerda que el `public_key` del sandbox comienza con `pk_test_`, mientras que el de producción comienza con `pk_live_`. |
| `holder_type`    | `string`            | El parámetro `holder_type` puede ser `business` o `individual`, y determina el tipo de cuenta que se conectará a Fintoc. Para payment initiation siempre debes usar `individual`.                                                                                                                                                                                                                                  |
| `product`        | `string`            | El parámetro `product` puede ser `movements`, `subscriptions`, `invoices` o `payments`, y determina el producto y el tipo de `Link` que se creará.                                                                                                                                                                                                                                                                 |
| `country`        | `string`            | El parámetro `country` debe ser el código `ISO 3166-1 alfa-2` del país al que estás intentando conectarte. Puede ser `cl` o `mx`. Por defecto es `cl`.                                                                                                                                                                                                                                                             |
| `institution_id` | `string`            | Identificador único de [una institución financiera](/es/guides/movements/overview-data-aggregation/products-and-institutions-movements). Si se incluye, el widget preselecciona la institución. Por ejemplo, `mx_banco_banamex` abre el widget con Banamex seleccionado.                                                                                                                                           |
| `username`       | `string` u `object` | Nombre de usuario para rellenar previamente al realizar un pago. Consulta los [atributos del objeto username](/es/guides/resources/widget/widget-webview-integration-old#username-object). Si envías un string, el widget usa el valor por defecto de `editable`.                                                                                                                                                  |
| `webhook_url`    | `string`            | URL que recibe una solicitud con el nuevo `Link` y su `link_token` después de su creación exitosa. Solo se usa con `movements` e `invoices`; no necesitas `webhook_url` para `payments` ni `subscriptions`.                                                                                                                                                                                                        |
| `widget_token`   | `string`            | Token generado por el backend que inicializa y configura el widget. Solo `payments` y `subscriptions` usan este parámetro.                                                                                                                                                                                                                                                                                         |

### Objeto Username

Para rellenar previamente un nombre de usuario y cambiar los valores por defecto, puedes enviar un objeto con los siguientes atributos:

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

También puedes incluir parámetros anidados en tu query utilizando el siguiente formato de query string:

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

Librerías como [qs](https://www.npmjs.com/package/qs) pueden ayudarte a formatear automáticamente un objeto anidado.

| Atributo   | Tipo      | Descripción                                                                                                                                                  |
| :--------- | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `value`    | `string`  | El nombre de usuario que se rellenará previamente en el widget. En Chile debes ingresar el RUT del usuario y en México debes ingresar su número de teléfono. |
| `editable` | `boolean` | Si el campo es editable o no en el widget. Por defecto está configurado como `true`.                                                                         |

## Ejemplo de uso

Aquí tienes algunos *snippets* para que empieces lo más rápido humanamente posible:

**Cliente (Android, Kotlin)**

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

**Cliente (iOS, Swift)**

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

Fíjate que el ejemplo en Swift tiene un método `webView`. Este método define lo que sucede cuando un usuario hace clic en un enlace dentro del WebView. En el ejemplo, el enlace se abre en Safari, pero puedes personalizar este comportamiento a tu gusto (los enlaces podrían abrirse dentro de la misma aplicación, por ejemplo). Esto es importante porque, al usar el producto de [Payment Initiation](/es/guides/payments/overview-payment-initiation), después de finalizar el flujo de pago el usuario puede hacer clic en un enlace para descargar el comprobante de la transacción. **Debes permitir que los enlaces se abran**.

## Redirecciones del WebView

Una vez integrado el WebView, puedes interactuar con sus eventos usando redirecciones.

| Método      | URL de redirección                                     | Descripción                                                                                                                                                     |
| :---------- | :----------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onSuccess` | `fintocwidget://succeeded`                             | Este evento ocurrirá después de que el flujo finalice exitosamente.                                                                                             |
| `onExit`    | `fintocwidget://exit`                                  | Este evento ocurrirá después de que un usuario cierre el Widget antes de completar el flujo.                                                                    |
| `onEvent`   | `fintocwidget://event/{event_name}?queryparam={value}` | Este evento ocurrirá en cada evento disponible del widget. Puedes encontrar más información en [Eventos del widget](/es/guides/resources/widget/widget-events). |

<Warning>
  **onEvent (WebView)**

  El evento `onEvent` está habilitado por defecto. Maneja la redirección `onEvent` para evitar que la integración del Widget se rompa cuando el WebView reciba este evento.
</Warning>

Para usar estos métodos en Android e iOS, puedes usar los siguientes *snippets*:

**Cliente (Android, 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
  }
}
```

**Cliente (Android, 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
      }
    }
  }
}
```

**Cliente (iOS, Swift)**

```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>
  **Agrega el esquema de URL `fintocwidget` en iOS**

  Antes de integrar el Widget de Fintoc con tu aplicación iOS, agrega `fintocwidget` como un esquema de URL permitido en el archivo `Info.plist` de la aplicación.
</Warning>

**Cliente (iOS 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>
```
