Skip to content

About

This is a SDK intended for connecting Fintoc easily

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Fintoc Android SDK

English · Español · Français · Português

Unofficial, community-built Kotlin and Jetpack Compose SDK to add Fintoc payments (such as SPEI in Mexico) and bank connections to an Android app. It wraps Fintoc's Widget, is built Compose-first and uses Koin for dependency injection.

Not affiliated with Fintoc. This is a community project. "Fintoc" is a trademark of its respective owners.

Status: ready for 1.0.0. Everything planned for the first release is in place: the Widget for Compose and an Activity host for apps without Compose, the hosted checkout, four languages with a manual override, accessibility checks, a sample app and publishing to Maven Central. The first release is 1.0.0, and it is not published yet: see Installation.

Modules

Module Purpose
fintoc-sdk The library published to Maven: mx.dev1.fintoc:fintoc-sdk.
app Sample application that consumes the SDK. Not published.
flowchart LR
    host["Your app"] --> sdk["fintoc-sdk"]
    sample["app (sample)"] --> sdk
    sdk --> koin["Koin (isolated container)"]
    sdk --> compose["Jetpack Compose"]
Loading

Requirements

Tool Version
JDK to launch Gradle 11 or newer (the build provisions a JDK 21 toolchain automatically)
Android SDK Platform 37 (compileSdk)
Android Studio A recent stable release that supports Android Gradle Plugin 9.4
Device or emulator Android 6.0 (API 23) or newer, only needed for instrumented tests

Supported on Android 6.0 (API 23) and newer. The Jetpack Compose and AndroidX libraries that the SDK builds on need compileSdk 37, and the SDK says so in its own metadata: an app that compiles against an older API stops with a clear message. Installation lists what your own app needs.

Installation

Not published yet. The first release has not reached Maven Central. Until it does, build the library from source: run ./gradlew :fintoc-sdk:publishToMavenLocal, add mavenLocal() to the repositories of your app, and use the VERSION_NAME of gradle.properties.

dependencies {
    implementation("mx.dev1.fintoc:fintoc-sdk:<version>")
}

What your app needs:

Requirement Why
compileSdk 37 or higher The Compose and AndroidX libraries that the SDK builds on require it. Gradle stops with a clear message if yours is lower, and pinning an older Compose BOM does not help.
Android Gradle Plugin One that supports compileSdk 37 This project uses 9.4.1.
minSdk 23 Android 6.0.
Kotlin 2.2 or newer Checked with compilers 2.2.0 and 2.4.20. The library is compiled at language level 2.2, and asks only for a 2.2 standard library, so it does not push your app to a newer Kotlin.
Jetpack Compose Only for the FintocWidget composable An app without Compose uses FintocWidgetContract, with no Compose plugin or code of its own. The Compose libraries still join your app, because the SDK depends on them.
Permissions and Activities Nothing to declare The SDK adds the INTERNET permission and its own private Activity to your manifest.

If you publish an Android App Bundle and want to force the language of the SDK's own texts, turn off language splits: see Languages.

Quick start

git clone git@github.com:DEV1-Softworks/fintoc-android.git
cd fintoc-android

./gradlew :app:assembleDebug          # build the sample app
./gradlew testDebugUnitTest           # unit tests (JUnit, Robolectric, Mockito)

To try the SDK against Fintoc's sandbox with the sample app, follow the sample app guide.

Using the SDK from an app:

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Fintoc.initialize(
            context = this,
            configuration = FintocConfiguration(publicKey = "pk_test_…"),
        )
    }
}

Describe what to show with FintocWidgetOptions. The tokens come from your backend:

val options = FintocWidgetOptions.Payments(sessionToken = tokenFromYourBackend)

Show the Widget from Compose with FintocWidget. When the session token comes from your backend, pass a suspend provider: the SDK calls it once for each attempt and shows a progress indicator while it waits.

