Skip to content

Commit

Permalink
Move rememberCustomerSheet to onCreate & properly fetch option.
Browse files Browse the repository at this point in the history
  • Loading branch information
samer-stripe committed May 23, 2024
1 parent 476b725 commit f6e13f5
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.stripe.android.customersheet.CustomerSheet
import com.stripe.android.customersheet.CustomerSheetResult
import com.stripe.android.customersheet.ExperimentalCustomerSheetApi
import com.stripe.android.customersheet.rememberCustomerSheet
import com.stripe.android.model.PaymentMethod
Expand All @@ -55,9 +57,12 @@ import com.stripe.android.paymentsheet.example.playground.settings.SettingsUi
import com.stripe.android.paymentsheet.example.samples.ui.shared.BuyButton
import com.stripe.android.paymentsheet.example.samples.ui.shared.CHECKOUT_TEST_TAG
import com.stripe.android.paymentsheet.example.samples.ui.shared.PaymentMethodSelector
import com.stripe.android.paymentsheet.model.PaymentOption
import com.stripe.android.paymentsheet.rememberPaymentSheet
import com.stripe.android.paymentsheet.rememberPaymentSheetFlowController
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.withContext

internal class PaymentSheetPlaygroundActivity : AppCompatActivity(), ExternalPaymentMethodConfirmHandler {
companion object {
Expand All @@ -76,6 +81,7 @@ internal class PaymentSheetPlaygroundActivity : AppCompatActivity(), ExternalPay
)
}

@OptIn(ExperimentalCustomerSheetApi::class)
@Suppress("LongMethod")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -101,6 +107,14 @@ internal class PaymentSheetPlaygroundActivity : AppCompatActivity(), ExternalPay

val playgroundState by viewModel.state.collectAsState()

val customerSheet = playgroundState?.asCustomerState()?.let { customerPlaygroundState ->
rememberCustomerSheet(
configuration = customerPlaygroundState.customerSheetConfiguration(),
customerAdapter = customerPlaygroundState.adapter,
callback = viewModel::onCustomerSheetCallback
)
}

PlaygroundTheme(
content = {
playgroundState?.asPaymentState()?.stripeIntentId?.let { stripeIntentId ->
Expand Down Expand Up @@ -130,6 +144,7 @@ internal class PaymentSheetPlaygroundActivity : AppCompatActivity(), ExternalPay
playgroundState = playgroundState,
paymentSheet = paymentSheet,
flowController = flowController,
customerSheet = customerSheet,
addressLauncher = addressLauncher,
)
}
Expand Down Expand Up @@ -208,11 +223,13 @@ internal class PaymentSheetPlaygroundActivity : AppCompatActivity(), ExternalPay
}
}

