Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add autofill in payment sheet #5672

Merged
merged 4 commits into from
Mar 8, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
### PaymentSheet
* [ADDED][6306](https://github.com/stripe/stripe-android/pull/6306) Added support for Cash App Pay.
* [FIXED][6326](https://github.com/stripe/stripe-android/pull/6326) Fixed an issue where the primary button would lose its padding on configuration changes.
* [ADDED][5672](https://github.com/stripe/stripe-android/pull/5672) Added support for credit card autofill.

## 20.19.5 - 2023-03-06

Expand Down
1 change: 0 additions & 1 deletion identity/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
<ID>ReturnCount:AddressSection.kt$private fun isValidAddress(addressMap: Map&lt;IdentifierSpec, FormFieldEntry>): Boolean</ID>
<ID>ReturnCount:IDNumberSection.kt$BRVisualTransformation.&lt;no name provided>$override fun originalToTransformed(offset: Int): Int</ID>
<ID>ReturnCount:IDNumberSection.kt$BRVisualTransformation.&lt;no name provided>$override fun transformedToOriginal(offset: Int): Int</ID>
<ID>SpreadOperator:AddressSection.kt$( it.errorMessage, *args )</ID>
<ID>SwallowedException:IdentityTheme.kt$e: ReflectiveOperationException</ID>
<ID>ThrowsCount:DefaultIdentityRepository.kt$DefaultIdentityRepository$private suspend fun &lt;Response : StripeModel> executeRequestWithModelJsonParser( request: StripeRequest, responseJsonParser: ModelJsonParser&lt;Response>, onSuccessExecutionTimeBlock: (Long) -> Unit = {} ): Response</ID>
<ID>TooManyFunctions:IdentityAnalyticsRequestFactory.kt$IdentityAnalyticsRequestFactory</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import com.stripe.android.link.ui.ErrorMessage
import com.stripe.android.link.ui.progressIndicatorTestTag
import com.stripe.android.link.ui.signup.SignUpState
import com.stripe.android.uicore.elements.EmailConfig
import com.stripe.android.ui.core.elements.NameConfig
import com.stripe.android.uicore.elements.NameConfig
import com.stripe.android.uicore.elements.PhoneNumberController
import com.stripe.android.uicore.elements.SimpleTextFieldController
import org.junit.Rule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.stripe.android.link.theme.DefaultLinkTheme
import com.stripe.android.link.ui.ErrorMessage
import com.stripe.android.link.ui.progressIndicatorTestTag
import com.stripe.android.uicore.elements.EmailConfig
import com.stripe.android.ui.core.elements.NameConfig
import com.stripe.android.uicore.elements.NameConfig
import com.stripe.android.uicore.elements.PhoneNumberController
import org.junit.Rule
import org.junit.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import com.stripe.android.model.CardBrand
import com.stripe.android.model.ConsumerPaymentDetails
import com.stripe.android.model.CvcCheck
import com.stripe.android.ui.core.elements.CvcController
import com.stripe.android.ui.core.elements.DateConfig
import com.stripe.android.uicore.elements.DateConfig
import com.stripe.android.uicore.elements.SimpleTextFieldController
import com.stripe.android.uicore.elements.TextFieldController
import kotlinx.coroutines.flow.MutableStateFlow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import com.stripe.android.link.ui.signup.SignUpState
import com.stripe.android.link.ui.signup.SignUpViewModel
import com.stripe.android.model.PaymentIntent
import com.stripe.android.model.SetupIntent
import com.stripe.android.ui.core.elements.NameConfig
import com.stripe.android.uicore.elements.EmailConfig
import com.stripe.android.uicore.elements.NameConfig
import com.stripe.android.uicore.elements.PhoneNumberController
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ import com.stripe.android.link.ui.ErrorText
import com.stripe.android.link.ui.LinkTerms
import com.stripe.android.link.ui.signup.EmailCollectionSection
import com.stripe.android.link.ui.signup.SignUpState
import com.stripe.android.ui.core.elements.NameConfig
import com.stripe.android.uicore.StripeTheme
import com.stripe.android.uicore.elements.EmailConfig
import com.stripe.android.uicore.elements.NameConfig
import com.stripe.android.uicore.elements.PhoneNumberCollectionSection
import com.stripe.android.uicore.elements.PhoneNumberController
import com.stripe.android.uicore.elements.TextFieldController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ import com.stripe.android.link.ui.PrimaryButton
import com.stripe.android.link.ui.PrimaryButtonState
import com.stripe.android.link.ui.ScrollableTopLevelColumn
import com.stripe.android.link.ui.progressIndicatorTestTag
import com.stripe.android.ui.core.elements.NameConfig
import com.stripe.android.uicore.elements.EmailConfig
import com.stripe.android.uicore.elements.NameConfig
import com.stripe.android.uicore.elements.PhoneNumberCollectionSection
import com.stripe.android.uicore.elements.PhoneNumberController
import com.stripe.android.uicore.elements.TextFieldController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import com.stripe.android.link.ui.getErrorMessage
import com.stripe.android.model.ConsumerSignUpConsentAction
import com.stripe.android.model.PaymentIntent
import com.stripe.android.model.SetupIntent
import com.stripe.android.ui.core.elements.NameConfig
import com.stripe.android.uicore.elements.EmailConfig
import com.stripe.android.uicore.elements.NameConfig
import com.stripe.android.uicore.elements.PhoneNumberController
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ import com.stripe.android.model.ConsumerPaymentDetails
import com.stripe.android.model.CvcCheck
import com.stripe.android.ui.core.elements.CvcController
import com.stripe.android.ui.core.elements.CvcElement
import com.stripe.android.ui.core.elements.DateConfig
import com.stripe.android.uicore.elements.DateConfig
import com.stripe.android.uicore.elements.IdentifierSpec
import com.stripe.android.uicore.elements.RowController
import com.stripe.android.uicore.elements.RowElement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ import com.stripe.android.payments.paymentlauncher.PaymentResult
import com.stripe.android.ui.core.FieldValuesToParamsMapConverter
import com.stripe.android.ui.core.address.toConfirmPaymentIntentShipping
import com.stripe.android.ui.core.elements.CvcController
import com.stripe.android.ui.core.elements.DateConfig
import com.stripe.android.ui.core.elements.createExpiryDateFormFieldValues
import com.stripe.android.uicore.elements.DateConfig
import com.stripe.android.uicore.elements.SimpleTextFieldController
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
Expand Down
8 changes: 0 additions & 8 deletions payments-ui-core/api/payments-ui-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,6 @@ public final class com/stripe/android/ui/core/elements/CountrySpec$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class com/stripe/android/ui/core/elements/DateConfig$Companion {
public final fun determineTextFieldState (IIII)Lcom/stripe/android/uicore/elements/TextFieldState;
}

public final class com/stripe/android/ui/core/elements/DisplayField : java/lang/Enum {
public static final field Companion Lcom/stripe/android/ui/core/elements/DisplayField$Companion;
public static final field Country Lcom/stripe/android/ui/core/elements/DisplayField;
Expand Down Expand Up @@ -436,10 +432,6 @@ public final class com/stripe/android/ui/core/elements/MandateTextSpec$Companion
public final class com/stripe/android/ui/core/elements/MandateTextUIKt {
}

public final class com/stripe/android/ui/core/elements/NameConfig$Companion {
public final fun createController (Ljava/lang/String;)Lcom/stripe/android/uicore/elements/SimpleTextFieldController;
}

public final class com/stripe/android/ui/core/elements/NameSpec$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field $stable I
public static final field INSTANCE Lcom/stripe/android/ui/core/elements/NameSpec$$serializer;
Expand Down
5 changes: 0 additions & 5 deletions payments-ui-core/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@
<ID>MagicNumber:CardNumberVisualTransformation.kt$CardNumberVisualTransformation.&lt;no name provided>$4</ID>
<ID>MagicNumber:CardNumberVisualTransformation.kt$CardNumberVisualTransformation.&lt;no name provided>$7</ID>
<ID>MagicNumber:CardNumberVisualTransformation.kt$CardNumberVisualTransformation.&lt;no name provided>$9</ID>
<ID>MagicNumber:DateConfig.kt$DateConfig$4</ID>
<ID>MagicNumber:DateConfig.kt$DateConfig.Companion$100</ID>
<ID>MagicNumber:DateConfig.kt$DateConfig.Companion$12</ID>
<ID>MagicNumber:DateConfig.kt$DateConfig.Companion$50</ID>
<ID>MagicNumber:IbanConfig.kt$IbanConfig$10</ID>
<ID>MagicNumber:IbanConfig.kt$IbanConfig$4</ID>
<ID>MagicNumber:LpmRepository.kt$LpmRepository$20</ID>
Expand Down Expand Up @@ -70,7 +66,6 @@
<ID>ReturnCount:CardNumberVisualTransformation.kt$CardNumberVisualTransformation.&lt;no name provided>$override fun transformedToOriginal(offset: Int): Int</ID>
<ID>ReturnCount:IbanConfig.kt$IbanConfig$override fun determineState(input: String): TextFieldState</ID>
<ID>SpreadOperator:BsbElementUI.kt$( it.errorMessage, *args )</ID>
<ID>SpreadOperator:SectionElementUI.kt$( it.errorMessage, *args )</ID>
<ID>TooGenericExceptionCaught:LpmSerializer.kt$LpmSerializer$e: Exception</ID>
<ID>TooGenericExceptionCaught:PlacesClientProxy.kt$DefaultPlacesClientProxy$e: Exception</ID>
<ID>UnnecessaryAbstractClass:FormControllerModule.kt$FormControllerModule$FormControllerModule</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
import com.stripe.android.uicore.elements.DateConfig
import com.stripe.android.uicore.elements.IdentifierSpec
import com.stripe.android.uicore.elements.RowController
import com.stripe.android.uicore.elements.RowElement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.annotation.RestrictTo
import com.stripe.android.uicore.elements.IdentifierSpec
import com.stripe.android.uicore.elements.SectionFieldErrorController
import com.stripe.android.uicore.elements.SectionMultiFieldElement
import com.stripe.android.uicore.elements.convertTo4DigitDate
import com.stripe.android.uicore.forms.FormFieldEntry
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.stripe.android.ui.core.elements

import android.content.Context
import androidx.annotation.VisibleForTesting
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.autofill.AutofillType
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
import com.stripe.android.cards.CardAccountRangeRepository
Expand Down Expand Up @@ -31,6 +33,9 @@ internal sealed class CardNumberController : TextFieldController, SectionFieldEr

abstract val cardScanEnabled: Boolean

@OptIn(ExperimentalComposeUiApi::class)
override val autofillType: AutofillType = AutofillType.CreditCardNumber

fun onCardScanResult(cardScanSheetResult: CardScanSheetResult) {
// Don't need to populate the card number if the result is Canceled or Failed
if (cardScanSheetResult is CardScanSheetResult.Completed) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.stripe.android.ui.core.elements

import androidx.annotation.RestrictTo
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.autofill.AutofillType
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
import com.stripe.android.model.CardBrand
Expand Down Expand Up @@ -38,6 +40,9 @@ class CvcController constructor(

override val debugLabel = cvcTextFieldConfig.debugLabel

@OptIn(ExperimentalComposeUiApi::class)
override val autofillType: AutofillType = AutofillType.CreditCardSecurityCode

private val _fieldValue = MutableStateFlow("")
override val fieldValue: Flow<String> = _fieldValue

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.stripe.android.ui.core.elements

import com.google.common.truth.Truth
import com.stripe.android.ui.core.R
import com.stripe.android.uicore.elements.DateConfig
import com.stripe.android.uicore.elements.TextFieldStateConstants
import org.junit.Test
import java.util.Calendar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.stripe.android.ui.core.elements

import androidx.compose.ui.text.AnnotatedString
import com.google.common.truth.Truth
import com.stripe.android.uicore.elements.ExpiryDateVisualTransformation
import org.junit.Test

internal class ExpiryDateVisualTransformationTest {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.stripe.android.ui.core.elements

import com.google.common.truth.Truth
import com.stripe.android.uicore.elements.NameConfig
import com.stripe.android.uicore.elements.TextFieldStateConstants.Error.Blank
import com.stripe.android.uicore.elements.TextFieldStateConstants.Valid.Limitless
import org.junit.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import com.stripe.android.ui.core.elements.EmailElement
import com.stripe.android.ui.core.elements.EmailSpec
import com.stripe.android.ui.core.elements.EmptyFormElement
import com.stripe.android.ui.core.elements.KeyboardType
import com.stripe.android.ui.core.elements.NameConfig
import com.stripe.android.ui.core.elements.NameSpec
import com.stripe.android.ui.core.elements.SimpleDropdownElement
import com.stripe.android.ui.core.elements.SimpleTextSpec
Expand All @@ -30,6 +29,7 @@ import com.stripe.android.uicore.elements.CountryConfig
import com.stripe.android.uicore.elements.CountryElement
import com.stripe.android.uicore.elements.EmailConfig
import com.stripe.android.uicore.elements.IdentifierSpec
import com.stripe.android.uicore.elements.NameConfig
import com.stripe.android.uicore.elements.SectionElement
import com.stripe.android.uicore.elements.SimpleTextElement
import kotlinx.coroutines.flow.first
Expand Down
2 changes: 0 additions & 2 deletions paymentsheet/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
<ID>MagicNumber:PrimaryButtonUiStateMapper.kt$PrimaryButtonUiStateMapper$5</ID>
<ID>MagicNumber:USBankAccountFormFragment.kt$USBankAccountFormFragment$0.5f</ID>
<ID>MaxLineLength:BillingAddressViewTest.kt$BillingAddressViewTest$fun</ID>
<ID>MaxLineLength:ConfirmPaymentIntentParamsFactoryTest.kt$ConfirmPaymentIntentParamsFactoryTest$fun</ID>
<ID>MaxLineLength:CustomerRepositoryTest.kt$CustomerRepositoryTest$onBlocking { detachPaymentMethod(anyString(), any(), anyString(), any()) }.doThrow(InvalidParameterException("error"))</ID>
<ID>MaxLineLength:DefaultFlowControllerTest.kt$DefaultFlowControllerTest$fun</ID>
<ID>MaxLineLength:FlowControllerConfigurationHandlerTest.kt$FlowControllerConfigurationHandlerTest$.</ID>
Expand All @@ -67,7 +66,6 @@
<ID>ThrowsCount:PaymentSheetConfigurationKtx.kt$internal fun PaymentSheet.Configuration.validate()</ID>
<ID>TooManyFunctions:DefaultFlowController.kt$DefaultFlowController : FlowControllerNonFallbackInjector</ID>
<ID>TooManyFunctions:PaymentOption.kt$DelegateDrawable : Drawable</ID>
<ID>TooManyFunctions:PaymentOptionsViewModel.kt$PaymentOptionsViewModel : BaseSheetViewModel</ID>
<ID>TooManyFunctions:PaymentSheetViewModel.kt$PaymentSheetViewModel : BaseSheetViewModel</ID>
<ID>UnnecessaryAbstractClass:PaymentSheetCommonModule.kt$PaymentSheetCommonModule$PaymentSheetCommonModule</ID>
<ID>UnnecessaryAbstractClass:PaymentSheetLauncherModule.kt$PaymentSheetLauncherModule$PaymentSheetLauncherModule</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ internal class DefaultEventReporter @Inject internal constructor(
)
}

override fun onAutofill(type: String) {
fireEvent(
PaymentSheetEvent.AutofillEvent(type)
)
}

private fun fireEvent(event: PaymentSheetEvent) {
CoroutineScope(workContext).launch {
analyticsRequestExecutor.executeAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ internal interface EventReporter {

fun onLpmSpecFailure()

fun onAutofill(type: String)

enum class Mode(val code: String) {
Complete("complete"),
Custom("custom");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ internal sealed class PaymentSheetEvent : AnalyticsEvent {
override val eventName: String = "luxe_serialize_failure"
}

class AutofillEvent(type: String) : PaymentSheetEvent() {
private fun String.toSnakeCase() = replace(
"(?<=.)(?=\\p{Upper})".toRegex(),
"_"
).lowercase()

override val additionalParams: Map<String, Any?>
get() = emptyMap()
override val eventName: String = "autofill_${type.toSnakeCase()}"
}

internal companion object {
private fun analyticsValue(
paymentSelection: PaymentSelection?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ import com.stripe.android.paymentsheet.model.create
import com.stripe.android.paymentsheet.paymentdatacollection.FormArguments
import com.stripe.android.paymentsheet.paymentdatacollection.ach.di.DaggerUSBankAccountFormComponent
import com.stripe.android.paymentsheet.paymentdatacollection.ach.di.USBankAccountFormViewModelSubcomponent
import com.stripe.android.ui.core.elements.NameConfig
import com.stripe.android.ui.core.elements.SaveForFutureUseElement
import com.stripe.android.ui.core.elements.SaveForFutureUseSpec
import com.stripe.android.uicore.elements.EmailConfig
import com.stripe.android.uicore.elements.NameConfig
import com.stripe.android.uicore.elements.TextFieldController
import com.stripe.android.utils.requireApplication
import kotlinx.coroutines.flow.MutableStateFlow
Expand Down
Loading