From 3a59f71bd9a8471be470ce6d624d28bb243b53b7 Mon Sep 17 00:00:00 2001 From: Isabel Martin Date: Thu, 18 Jul 2024 09:28:57 -0700 Subject: [PATCH] MBL-1615: BackingId sent to createPaymentIntent as param on the late pledges checkout flow (#2075) --- app/src/main/graphql/checkout.graphql | 7 ++- .../com/kickstarter/models/CheckoutPayment.kt | 2 +- .../models/CreatePaymentIntentInput.kt | 2 +- .../kickstarter/services/KSApolloClientV2.kt | 7 ++- .../ui/activities/ProjectPageActivity.kt | 4 +- .../projectpage/ConfirmDetailsViewModel.kt | 4 +- .../LatePledgeCheckoutViewModel.kt | 49 +++++++++++-------- .../LatePledgeCheckoutViewModelTests.kt | 3 +- 8 files changed, 49 insertions(+), 29 deletions(-) diff --git a/app/src/main/graphql/checkout.graphql b/app/src/main/graphql/checkout.graphql index b3070d54af..57cdfbb590 100644 --- a/app/src/main/graphql/checkout.graphql +++ b/app/src/main/graphql/checkout.graphql @@ -45,12 +45,15 @@ mutation CreateCheckout($projectId: ID!, $amount: String!, $rewardIds: [ID!], $l checkout{ id paymentUrl + backing { + id + } } } } -mutation CreatePaymentIntent($projectId: ID!, $amount: String!, $paymentIntentContext: StripeIntentContextTypes, $checkoutId: ID!) { - createPaymentIntent(input: { projectId: $projectId, amount: $amount, paymentIntentContext: $paymentIntentContext, checkoutId: $checkoutId } ) { +mutation CreatePaymentIntent($projectId: ID!, $amount: String!, $paymentIntentContext: StripeIntentContextTypes, $checkoutId: ID!, $backingId: ID) { + createPaymentIntent(input: { projectId: $projectId, amount: $amount, paymentIntentContext: $paymentIntentContext, checkoutId: $checkoutId, backingId: $backingId } ) { clientSecret } } diff --git a/app/src/main/java/com/kickstarter/models/CheckoutPayment.kt b/app/src/main/java/com/kickstarter/models/CheckoutPayment.kt index 9e6a8ca413..972af789ce 100644 --- a/app/src/main/java/com/kickstarter/models/CheckoutPayment.kt +++ b/app/src/main/java/com/kickstarter/models/CheckoutPayment.kt @@ -1,3 +1,3 @@ package com.kickstarter.models -data class CheckoutPayment(val id: Long, val paymentUrl: String?) +data class CheckoutPayment(val id: Long, val paymentUrl: String?, val backing: Backing? = null) diff --git a/app/src/main/java/com/kickstarter/models/CreatePaymentIntentInput.kt b/app/src/main/java/com/kickstarter/models/CreatePaymentIntentInput.kt index eae0610450..582abd105c 100644 --- a/app/src/main/java/com/kickstarter/models/CreatePaymentIntentInput.kt +++ b/app/src/main/java/com/kickstarter/models/CreatePaymentIntentInput.kt @@ -1,3 +1,3 @@ package com.kickstarter.models -data class CreatePaymentIntentInput(val project: Project, val amount: String, val checkoutId: String) +data class CreatePaymentIntentInput(val project: Project, val amount: String, val checkoutId: String, val backing: Backing) diff --git a/app/src/main/java/com/kickstarter/services/KSApolloClientV2.kt b/app/src/main/java/com/kickstarter/services/KSApolloClientV2.kt index c655335bd6..4618a3761b 100644 --- a/app/src/main/java/com/kickstarter/services/KSApolloClientV2.kt +++ b/app/src/main/java/com/kickstarter/services/KSApolloClientV2.kt @@ -1489,10 +1489,13 @@ class KSApolloClientV2(val service: ApolloClient, val gson: Gson) : ApolloClient } else { response.data?.let { data -> data.createCheckout()?.checkout()?.let { checkoutObj -> + val backingId = decodeRelayId(checkoutObj.id()) ?: 0L + val backing = Backing.builder().id(backingId).build() decodeRelayId(checkoutObj.id())?.let { id -> val checkout = CheckoutPayment( id, - checkoutObj.paymentUrl() + checkoutObj.paymentUrl(), + backing = backing ) ps.onNext(checkout) } ?: ps.onError(Exception("CreateCheckout could not decode ID")) @@ -1511,12 +1514,14 @@ class KSApolloClientV2(val service: ApolloClient, val gson: Gson) : ApolloClient val ps = PublishSubject.create() val checkoutId = createPaymentIntentInput.checkoutId + val backingId = encodeRelayId(createPaymentIntentInput.backing) this.service.mutate( CreatePaymentIntentMutation.builder() .projectId(encodeRelayId(createPaymentIntentInput.project)) .amount(createPaymentIntentInput.amount) .paymentIntentContext(StripeIntentContextTypes.POST_CAMPAIGN_CHECKOUT) .checkoutId(Base64Utils.encodeUrlSafe(("Checkout-$checkoutId").toByteArray(Charset.defaultCharset()))) + .backingId(backingId) .build() ).enqueue(object : ApolloCall.Callback() { override fun onFailure(e: ApolloException) { diff --git a/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt index 319b725e91..3039b11c9c 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt @@ -549,7 +549,9 @@ class ProjectPageActivity : if (checkoutPayment.id != 0L) checkoutFlowViewModel.onConfirmDetailsContinueClicked { startLoginToutActivity() } - latePledgeCheckoutViewModel.provideCheckoutId(checkoutPayment.id) + checkoutPayment.backing?.let { + latePledgeCheckoutViewModel.provideCheckoutIdAndBacking(checkoutPayment.id, it) + } } confirmDetailsViewModel.provideErrorAction { message -> diff --git a/app/src/main/java/com/kickstarter/viewmodels/projectpage/ConfirmDetailsViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/projectpage/ConfirmDetailsViewModel.kt index cfb662c62c..76f652cbd0 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/projectpage/ConfirmDetailsViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/projectpage/ConfirmDetailsViewModel.kt @@ -66,14 +66,14 @@ class ConfirmDetailsViewModel(val environment: Environment) : ViewModel() { ) private val mutableCheckoutPayment = - MutableStateFlow(CheckoutPayment(id = 0L, paymentUrl = null)) + MutableStateFlow(CheckoutPayment(id = 0L, paymentUrl = null, backing = null)) val checkoutPayment: StateFlow get() = mutableCheckoutPayment .asStateFlow() .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(), - initialValue = CheckoutPayment(id = 0L, paymentUrl = null) + initialValue = CheckoutPayment(id = 0L, paymentUrl = null, null) ) fun provideProjectData(projectData: ProjectData) { diff --git a/app/src/main/java/com/kickstarter/viewmodels/projectpage/LatePledgeCheckoutViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/projectpage/LatePledgeCheckoutViewModel.kt index cacc9cfa81..67a32bc7d0 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/projectpage/LatePledgeCheckoutViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/projectpage/LatePledgeCheckoutViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import com.kickstarter.libs.Environment import com.kickstarter.libs.utils.extensions.isNotNull +import com.kickstarter.models.Backing import com.kickstarter.models.Checkout import com.kickstarter.models.CreatePaymentIntentInput import com.kickstarter.models.Project @@ -50,6 +51,7 @@ class LatePledgeCheckoutViewModel(val environment: Environment) : ViewModel() { private var storedCards: List = listOf() private var userEmail: String = "" private var checkoutId: String? = null + private var backing: Backing? = null private var stripe: Stripe = requireNotNull(environment.stripe()) @@ -113,8 +115,9 @@ class LatePledgeCheckoutViewModel(val environment: Environment) : ViewModel() { } } - fun provideCheckoutId(checkoutId: Long) { + fun provideCheckoutIdAndBacking(checkoutId: Long, backing: Backing) { this.checkoutId = checkoutId.toString() + this.backing = backing } fun onAddNewCardClicked(project: Project) { @@ -185,31 +188,37 @@ class LatePledgeCheckoutViewModel(val environment: Environment) : ViewModel() { totalAmount: Double ) { viewModelScope.launch { - checkoutId?.let { - apolloClient.createPaymentIntent( - CreatePaymentIntentInput( - project = project, - amount = totalAmount.toString(), - checkoutId = it - ) - ).asFlow().onStart { - emitCurrentState(isLoading = true) - }.map { clientSecret -> - selectedCard?.let { - checkoutId?.let { - validateCheckout(clientSecret = clientSecret, selectedCard = selectedCard) + checkoutId?.let { cId -> + backing?.let { b -> + apolloClient.createPaymentIntent( + CreatePaymentIntentInput( + project = project, + amount = totalAmount.toString(), + checkoutId = cId, + backing = b + ) + ).asFlow().onStart { + emitCurrentState(isLoading = true) + }.map { clientSecret -> + selectedCard?.let { + checkoutId?.let { + validateCheckout( + clientSecret = clientSecret, + selectedCard = selectedCard + ) + } ?: run { + emitCurrentState() + errorAction.invoke(null) + } } ?: run { emitCurrentState() errorAction.invoke(null) } - } ?: run { + }.catch { emitCurrentState() errorAction.invoke(null) - } - }.catch { - emitCurrentState() - errorAction.invoke(null) - }.collect() + }.collect() + } } ?: run { emitCurrentState() errorAction.invoke(null) diff --git a/app/src/test/java/com/kickstarter/viewmodels/LatePledgeCheckoutViewModelTests.kt b/app/src/test/java/com/kickstarter/viewmodels/LatePledgeCheckoutViewModelTests.kt index c5d06f0c7c..b8b0a2fa47 100644 --- a/app/src/test/java/com/kickstarter/viewmodels/LatePledgeCheckoutViewModelTests.kt +++ b/app/src/test/java/com/kickstarter/viewmodels/LatePledgeCheckoutViewModelTests.kt @@ -12,6 +12,7 @@ import com.kickstarter.mock.factories.ShippingRuleFactory import com.kickstarter.mock.factories.StoredCardFactory import com.kickstarter.mock.factories.UserFactory import com.kickstarter.mock.services.MockApolloClientV2 +import com.kickstarter.models.Backing import com.kickstarter.models.CreatePaymentIntentInput import com.kickstarter.models.PaymentValidationResponse import com.kickstarter.models.Project @@ -323,7 +324,7 @@ class LatePledgeCheckoutViewModelTests : KSRobolectricTestCase() { errorActionCount++ } - viewModel.provideCheckoutId(100L) + viewModel.provideCheckoutIdAndBacking(100L, Backing.builder().id(101L).build()) viewModel.onPledgeButtonClicked(cardList.first(), ProjectFactory.project(), 100.0)