From 1cfd6a4d98f906af1039602857323a70292bf20a Mon Sep 17 00:00:00 2001 From: Michael Shafrir Date: Tue, 24 Dec 2019 14:16:34 -0500 Subject: [PATCH] Create TokenizationMethod enum If a card number is tokenized, this is the method that was used. https://stripe.com/docs/api/cards/object#card_object-tokenization_method --- .../java/com/stripe/android/model/Card.kt | 8 ++--- .../stripe/android/model/CustomerSource.kt | 6 ++-- .../stripe/android/model/SourceCardData.kt | 2 +- .../android/model/TokenizationMethod.kt | 17 ++++++++++ .../android/model/parsers/CardJsonParser.kt | 7 +++- .../model/parsers/SourceCardDataJsonParser.kt | 5 ++- .../com/stripe/android/model/CardFixtures.kt | 33 +++++++++++++++++++ .../model/parsers/CardJsonParserTest.kt | 16 +++++++++ .../parsers/SourceCardDataJsonParserTest.kt | 3 +- 9 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 stripe/src/main/java/com/stripe/android/model/TokenizationMethod.kt create mode 100644 stripe/src/test/java/com/stripe/android/model/parsers/CardJsonParserTest.kt diff --git a/stripe/src/main/java/com/stripe/android/model/Card.kt b/stripe/src/main/java/com/stripe/android/model/Card.kt index 38a3a7606be..604a25ce647 100644 --- a/stripe/src/main/java/com/stripe/android/model/Card.kt +++ b/stripe/src/main/java/com/stripe/android/model/Card.kt @@ -188,7 +188,7 @@ data class Card internal constructor( * * [API Reference](https://stripe.com/docs/api/cards/object#card_object-tokenization_method) */ - internal val tokenizationMethod: String?, + val tokenizationMethod: TokenizationMethod? = null, /** * @return Set of key-value pairs that you can attach to an object. This can be useful fo @@ -408,7 +408,7 @@ data class Card internal constructor( private var customerId: String? = null private var cvcCheck: String? = null private var id: String? = null - private var tokenizationMethod: String? = null + private var tokenizationMethod: TokenizationMethod? = null private var metadata: Map? = null private var loggingTokens: List? = null @@ -485,7 +485,7 @@ data class Card internal constructor( this.id = id } - fun tokenizationMethod(tokenizationMethod: String?): Builder = apply { + fun tokenizationMethod(tokenizationMethod: TokenizationMethod?): Builder = apply { this.tokenizationMethod = tokenizationMethod } @@ -528,7 +528,7 @@ data class Card internal constructor( customerId = customerId.takeUnless { it.isNullOrBlank() }, cvcCheck = cvcCheck.takeUnless { it.isNullOrBlank() }, id = id.takeUnless { it.isNullOrBlank() }, - tokenizationMethod = tokenizationMethod.takeUnless { it.isNullOrBlank() }, + tokenizationMethod = tokenizationMethod, metadata = metadata, loggingTokens = loggingTokens.orEmpty().toMutableList() ) diff --git a/stripe/src/main/java/com/stripe/android/model/CustomerSource.kt b/stripe/src/main/java/com/stripe/android/model/CustomerSource.kt index ecdf5ccfe5d..7ac6ea6eff8 100644 --- a/stripe/src/main/java/com/stripe/android/model/CustomerSource.kt +++ b/stripe/src/main/java/com/stripe/android/model/CustomerSource.kt @@ -19,8 +19,10 @@ data class CustomerSource internal constructor( val paymentAsCard = asCard() return if (paymentAsSource != null && Source.SourceType.CARD == paymentAsSource.type) { val cardData = paymentAsSource.sourceTypeModel as SourceCardData? - cardData?.tokenizationMethod - } else paymentAsCard?.tokenizationMethod + cardData?.tokenizationMethod?.code + } else { + paymentAsCard?.tokenizationMethod?.code + } } val sourceType: String diff --git a/stripe/src/main/java/com/stripe/android/model/SourceCardData.kt b/stripe/src/main/java/com/stripe/android/model/SourceCardData.kt index 9cd0ff69c00..0a8fa995266 100644 --- a/stripe/src/main/java/com/stripe/android/model/SourceCardData.kt +++ b/stripe/src/main/java/com/stripe/android/model/SourceCardData.kt @@ -28,7 +28,7 @@ data class SourceCardData internal constructor( @get:ThreeDSecureStatus val threeDSecureStatus: String?, - val tokenizationMethod: String? + val tokenizationMethod: TokenizationMethod? = null ) : StripeSourceTypeModel() { @Retention(AnnotationRetention.SOURCE) @StringDef(ThreeDSecureStatus.REQUIRED, ThreeDSecureStatus.OPTIONAL, diff --git a/stripe/src/main/java/com/stripe/android/model/TokenizationMethod.kt b/stripe/src/main/java/com/stripe/android/model/TokenizationMethod.kt new file mode 100644 index 00000000000..6429ac6c74f --- /dev/null +++ b/stripe/src/main/java/com/stripe/android/model/TokenizationMethod.kt @@ -0,0 +1,17 @@ +package com.stripe.android.model + +/** + * If a card number is tokenized, this is the method that was used. Can be apple_pay or google_pay. + */ +enum class TokenizationMethod(val code: String) { + ApplePay("apple_pay"), + GooglePay("google_pay"); + + internal companion object { + internal fun fromCode(code: String?): TokenizationMethod? { + return values().firstOrNull { + it.code == code + } + } + } +} diff --git a/stripe/src/main/java/com/stripe/android/model/parsers/CardJsonParser.kt b/stripe/src/main/java/com/stripe/android/model/parsers/CardJsonParser.kt index 243f881a5c6..b1722c21ecb 100644 --- a/stripe/src/main/java/com/stripe/android/model/parsers/CardJsonParser.kt +++ b/stripe/src/main/java/com/stripe/android/model/parsers/CardJsonParser.kt @@ -4,6 +4,7 @@ import com.stripe.android.model.Card import com.stripe.android.model.Card.FundingType import com.stripe.android.model.CardBrand import com.stripe.android.model.StripeJsonUtils +import com.stripe.android.model.TokenizationMethod import org.json.JSONObject internal class CardJsonParser : ModelJsonParser { @@ -40,7 +41,11 @@ internal class CardJsonParser : ModelJsonParser { .id(StripeJsonUtils.optString(json, FIELD_ID)) .last4(StripeJsonUtils.optString(json, FIELD_LAST4)) .name(StripeJsonUtils.optString(json, FIELD_NAME)) - .tokenizationMethod(StripeJsonUtils.optString(json, FIELD_TOKENIZATION_METHOD)) + .tokenizationMethod( + TokenizationMethod.fromCode( + StripeJsonUtils.optString(json, FIELD_TOKENIZATION_METHOD) + ) + ) .metadata(StripeJsonUtils.optHash(json, FIELD_METADATA)) .build() } diff --git a/stripe/src/main/java/com/stripe/android/model/parsers/SourceCardDataJsonParser.kt b/stripe/src/main/java/com/stripe/android/model/parsers/SourceCardDataJsonParser.kt index 6db4a755ccc..e857fb21768 100644 --- a/stripe/src/main/java/com/stripe/android/model/parsers/SourceCardDataJsonParser.kt +++ b/stripe/src/main/java/com/stripe/android/model/parsers/SourceCardDataJsonParser.kt @@ -5,6 +5,7 @@ import com.stripe.android.model.Card import com.stripe.android.model.CardBrand import com.stripe.android.model.SourceCardData import com.stripe.android.model.StripeJsonUtils +import com.stripe.android.model.TokenizationMethod import java.util.Locale import org.json.JSONObject @@ -24,7 +25,9 @@ internal class SourceCardDataJsonParser : ModelJsonParser { threeDSecureStatus = asThreeDSecureStatus( StripeJsonUtils.optString(json, FIELD_THREE_D_SECURE) ), - tokenizationMethod = StripeJsonUtils.optString(json, FIELD_TOKENIZATION_METHOD) + tokenizationMethod = TokenizationMethod.fromCode( + StripeJsonUtils.optString(json, FIELD_TOKENIZATION_METHOD) + ) ) } diff --git a/stripe/src/test/java/com/stripe/android/model/CardFixtures.kt b/stripe/src/test/java/com/stripe/android/model/CardFixtures.kt index 00f914c720f..38ffcbdc82a 100644 --- a/stripe/src/test/java/com/stripe/android/model/CardFixtures.kt +++ b/stripe/src/test/java/com/stripe/android/model/CardFixtures.kt @@ -93,4 +93,37 @@ object CardFixtures { } """.trimIndent() ))) + + internal val CARD_GOOGLE_PAY = requireNotNull(CardJsonParser().parse(JSONObject( + """ + { + "id": "card_189fi32eZvKYlo2CHK8NPRME", + "object": "card", + "address_city": "Des Moines", + "address_country": "US", + "address_line1": "123 Any Street", + "address_line1_check": "unavailable", + "address_line2": "456", + "address_state": "IA", + "address_zip": "50305", + "address_zip_check": "unavailable", + "brand": "Visa", + "country": "US", + "currency": "usd", + "customer": "customer77", + "cvc_check": "unavailable", + "exp_month": 8, + "exp_year": 2017, + "funding": "credit", + "fingerprint": "abc123", + "last4": "4242", + "name": "John Cardholder", + "tokenization_method": "google_pay", + "metadata": { + "color": "blue", + "animal": "dog" + } + } + """.trimIndent() + ))) } diff --git a/stripe/src/test/java/com/stripe/android/model/parsers/CardJsonParserTest.kt b/stripe/src/test/java/com/stripe/android/model/parsers/CardJsonParserTest.kt new file mode 100644 index 00000000000..b1ffb68f245 --- /dev/null +++ b/stripe/src/test/java/com/stripe/android/model/parsers/CardJsonParserTest.kt @@ -0,0 +1,16 @@ +package com.stripe.android.model.parsers + +import com.stripe.android.model.CardFixtures +import com.stripe.android.model.TokenizationMethod +import kotlin.test.Test +import kotlin.test.assertEquals + +class CardJsonParserTest { + @Test + fun parseGooglePayCard() { + assertEquals( + TokenizationMethod.GooglePay, + CardFixtures.CARD_GOOGLE_PAY.tokenizationMethod + ) + } +} diff --git a/stripe/src/test/java/com/stripe/android/model/parsers/SourceCardDataJsonParserTest.kt b/stripe/src/test/java/com/stripe/android/model/parsers/SourceCardDataJsonParserTest.kt index 531a810fe99..b4c8954f810 100644 --- a/stripe/src/test/java/com/stripe/android/model/parsers/SourceCardDataJsonParserTest.kt +++ b/stripe/src/test/java/com/stripe/android/model/parsers/SourceCardDataJsonParserTest.kt @@ -4,6 +4,7 @@ import com.stripe.android.model.Card import com.stripe.android.model.CardBrand import com.stripe.android.model.SourceCardData import com.stripe.android.model.SourceFixtures +import com.stripe.android.model.TokenizationMethod import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotNull @@ -36,7 +37,7 @@ class SourceCardDataJsonParserTest { assertEquals(2050, CARD_DATA.expiryYear) assertEquals("US", CARD_DATA.country) assertEquals("optional", CARD_DATA.threeDSecureStatus) - assertEquals("apple_pay", CARD_DATA.tokenizationMethod) + assertEquals(TokenizationMethod.ApplePay, CARD_DATA.tokenizationMethod) } @Test