@OptIn(ExperimentalCustomerSheetApi::class)
@Composable
private fun PlaygroundStateUi(
playgroundState: PlaygroundState?,
paymentSheet: PaymentSheet,
flowController: PaymentSheet.FlowController,
customerSheet: CustomerSheet?,
addressLauncher: AddressLauncher
) {
if (playgroundState == null) {
Expand Down Expand Up @@ -243,15 +260,8 @@ internal class PaymentSheetPlaygroundActivity : AppCompatActivity(), ExternalPay
else -> Unit
}
}
is PlaygroundState.Customer -> {
val customerSheetState by viewModel.customerSheetState.collectAsState()

customerSheetState?.let { state ->
CustomerSheetUi(
customerSheetState = state,
playgroundState = playgroundState
)
}
is PlaygroundState.Customer -> customerSheet?.run {
CustomerSheetUi(customerSheet = this)
}
}
}
Expand Down Expand Up @@ -318,29 +328,41 @@ internal class PaymentSheetPlaygroundActivity : AppCompatActivity(), ExternalPay
@OptIn(ExperimentalCustomerSheetApi::class)
@Composable
fun CustomerSheetUi(
playgroundState: PlaygroundState.Customer,
customerSheetState: CustomerSheetState,
customerSheet: CustomerSheet,
) {
val customerSheet = rememberCustomerSheet(
configuration = playgroundState.customerSheetConfiguration(),
customerAdapter = playgroundState.adapter,
callback = viewModel::onCustomerSheetCallback
)
val customerSheetState by viewModel.customerSheetState.collectAsState()

customerSheetState?.let { state ->
LaunchedEffect(state) {
if (state.shouldFetchPaymentOption) {
fetchOption(customerSheet).onSuccess { option ->
viewModel.customerSheetState.emit(
CustomerSheetState(
selectedPaymentOption = option,
shouldFetchPaymentOption = false
)
)
}.onFailure { exception ->
viewModel.status.emit(
StatusMessage(
message = "Failed to retrieve payment options:\n${exception.message}"
)
)
}
}
}

LaunchedEffect(customerSheet) {
viewModel.fetchOption(customerSheet)
}
if (state.shouldFetchPaymentOption) {
return
}

if (customerSheetState.shouldFetchPaymentOption) {
return
PaymentMethodSelector(
isEnabled = true,
paymentMethodLabel = customerSheetState.paymentMethodLabel(),
paymentMethodPainter = customerSheetState.paymentMethodPainter(),
onClick = customerSheet::present
)
}

PaymentMethodSelector(
isEnabled = true,
paymentMethodLabel = customerSheetState.paymentMethodLabel(),
paymentMethodPainter = customerSheetState.paymentMethodPainter(),
onClick = customerSheet::present
)
}

@Composable
Expand Down Expand Up @@ -419,6 +441,17 @@ internal class PaymentSheetPlaygroundActivity : AppCompatActivity(), ExternalPay
}
}

@OptIn(ExperimentalCustomerSheetApi::class)
private suspend fun fetchOption(
customerSheet: CustomerSheet
): Result<PaymentOption?> = withContext(Dispatchers.IO) {
when (val result = customerSheet.retrievePaymentOptionSelection()) {
is CustomerSheetResult.Selected -> Result.success(result.selection?.paymentOption)
is CustomerSheetResult.Failed -> Result.failure(result.exception)
is CustomerSheetResult.Canceled -> Result.success(null)
}
}

override fun confirmExternalPaymentMethod(
externalPaymentMethodType: String,
billingDetails: PaymentMethod.BillingDetails
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import com.github.kittinunf.result.Result
import com.stripe.android.PaymentConfiguration
import com.stripe.android.customersheet.CustomerAdapter
import com.stripe.android.customersheet.CustomerEphemeralKey
import com.stripe.android.customersheet.CustomerSheet
import com.stripe.android.customersheet.CustomerSheetResult
import com.stripe.android.customersheet.ExperimentalCustomerSheetApi
import com.stripe.android.model.PaymentMethod
Expand Down Expand Up @@ -304,42 +303,6 @@ internal class PaymentSheetPlaygroundViewModel(
status.value = StatusMessage(statusMessage)
}

@OptIn(ExperimentalCustomerSheetApi::class)
fun fetchOption(customerSheet: CustomerSheet) {
viewModelScope.launch(Dispatchers.IO) {
when (val result = customerSheet.retrievePaymentOptionSelection()) {
is CustomerSheetResult.Selected -> {
customerSheetState.update { existingState ->
existingState?.copy(
selectedPaymentOption = result.selection?.paymentOption,
shouldFetchPaymentOption = false,
)
}
}
is CustomerSheetResult.Failed -> {
customerSheetState.update { existingState ->
existingState?.copy(
shouldFetchPaymentOption = false,
)
}

status.emit(
StatusMessage(
message = "Failed to retrieve payment options:\n${result.exception.message}"
)
)
}
is CustomerSheetResult.Canceled -> {
customerSheetState.update { existingState ->
existingState?.copy(
shouldFetchPaymentOption = false,
)
}
}
}
}
}

@OptIn(ExperimentalCustomerSheetApi::class)
fun onCustomerSheetCallback(result: CustomerSheetResult) {
val statusMessage = when (result) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ internal sealed interface PlaygroundState {
return this as? Payment
}

fun asCustomerState(): Customer? {
return this as? Customer
}

companion object {
fun CheckoutResponse.asPlaygroundState(
snapshot: PlaygroundSettings.Snapshot,
Expand Down

0 comments on commit f6e13f5

Please sign in to comment.