Skip to content

Wallet Screen

We provide a complete wallet experience via our WalletScreen - in both a self-managed capacity and a fully "Ansa-managed" experience.

Ansa Managed UI

The Ansa-managed screen utilizes your AnsaClient and handles ALL internal workings of the screen.

The simplest setup of WalletScreen is 4 lines.

val ansaClient = AnsaClient.init(
    /* initialization params */
)

AnsaTheme {
    AnsaWalletScreen(
        ansaClient = ansaClient,
        customerId = { /* the customer ID provided */ },
        merchantId = { /* the merchant ID provided */ },
    )
}

The Ansa managed experience also supports being used as a nested destination by providing onNavigateBack callback. In doing so, a back arrow will be placed in the Top App Bar of the screen.

AnsaWalletScreen(
    ansaClient = ansaClient,
    customerId = { /* the customer ID provided */ },
    merchantId = { /* the merchant ID provided */ },
    onNavigateBack = { navigator.pop() }
)

Self Managed UI

The WalletScreen also supports self-management via all knobs you would expect.

AnsaWalletScreen(
    title: String = stringResource(Res.string.home_screen_title),
    termsAndConditions: TermsAndConditions? = null,
    isRefreshing: Boolean,
    isSandboxMode: Boolean = false,
    merchantCardArt: String? = null,
    balance: Balance = Balance(0, LocalCurrencyFormatter.current.localCurrency()),
    alertContent: InlineAlertContent? = null,
    transactions: List<Transaction> = emptyList(),
    autoReloadConfiguration: AutoReloadConfiguration?,
    userReloadConfiguration: UserReloadConfiguration?,
    onRefresh: () -> Unit,
    onSelectPaymentMethod: (() -> Unit),
    onAddFunds: () -> Unit,
    onAutoReloadClicked: () -> Unit,
    onAddCard: (() -> Unit)? = null,
    onHowToUseBalance: (() -> Unit)? = null,
    onRedeemGiftCard: (() -> Unit)? = null,
    onNavigateBack: (() -> Unit)? = null,
    endContent: @Composable BoxScope.() -> Unit = { },
)

The data you provide will be rendered as such.

Custom Add Card Handling

In both Ansa managed and Self managed UI, we support the ability to handle/override the "Add Card" flow. This is handled by provided the onAddCard callback. This can be utilized to navigate to another screen, show a modal, etc. Once the card is successfully added via our APIs and you receive a PaymentMethod from the backend, you can inform the SDK of the change via the LocalPaymentMethodManager Composition local by calling onPaymentMethodAdded(paymentMethod). If the add flow is cancelled, simply call onCancelled

An example of this in action with a BottomSheet:

AnsaTheme {
    val paymentMethodUpdateManager = LocalPaymentMethodManager.current

    val bottomSheetState =
        rememberStandardBottomSheetState(
            initialValue = SheetValue.Hidden,
            skipHiddenState = false,
        )
    val scaffoldState =
        rememberBottomSheetScaffoldState(bottomSheetState = bottomSheetState)
    val composeScope = rememberCoroutineScope()

    BottomSheetScaffold(
        scaffoldState = scaffoldState,
        sheetShadowElevation = 8.dp,
        sheetPeekHeight = 0.dp,
        sheetContent = {
            PrimaryButtonLarge(
                modifier = Modifier.navigationBarsPadding(),
                text = "Click me",
                onClick = {
                    composeScope.launch {
                        val paymentMethod =
                            PaymentMethod(
                                card =
                                Card(
                                    brand = "visa",
                                    fingerprint = UUID.randomUUID().toString(),
                                    lastFour = "4890",
                                    firstSix = "123456"
                                ),
                                id = UUID.randomUUID().toString(),
                                type = "credit_card"
                            )

                        // notify SDK cancelled payment method selection flow
                        // paymentUpdateManager.onCancelled()

                        // notify SDK user added payment method
                        paymentMethodUpdateManager.onPaymentMethodAdded(paymentMethod)
                        bottomSheetState.hide()
                    }
                }
            )
        }
    ) {
        BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
            AnsaWalletScreen(
                ansaClient = ansaClient,
                customerId = { BuildConfig.CUSTOMER_ID },
                merchantId = { BuildConfig.MERCHANT_ID },
                onAddCard = {
                    composeScope.launch {
                        bottomSheetState.show()
                    }
                }
            )
            val maxHeightPx = with(LocalDensity.current) { maxHeight.toPx() }

            val scrim by
            animateColorAsState(
                targetValue =
                if (maxHeightPx - bottomSheetState.requireOffset() > 0f)
                    AnsaTheme.colors.background.scrim
                else Color.Transparent
            )

            Box(
                modifier =
                Modifier.matchParentSize().background(scrim).addIf(
                    bottomSheetState.currentValue == SheetValue.Expanded
                ) {
                    Modifier.clickable {
                        composeScope.launch {
                            bottomSheetState.hide()
                            delay(300)
                            paymentMethodUpdateManager.onCancelled()
                        }
                    }
                }
            )
        }
    }
}

