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

Enable Google Pay option in Basic Integration #1995

Merged
merged 1 commit into from
Dec 20, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class PaymentSessionActivity : AppCompatActivity() {
// Optionally specify the `PaymentMethod.Type` values to use.
// Defaults to `PaymentMethod.Type.Card`
.setPaymentMethodTypes(listOf(PaymentMethod.Type.Card))
.setShouldShowGooglePay(true)
.setAllowedShippingCountryCodes(setOf("US", "CA"))
.setShippingInformationValidator(ShippingInformationValidator())
.setShippingMethodsFactory(ShippingMethodsFactory())
Expand All @@ -102,11 +103,20 @@ class PaymentSessionActivity : AppCompatActivity() {
}

private fun createPaymentMethodDescription(data: PaymentSessionData): String {
return data.paymentMethod?.let { paymentMethod ->
paymentMethod.card?.let { card ->
"${card.brand} ending in ${card.last4}"
} ?: paymentMethod.type
} ?: notSelectedText
val paymentMethod = data.paymentMethod
return when {
paymentMethod != null -> {
paymentMethod.card?.let { card ->
"${card.brand} ending in ${card.last4}"
} ?: paymentMethod.type.orEmpty()
}
data.useGooglePay -> {
"Use Google Pay"
}
else -> {
notSelectedText
}
}
}

private fun createShippingInfoDescription(shippingInformation: ShippingInformation?): String {
Expand Down
19 changes: 14 additions & 5 deletions stripe/src/main/java/com/stripe/android/PaymentSession.kt
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,11 @@ class PaymentSession @VisibleForTesting internal constructor(
}

private fun onPaymentMethodResult(data: Intent) {
val paymentMethod: PaymentMethod? =
PaymentMethodsActivityStarter.Result.fromIntent(data)?.paymentMethod
persistPaymentMethod(paymentMethod)
val result = PaymentMethodsActivityStarter.Result.fromIntent(data)
persistPaymentMethodResult(
paymentMethod = result?.paymentMethod,
useGooglePay = result?.useGooglePay ?: false
)
dispatchUpdates()
}

Expand All @@ -129,11 +131,17 @@ class PaymentSession @VisibleForTesting internal constructor(
paymentSessionListener?.onCommunicatingStateChanged(false)
}

private fun persistPaymentMethod(paymentMethod: PaymentMethod?) {
private fun persistPaymentMethodResult(
paymentMethod: PaymentMethod?,
useGooglePay: Boolean
) {
customerSession.cachedCustomer?.id?.let { customerId ->
paymentSessionPrefs.saveSelectedPaymentMethodId(customerId, paymentMethod?.id)
}
paymentSessionData = paymentSessionData.copy(paymentMethod = paymentMethod)
paymentSessionData = paymentSessionData.copy(
paymentMethod = paymentMethod,
useGooglePay = useGooglePay
)
}

/**
Expand Down Expand Up @@ -260,6 +268,7 @@ class PaymentSession @VisibleForTesting internal constructor(
.setIsPaymentSessionActive(true)
.setPaymentConfiguration(PaymentConfiguration.getInstance(context))
.setPaymentMethodTypes(config?.paymentMethodTypes.orEmpty())
.setShouldShowGooglePay(config?.shouldShowGooglePay ?: false)
.setWindowFlags(config?.windowFlags)
.setBillingAddressFields(config?.billingAddressFields ?: BillingAddressFields.None)
.build()
Expand Down
12 changes: 12 additions & 0 deletions stripe/src/main/java/com/stripe/android/PaymentSessionConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ data class PaymentSessionConfig internal constructor(
@get:LayoutRes
val addPaymentMethodFooterLayoutId: Int = 0,
val paymentMethodTypes: List<PaymentMethod.Type> = listOf(PaymentMethod.Type.Card),
val shouldShowGooglePay: Boolean,
val allowedShippingCountryCodes: Set<String> = emptySet(),
val billingAddressFields: BillingAddressFields = BillingAddressFields.None,

Expand Down Expand Up @@ -95,6 +96,7 @@ data class PaymentSessionConfig internal constructor(
private var optionalShippingInfoFields: List<String>? = null
private var shippingInformation: ShippingInformation? = null
private var paymentMethodTypes: List<PaymentMethod.Type> = listOf(PaymentMethod.Type.Card)
private var shouldShowGooglePay: Boolean = false
private var allowedShippingCountryCodes: Set<String> = emptySet()
private var shippingInformationValidator: ShippingInformationValidator? = null
private var shippingMethodsFactory: ShippingMethodsFactory? = null
Expand Down Expand Up @@ -186,6 +188,15 @@ data class PaymentSessionConfig internal constructor(
this.paymentMethodTypes = paymentMethodTypes
}

/**
* @param shouldShowGooglePay if `true`, will show "Google Pay" as an option on the
* Payment Methods selection screen. If a user selects the Google Pay option,
* [PaymentSessionData.useGooglePay] will be `true`.
*/
fun setShouldShowGooglePay(shouldShowGooglePay: Boolean): Builder = apply {
this.shouldShowGooglePay = shouldShowGooglePay
}

/**
* @param allowedShippingCountryCodes A set of allowed country codes for the
* customer's shipping address. Will be ignored if empty.
Expand Down Expand Up @@ -250,6 +261,7 @@ data class PaymentSessionConfig internal constructor(
isShippingMethodRequired = shippingMethodsRequired,
addPaymentMethodFooterLayoutId = addPaymentMethodFooterLayoutId,
paymentMethodTypes = paymentMethodTypes,
shouldShowGooglePay = shouldShowGooglePay,
allowedShippingCountryCodes = allowedShippingCountryCodes,
shippingInformationValidator = shippingInformationValidator,
shippingMethodsFactory = shippingMethodsFactory,
Expand Down
11 changes: 9 additions & 2 deletions stripe/src/main/java/com/stripe/android/PaymentSessionData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ data class PaymentSessionData internal constructor(
/**
* @return the selected payment method for the associated [PaymentSession]
*/
val paymentMethod: PaymentMethod? = null
val paymentMethod: PaymentMethod? = null,

/**
* When `true`, the customer has indicated their intent to pay with Google Pay. Use the
* [Google Pay API](https://developers.google.com/pay/api/android/overview) to complete
* payment with Google Pay.
*/
val useGooglePay: Boolean = false
) : Parcelable {

/**
Expand All @@ -45,7 +52,7 @@ data class PaymentSessionData internal constructor(
*/
val isPaymentReadyToCharge: Boolean
get() =
paymentMethod != null && config != null &&
(paymentMethod != null || useGooglePay) && config != null &&
(!config.isShippingInfoRequired || shippingInformation != null) &&
(!config.isShippingMethodRequired || shippingMethod != null)
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,11 @@ class PaymentMethodsActivity : AppCompatActivity() {
}

private fun finishWithGooglePay() {
// TODO(mshafrir-stripe): set correct result - ANDROID-457
setResult(Activity.RESULT_OK,
Intent().putExtras(
PaymentMethodsActivityStarter.Result(useGooglePay = true).toBundle()
)
)

finish()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ class PaymentMethodsActivityStarter : ActivityStarter<PaymentMethodsActivity, Ar
* Payment Methods selection screen. If a user selects the Google Pay option,
* [PaymentMethodsActivityStarter.Result.useGooglePay] will be `true`.
*/
@JvmSynthetic
internal fun setShouldShowGooglePay(shouldShowGooglePay: Boolean): Builder = apply {
fun setShouldShowGooglePay(shouldShowGooglePay: Boolean): Builder = apply {
this.shouldShowGooglePay = shouldShowGooglePay
}

Expand Down Expand Up @@ -168,8 +167,8 @@ class PaymentMethodsActivityStarter : ActivityStarter<PaymentMethodsActivity, Ar
*/
@Parcelize
data class Result internal constructor(
@JvmField val paymentMethod: PaymentMethod?,
private val useGooglePay: Boolean = false
@JvmField val paymentMethod: PaymentMethod? = null,
val useGooglePay: Boolean = false
) : ActivityStarter.Result {
override fun toBundle(): Bundle {
val bundle = Bundle()
Expand Down
32 changes: 30 additions & 2 deletions stripe/src/test/java/com/stripe/android/PaymentSessionTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class PaymentSessionTest {
}

@Test
fun handlePaymentData_whenPaymentMethodRequest_notifiesListenerAndFetchesCustomer() {
fun handlePaymentData_whenPaymentMethodSelected_notifiesListenerAndFetchesCustomer() {
CustomerSession.instance = createCustomerSession()

val paymentSession = PaymentSession(activity)
Expand All @@ -128,7 +128,9 @@ class PaymentSessionTest {
// We have already tested the functionality up to here.
reset(paymentSessionListener)

val result = PaymentMethodsActivityStarter.Result(PaymentMethodFixtures.CARD_PAYMENT_METHOD)
val result = PaymentMethodsActivityStarter.Result(
paymentMethod = PaymentMethodFixtures.CARD_PAYMENT_METHOD
)
val handled = paymentSession.handlePaymentData(
PaymentMethodsActivityStarter.REQUEST_CODE, RESULT_OK,
Intent().putExtras(result.toBundle()))
Expand All @@ -138,6 +140,32 @@ class PaymentSessionTest {
.onPaymentSessionDataChanged(paymentSessionDataArgumentCaptor.capture())
val data = paymentSessionDataArgumentCaptor.firstValue
assertEquals(PaymentMethodFixtures.CARD_PAYMENT_METHOD, data.paymentMethod)
assertFalse(data.useGooglePay)
}

@Test
fun handlePaymentData_whenGooglePaySelected_notifiesListenerAndFetchesCustomer() {
CustomerSession.instance = createCustomerSession()

val paymentSession = PaymentSession(activity)
paymentSession.init(paymentSessionListener, PaymentSessionConfig.Builder().build())

// We have already tested the functionality up to here.
reset(paymentSessionListener)

val result = PaymentMethodsActivityStarter.Result(
useGooglePay = true
)
val handled = paymentSession.handlePaymentData(
PaymentMethodsActivityStarter.REQUEST_CODE, RESULT_OK,
Intent().putExtras(result.toBundle()))
assertTrue(handled)

verify(paymentSessionListener)
.onPaymentSessionDataChanged(paymentSessionDataArgumentCaptor.capture())
val data = paymentSessionDataArgumentCaptor.firstValue
assertNull(data.paymentMethod)
assertTrue(data.useGooglePay)
}

@Test
Expand Down