Skip to content

PaymentSheet

Renders a secure tokenization form as a modal sheet. When the buyer submits the form, the SDK tokenizes the payment details and (optionally) runs 3D Secure, returning a PaymentSheetResponse via the onSuccess callback.

Breaking API change

The signature below replaces the previous CompletePaymentSheet / CompletePaymentSheetOutlined signature. The old signature is still shipped for backward compatibility but is deprecated — see Deprecated signature below. Migration is required to use 3D Secure or receive structured failure callbacks.

Function signature

@Composable
fun CompletePaymentSheet(
    configuration: PaymentSheetConfiguration,
    amount: Long,
    currency: String,
    onCancel: () -> Unit,
    onSuccess: (PaymentSheetResponse) -> Unit,
    onFailure: (FinixErrorCode) -> Unit,
    modifier: Modifier = Modifier,
)
ParameterTypeRequiredDescription
configurationPaymentSheetConfigurationYesApplication credentials, environment, and optional 3D Secure config. See PaymentSheetConfiguration.
amountLongYesTransaction amount in the smallest currency unit (e.g. cents for USD).
currencyStringYesISO 4217 currency code (e.g. "USD").
onCancel() -> UnitYesCalled when the buyer dismisses the sheet or taps cancel. Replaces the deprecated onDismiss + onNegativeClick pair.
onSuccess(PaymentSheetResponse) -> UnitYesCalled with a PaymentSheetResponse on successful tokenization. When 3DS is enabled, the response's threeDSResponse is populated; otherwise it is null.
onFailure(FinixErrorCode) -> UnitYesCalled when tokenization or 3DS fails. Receives a FinixErrorCode describing the failure mode.
modifierModifierNoJetpack Compose modifier applied to the sheet container. Defaults to Modifier.

configuration

Pass a PaymentSheetConfiguration carrying your Finix Application ID, environment flag, and (optionally) a ThreeDSConfiguration to enable 3D Secure.

amount / currency

amount is the transaction amount in the smallest currency unit. currency is the ISO 4217 code the amount is denominated in.

onCancel / onSuccess / onFailure

The three required callbacks cover every terminal state of the sheet.

CallbackTriggerReceives
onCancelBuyer dismisses the sheet or taps the cancel buttonnothing
onSuccessTokenization completes (and 3DS succeeds if enabled)PaymentSheetResponse
onFailureTokenization or 3DS failsFinixErrorCode

Dismiss the sheet from all three callbacks to avoid leaving it open after interaction.

Full example

A complete implementation using PaymentSheetConfiguration, 3D Secure, and structured success/failure callbacks.

Deprecated signature

The earlier signature is still exported for backward compatibility. It cannot receive 3D Secure results and surfaces tokenization errors via an in-sheet toast instead of a callback.

Do not use for new integrations

Migrate to the signature above. The deprecated version will be removed in a future major release.

@Composable
@Deprecated("Use CompletePaymentSheet(configuration, amount, currency, …) — see PaymentSheet reference.")
fun CompletePaymentSheet(
    modifier: Modifier = Modifier,
    applicationId: String = "",
    environment: PaymentSheetEnvironment = PaymentSheetEnvironment.SANDBOX,
    amount: Long,
    onDismiss: () -> Unit,
    onCancel: () -> Unit,
    onScanCard: () -> Unit = {},
    onTokenized: (TokenizedResponse) -> Unit,
)

The deprecated signature was replaced because:

  • No failure callback — tokenization errors were only surfaced via a toast.
  • onDismiss and onCancel fired on the same user interaction, so one was redundant.
  • onScanCard leaked SDK internals clients didn't need.
  • onTokenized was named inconsistently with iOS (didSucceed).
  • modifier sat before required parameters, violating Compose convention.
CompletePaymentSheet(
    configuration = configuration,
    amount = amount,
    currency = currency,
    onCancel = onCancel,
    onSuccess = onSuccess,
    onFailure = onFailure,
)

val configuration = PaymentSheetConfiguration(
    applicationId = "APgPDQrLD52TYvqazjHJJchM",
    environment = PaymentSheetEnvironment.LIVE,
    merchantId = "MUxxxxxxxx",
    apiUsername = "USxxxxxxxx",
    apiPassword = "your-api-password",
    threeDSConfiguration = ThreeDSConfiguration(
        redirectScheme = "yourappscheme://redirect",
        isEnabled = true,
    ),
)

CompletePaymentSheet(
    configuration = configuration,
    amount = 9900L,     // $99.00
    currency = "USD",
    onCancel = { },
    onSuccess = { },
    onFailure = { },
)

CompletePaymentSheet(
    configuration = configuration,
    amount = 9900L,
    currency = "USD",
    onCancel = {
        // Buyer dismissed the sheet or tapped cancel
        viewModel.setShowPaymentSheet(false)
    },
    onSuccess = { response ->
        // Tokenization succeeded (and 3DS succeeded if enabled)
        viewModel.saveTokenResponse(response.tokenizedResponse)
        response.threeDSResponse?.let { viewModel.saveThreeDS(it) }
        viewModel.setShowPaymentSheet(false)
    },
    onFailure = { error ->
        // Tokenization or 3DS failed
        viewModel.showError(error)
        viewModel.setShowPaymentSheet(false)
    },
)

@Composable
fun CheckoutScreen() {
    val viewModel = viewModel<CheckOutViewModel>()
    val state = viewModel.state

    if (state.showPaymentSheet) {
        CompletePaymentSheet(
            configuration = PaymentSheetConfiguration(
                applicationId = "APgPDQrLD52TYvqazjHJJchM",
                environment = PaymentSheetEnvironment.LIVE,
                merchantId = "MUxxxxxxxx",
                apiUsername = "USxxxxxxxx",
                apiPassword = "your-api-password",
                threeDSConfiguration = ThreeDSConfiguration(
                    redirectScheme = "yourappscheme://redirect",
                    isEnabled = true,
                ),
            ),
            amount = 9900L,
            currency = "USD",
            onCancel = { viewModel.setShowPaymentSheet(false) },
            onSuccess = { response ->
                viewModel.saveTokenResponse(response.tokenizedResponse)
                response.threeDSResponse?.let { viewModel.saveThreeDS(it) }
                viewModel.setShowPaymentSheet(false)
            },
            onFailure = { error ->
                viewModel.showError(error)
                viewModel.setShowPaymentSheet(false)
            },
        )
    }
}