Custom Select Payment Method Handling

Similarly, in both Ansa managed and Self managed UI, we support the ability to handle/override the "Select Payment Method" flow. This is handled by provided the onSelectPaymentMethod callback. This can be utilized to navigate to another screen, show a modal, etc. Once the card is successfully added via our APIs and you receive a PaymentMethod from the backend, you can inform the SDK of the change via the LocalPaymentMethodManager Composition local by calling onPaymentMethodAdded(paymentMethod). If the add flow is cancelled, simply call onCancelled

An example of this in action with a BottomSheet:

AnsaTheme {
    val paymentMethodUpdateManager = LocalPaymentMethodManager.current

    val bottomSheetState =
        rememberStandardBottomSheetState(
            initialValue = SheetValue.Hidden,
            skipHiddenState = false,
        )
    val scaffoldState =
        rememberBottomSheetScaffoldState(bottomSheetState = bottomSheetState)
    val composeScope = rememberCoroutineScope()

    BottomSheetScaffold(
        scaffoldState = scaffoldState,
        sheetShadowElevation = 8.dp,
        sheetPeekHeight = 0.dp,
        sheetContent = {
            PrimaryButtonLarge(
                modifier = Modifier.navigationBarsPadding(),
                text = "Click me to select card",
                onClick = {
                    composeScope.launch {
                        val paymentMethod =
                            PaymentMethod(
                                card =
                                Card(
                                    brand = "visa",
                                    fingerprint = UUID.randomUUID().toString(),
                                    lastFour = "4890",
                                    firstSix = "123456"
                                ),
                                id = UUID.randomUUID().toString(),
                                type = "credit_card"
                            )

                        // notify SDK cancelled payment method selection flow
                        // paymentUpdateManager.onCancelled()

                        // notify SDK user added or selected payment method
                        paymentMethodUpdateManager.onPaymentMethodAdded(paymentMethod)
                        bottomSheetState.hide()
                    }
                }
            )
        }
    ) {
        BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
            AnsaWalletScreen(
                ansaClient = ansaClient,
                customerId = { BuildConfig.CUSTOMER_ID },
                merchantId = { BuildConfig.MERCHANT_ID },
                onSelectPaymentMethod = {
                    composeScope.launch {
                        bottomSheetState.show()
                    }
                }
            )
            val maxHeightPx = with(LocalDensity.current) { maxHeight.toPx() }

            val scrim by
            animateColorAsState(
                targetValue =
                if (maxHeightPx - bottomSheetState.requireOffset() > 0f)
                    AnsaTheme.colors.background.scrim
                else Color.Transparent
            )

            Box(
                modifier =
                Modifier.matchParentSize().background(scrim).addIf(
                    bottomSheetState.currentValue == SheetValue.Expanded
                ) {
                    Modifier.clickable {
                        composeScope.launch {
                            bottomSheetState.hide()
                            delay(300)
                            paymentMethodUpdateManager.onCancelled()
                        }
                    }
                }
            )
        }
    }
}