FintocWidget(
    sessionTokenProvider = { myBackend.createSessionToken(orderId) },
    onEvent = { event ->
        when (event) {
            is FintocWidgetEvent.Succeeded -> showReceipt()
            FintocWidgetEvent.Exited -> closeScreen()
            is FintocWidgetEvent.Occurred -> Unit
        }
    },
    modifier = Modifier.fillMaxSize(),
)

If you already hold the options, for example Movements, which needs no token, pass them directly with FintocWidget(options = …, onEvent = …). The SDK declares the INTERNET permission itself, so your app does not have to.

Apps without Compose open the Widget in a screen of its own, with the Activity Result API:

private val fintocWidget = registerForActivityResult(FintocWidgetContract()) { result ->
    when (result) {
        is FintocWidgetResult.Succeeded -> checkThePaymentOnYourBackend()
        FintocWidgetResult.Exited -> Unit
    }
}

fintocWidget.launch(FintocWidgetOptions.Payments(sessionToken = tokenFromYourBackend))

Without that API, call FintocWidgetContract().createIntent(…) and parseResult(…) from startActivityForResult.

The SDK's own texts (loading message, errors, buttons) come in English, Spanish, French and Portuguese, and follow the language of the device. To force one, for example because your app has its own language picker:

FintocConfiguration(publicKey = "pk_test_…", language = FintocLanguage.SPANISH)

The Widget page is Fintoc's and keeps its own language.

To send the customer to a Fintoc-hosted checkout page instead, open the redirect_url of your Checkout Session in a Custom Tab and read what comes back to your app:

val nonce = UUID.randomUUID().toString() // keep it with the order; send both addresses to your backend
val checkout = FintocHostedCheckout(
    successUrl = "https://merchant.com/pay/success?n=$nonce",
    cancelUrl = "https://merchant.com/pay/cancel?n=$nonce",
)

checkout.open(this, redirectUrlFromYourBackend)

// In the Activity that receives those addresses, in onCreate and onNewIntent:
when (checkout.outcomeOf(intent)) {
    FintocHostedCheckoutOutcome.Succeeded -> showThatTheOrderIsBeingConfirmed()
    FintocHostedCheckoutOutcome.Cancelled -> showThatThePaymentWasCancelled()
    FintocHostedCheckoutOutcome.Unrelated -> Unit
}

The returned address is only a hint: confirm payments with Fintoc webhooks on your backend.

Security model

  • The app only holds the public key (pk_test_ or pk_live_). The SDK refuses secret keys (sk_…).
  • Your backend creates the Checkout Session with its secret key and hands the short-lived session_token to the app; the app passes it to the SDK.
  • Tokens are never logged: the toString() of every option redacts them.
  • The Widget runs in a hardened WebView: no access to files or content providers, no insecure subresources, Safe Browsing on, no JavaScript interface, and certificate errors are never accepted. The SDK never turns WebView debugging on.
  • The WebView stays on Fintoc's hosts (webview.fintoc.com, wizard.fintoc.com and js.fintoc.com). Other https links, such as the payment voucher, open in the browser, and everything else is blocked.
  • When the page cannot be loaded, the SDK shows its own message. The error page of the WebView would print the address, and the address holds the session token.
  • The screen for apps without Compose is private to your app and hides itself from screenshots and the recent apps list. Session tokens never travel inside an Intent.
  • A hosted checkout only opens https addresses on a fintoc.com subdomain, in a Custom Tab whose address bar stays visible. The address that comes back to your app can be forged by any app on the device, so the SDK requires the secret value that you put in your own return address to come back too.
  • What the Widget reports to the app is not proof of payment. Confirm payments with Fintoc webhooks on your backend.

Documentation

Topic English Español Français Português
Overview this file es fr pt
Architecture en es fr pt
Sample app en es fr pt
Releasing en es fr pt
Changelog en es fr pt
Contributing en es fr pt

Credits and license

The Widget integration follows Fintoc's public documentation and the behavior of the official React Native SDK. The MIT notice of the community Swift client sergiocampama/Fintoc (© 2021 Sergio Campamá) is kept in NOTICE in case code derived from it is added.

This project is licensed under the Apache License 2.0.

About

This is a SDK intended for connecting Fintoc easily

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages