chrisjenx
02/03/2025, 5:28 PMChrimaeon
02/03/2025, 6:14 PMchrisjenx
02/03/2025, 8:03 PMmarkturnip
11/06/2025, 10:51 AMmarkturnip
11/06/2025, 10:52 AMmarkturnip
11/06/2025, 10:52 AMchrisjenx
11/07/2025, 2:25 AMchrisjenx
11/07/2025, 2:27 AMchrisjenx
11/07/2025, 2:27 AMmarkturnip
11/07/2025, 2:33 AMchrisjenx
11/07/2025, 2:34 AMmarkturnip
11/07/2025, 2:34 AMmarkturnip
11/07/2025, 2:34 AMchrisjenx
11/07/2025, 2:35 AMmarkturnip
11/07/2025, 2:35 AMmarkturnip
11/18/2025, 7:21 AMPaymentSheet from within my definition, but the initialiser requires Activity
For now I’ve ended up creating a StripeCheckout composable which owns the paymentSheet and is responsible for presenting:
https://github.com/markst/stripe-kmp/blob/main/shared/src/androidMain/kotlin/com/fouroneone/stripe/StripePayments.android.ktmarkturnip
11/18/2025, 7:26 AMPaymentSheet simply like this:
private class AndroidStripePayments(private val context: Context) : StripePayments {
var paymentSheet: PaymentSheet?
@Composable
override fun Initialize(publishableKey: String) {
PaymentConfiguration.init(context = context, publishableKey = publishableKey)
paymentSheet = PaymentSheet.Builder { result -> onResult(result.toCommonResult()) }.build()
}
@Composable
override fun presentWithPaymentIntent(
clientSecret: String,
onResult: (PaymentSheetResult) -> Unit
) {
paymentSheet.presentWithPaymentIntent(
paymentIntentClientSecret = clientSecret,
configuration = null
)
}
}markturnip
11/20/2025, 10:55 PMComposable for my PaymentSheet.
@Composable
actual fun rememberPaymentSheet(
stripePayments: StripePayments,
onResult: (PaymentSheetResult) -> Unit
): PaymentSheetWrapper {
val paymentSheet = remember(onResult) {
PaymentSheet.Builder(resultCallback = { result: StripePaymentSheetResult ->
onResult(result.toCommonResult())
})
}.build()
return remember(paymentSheet) {
AndroidPaymentSheetWrapper(paymentSheet)
}
}
But am curious how you went about this @chrisjenxchrisjenx
11/20/2025, 10:56 PMmarkturnip
11/25/2025, 10:37 PMmarkturnip
11/25/2025, 10:37 PMchrisjenx
11/26/2025, 12:59 AMchrisjenx
11/26/2025, 12:59 AMchrisjenx
11/26/2025, 6:44 AMmarkturnip
11/26/2025, 6:44 AMmarkturnip
11/26/2025, 6:44 AMchrisjenx
11/26/2025, 7:10 AMchrisjenx
11/26/2025, 7:10 AMmarkturnip
11/27/2025, 3:48 AMmarkturnip
11/27/2025, 3:49 AMAndroidPaymentsLauncher() I had trouble with that:
Copy codeIllegalStateException: LifecycleOwners must call register before they are STARTED
chrisjenx
11/28/2025, 5:02 PMoverride fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge(statusBarStyle = SystemBarStyle.light(Color.TRANSPARENT, Color.BLACK))
super.onCreate(savedInstanceState)
// Always create the root component outside Compose on the main thread
val defaultComponentContext = defaultComponentContext()
val root = DefaultAppComponent(
componentContext = defaultComponentContext,
navigationHandler = AndroidNavigationHandler(this),
paymentsLauncher = AndroidPaymentsLauncher(this),
)chrisjenx
11/28/2025, 5:09 PMLocalContext and used to init from the @Composable, but paymentsheet needed to be registered in onCreate because the activity result they use needs to be able to listen to ActivityResults from there started activity. Just annoying API design on Stripe side (Also would be nice if google result handler would just send you the result after registering so you can register post onCreate)chrisjenx
11/30/2025, 12:11 AMmarkturnip
11/30/2025, 12:12 AMchrisjenx
11/30/2025, 12:14 AMmarkturnip
11/30/2025, 12:15 AM