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

Card-scanning in PaymentSheet #4804

Merged
merged 153 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
153 commits
Select commit Hold shift + click to select a range
c5ef5ec
[WIP]
michelleb-stripe Aug 9, 2021
0c95106
Display and receive input for Credit Card number and CVC.
michelleb-stripe Aug 12, 2021
75e54d1
Add in the credit billing fields, need hidden visibility to work on a…
michelleb-stripe Aug 12, 2021
cd4ff51
Merge with master.
michelleb-stripe Aug 12, 2021
da41eb0
Billing code now shows the correct fields.
michelleb-stripe Aug 12, 2021
a9a04ac
Billing now added to the credit element.
michelleb-stripe Aug 12, 2021
2ceac10
Credit card number length verification corrected.
michelleb-stripe Aug 12, 2021
e35e2c7
Refactor Elements so each element (including sections) provide the fo…
michelleb-stripe Aug 17, 2021
f897f12
Add in the expiration date functionality.
michelleb-stripe Aug 18, 2021
53661e1
Merge branch 'master' into michelleb/credit-card-compose
michelleb-stripe Aug 21, 2021
4f20fb2
Refactor so that each element returns a flow of FormFieldEntries, so …
michelleb-stripe Aug 21, 2021
940f304
Fix unit test
michelleb-stripe Aug 23, 2021
e8fc0ff
Merge with master.
michelleb-stripe Aug 23, 2021
7e5ee6a
Rename class
michelleb-stripe Aug 23, 2021
c3d7b28
More rework
michelleb-stripe Aug 23, 2021
a61ea99
Merge with michelleb/refactor-section-form-fields
michelleb-stripe Aug 23, 2021
b3be29c
Get ready for merge with master
michelleb-stripe Aug 27, 2021
9a258ec
Merge with master.
michelleb-stripe Aug 29, 2021
57b617c
Merge with master
michelleb-stripe Sep 20, 2021
3e60136
Merge with master.
michelleb-stripe Nov 2, 2021
4d8ec20
Change from liveData to flow.
michelleb-stripe Nov 2, 2021
591a73e
Merge branch 'michelleb/convert-to-flow' into michelleb/credit-card-c…
michelleb-stripe Nov 2, 2021
2aeb3ef
Row is working but not expiry date
michelleb-stripe Nov 2, 2021
9161d4f
Make the keypad just numbers.
michelleb-stripe Nov 2, 2021
0441d0a
Make the keypad just numbers.
michelleb-stripe Nov 2, 2021
c41ec5d
Set the expiration month and date correctly in the formFieldValues
michelleb-stripe Nov 2, 2021
fdad41f
Update the focus to visit the CVC
michelleb-stripe Nov 2, 2021
43c9127
Handle a full text field state.
michelleb-stripe Nov 3, 2021
317a841
Merge with master
michelleb-stripe Nov 4, 2021
8e649c8
Unit tests
michelleb-stripe Nov 5, 2021
9ead541
ktlintFormat
michelleb-stripe Nov 5, 2021
939dba9
Format card number based on max pan for card number
michelleb-stripe Nov 5, 2021
60da73f
Cleanup date util for expiration month
michelleb-stripe Nov 5, 2021
f51f90b
Make the label flowable
michelleb-stripe Nov 5, 2021
fef63b3
Fix internals
michelleb-stripe Nov 9, 2021
f19cbe2
Cleanup
michelleb-stripe Nov 9, 2021
07cfa62
Cleanup
michelleb-stripe Nov 9, 2021
bd5d754
Merge with master
michelleb-stripe Nov 9, 2021
2722977
Fix unit tests
michelleb-stripe Nov 9, 2021
4bee0c1
ktlintFormat
michelleb-stripe Nov 9, 2021
4b78747
Undos
michelleb-stripe Nov 9, 2021
9242d80
ktlintFormat
michelleb-stripe Nov 9, 2021
b1cd5b0
Merge with master
michelleb-stripe Nov 11, 2021
239273d
Merge remote-tracking branch 'origin/master' into michelleb/credit-ca…
michelleb-stripe Nov 17, 2021
8eb4204
Merge with master
michelleb-stripe Nov 29, 2021
40fe6c0
Merge with master
michelleb-stripe Dec 2, 2021
adaed05
Ignore tests that cause other failures
michelleb-stripe Dec 5, 2021
667bd39
Merge branch 'master' into michelleb/credit-card-compose
michelleb-stripe Feb 3, 2022
7c5e474
Working on the merge.
michelleb-stripe Feb 4, 2022
1eee681
Almost building
michelleb-stripe Feb 4, 2022
7ed49f3
Get closer to master
michelleb-stripe Feb 4, 2022
e68a86a
Update files.
michelleb-stripe Feb 4, 2022
f0fa03a
Iterating
michelleb-stripe Feb 4, 2022
5ad3f10
Building
michelleb-stripe Feb 4, 2022
a3c9eae
Fix unit tests
michelleb-stripe Feb 4, 2022
e2f39c4
Cleanup
michelleb-stripe Feb 8, 2022
57677d8
Remove extra comment
michelleb-stripe Feb 8, 2022
6bee0a4
Fix failing tests
epan-stripe Feb 8, 2022
2c6e45c
Fix linting
epan-stripe Feb 8, 2022
8b5d2ae
Fix SaveForFutureUseController.label not showing
epan-stripe Feb 8, 2022
313f52a
Merge with master
michelleb-stripe Feb 8, 2022
c1e78f7
Cleanup
michelleb-stripe Feb 8, 2022
6c9cb94
apiDump
michelleb-stripe Feb 9, 2022
508b5ad
Merge with master
michelleb-stripe Feb 9, 2022
33b754a
apiDump
michelleb-stripe Feb 9, 2022
7819db6
Fix some failing tests, apiDump, ktlintFormat
michelleb-stripe Feb 10, 2022
b3917f9
Fix remaining failing tests, apiDump, ktlintFormat
michelleb-stripe Feb 10, 2022
95d8557
Fix todo
michelleb-stripe Feb 10, 2022
7af4ff5
Merge remote-tracking branch 'origin/master' into michelleb/credit-ca…
michelleb-stripe Feb 10, 2022
afd06c9
Simplify and add DateConfig tests and cleanup commented out code in T…
michelleb-stripe Feb 11, 2022
98043bd
Merge with master
michelleb-stripe Feb 11, 2022
8ca28d2
Merge remote-tracking branch 'origin/master' into michelleb/credit-ca…
michelleb-stripe Feb 14, 2022
9bf81f2
ktlintFormat apiDump
michelleb-stripe Feb 14, 2022
783039a
Merge with master
michelleb-stripe Feb 15, 2022
bf51053
Add icons to the IBAN, credit card and CVC fields. (#4359)
michelleb-stripe Feb 18, 2022
7979d18
Merge with master
michelleb-stripe Feb 22, 2022
bd3fb81
Merge with remote
michelleb-stripe Feb 22, 2022
a18c6c2
Add Card Metadata Service to CardNumberController (#4573)
epan-stripe Feb 25, 2022
b4cacba
Don't show cardbrand if there are multiple possibilities
epan-stripe Feb 25, 2022
06c5d00
Don't show cardbrand if there are multiple possibilities
epan-stripe Feb 25, 2022
c179b73
Merge branch 'michelleb/credit-card-compose' of github.com:stripe/str…
epan-stripe Feb 25, 2022
61200f9
Merge remote-tracking branch 'origin/master' into michelleb/credit-ca…
michelleb-stripe Feb 25, 2022
110ecd3
Merge with master
michelleb-stripe Feb 25, 2022
067ea3b
Material Theme information gathering.
michelleb-stripe Feb 25, 2022
36913d3
Revert "Material Theme information gathering."
michelleb-stripe Feb 25, 2022
167b00f
Immediately detect invalid card numbers (no brand)
epan-stripe Mar 1, 2022
8701f44
Fix invalid vs incomplete dateconfig error text
epan-stripe Mar 1, 2022
b6fff48
Fix CVC icon and next field focus
epan-stripe Mar 2, 2022
3ed0104
Fix expiry date accessibility reader
epan-stripe Mar 2, 2022
7f3d2f2
Merge branch 'master' into michelleb/credit-card-compose
epan-stripe Mar 2, 2022
d92df95
Fix merge issues
epan-stripe Mar 2, 2022
e2880f4
Add ability to move focus on delete
jameswoo-stripe Mar 3, 2022
81042c0
Merge remote-tracking branch 'origin/master' into michelleb/credit-ca…
michelleb-stripe Mar 3, 2022
219e999
Fix dark mode error underline
epan-stripe Mar 3, 2022
126de9a
Fix cursor and spacing position in card details
epan-stripe Mar 4, 2022
10f4f47
update icons and colors for future wardrobe work
skyler-stripe Mar 4, 2022
da16b49
Merge branch 'master' into michelleb/credit-card-compose
michelleb-stripe Mar 8, 2022
0d7f077
Merge branch 'michelleb/credit-card-compose' of github.com:stripe/str…
michelleb-stripe Mar 8, 2022
ba21e4a
Add card information title
epan-stripe Mar 8, 2022
0c87580
Add tests for card number formatting
epan-stripe Mar 9, 2022
7a60b61
Revert "Add tests for card number formatting"
epan-stripe Mar 9, 2022
d2ff7ba
Add country list to card and sepa billing spec. (#4669)
michelleb-stripe Mar 9, 2022
55a143b
Credit Card Address and focus bug fixes (#4665)
michelleb-stripe Mar 9, 2022
f111ac0
Fix width of rows (#4676)
epan-stripe Mar 11, 2022
f3d960b
Fix spacing for AMEX and Discover cards (#4672)
epan-stripe Mar 11, 2022
f8c7ec7
Don't show CVC error when CardBrand is unknown (#4681)
epan-stripe Mar 14, 2022
5fbad06
Stop accessibility talkback reading textfields twice (#4683)
epan-stripe Mar 14, 2022
c6363f2
Merge with master
michelleb-stripe Mar 14, 2022
c5c70e5
Merge branch 'michelleb/credit-card-compose' of github.com:stripe/str…
michelleb-stripe Mar 14, 2022
2ba55b8
ktformat
michelleb-stripe Mar 14, 2022
6fb7a3f
Fix detekt
michelleb-stripe Mar 14, 2022
b9095ff
checkbox colors read from theme object now
skyler-stripe Mar 15, 2022
74e4e3d
Initial implementation
epan-stripe Mar 18, 2022
3fe4155
Fix camera icon
epan-stripe Mar 23, 2022
f57c34c
Move design changes to different branch
epan-stripe Mar 23, 2022
c8b3779
Update camera icon design
epan-stripe Mar 24, 2022
ecdeafc
Add string resource for scan card text and remove "test" name
epan-stripe Mar 29, 2022
091965a
Use actual publishable key
epan-stripe Mar 29, 2022
13b81ab
Add removeCardScanFragment to StripeCardScanProxy
epan-stripe Mar 31, 2022
466d186
Restart fragment onResume and onPause
epan-stripe Mar 31, 2022
e768bc8
Restart fragment onResume and onPause
epan-stripe Mar 31, 2022
e2c7f3b
Merge branch 'elena/cardscanning' of github.com:stripe/stripe-android…
epan-stripe Mar 31, 2022
5d9abea
Merge branch 'master' of github.com:stripe/stripe-android into elena/…
epan-stripe Mar 31, 2022
3184ef0
Merge branch 'master' of github.com:stripe/stripe-android into elena/…
epan-stripe Mar 31, 2022
fabd5df
Merge branch 'elena/cardscanning' of github.com:stripe/stripe-android…
epan-stripe Mar 31, 2022
4c69279
Update to match CardScanSheet changes
epan-stripe Mar 31, 2022
da2f828
Fix scan card button styling
epan-stripe Mar 31, 2022
c973df5
Fix scan card button styling
epan-stripe Mar 31, 2022
51ed547
Merge branch 'elena/cardscanning' of github.com:stripe/stripe-android…
epan-stripe Mar 31, 2022
f8d4d13
Update CHANGELOG
epan-stripe Mar 31, 2022
accd9e8
Move CARD_SCAN_PARCELABLE_NAME to companion object
epan-stripe Apr 1, 2022
0b9ada6
Stop passing context in and delete CardDetailsSpec
epan-stripe Apr 1, 2022
fc0d5cf
Make CardScanActivity internal
epan-stripe Apr 1, 2022
40242b5
Make code segment more functional
epan-stripe Apr 1, 2022
2cb02da
Fix comment
epan-stripe Apr 1, 2022
c329abb
Add tests for StripeCardScanProxy
epan-stripe Apr 1, 2022
33cca0b
Fix tests
epan-stripe Apr 4, 2022
4c3c836
Fix tests
epan-stripe Apr 4, 2022
e34a80e
Merge branch 'elena/cardscanning' of github.com:stripe/stripe-android…
epan-stripe Apr 4, 2022
4ea2f2d
Stop setting Scan card button font weight
epan-stripe Apr 4, 2022
5c75cfa
Merge branch 'master' into elena/cardscanning
epan-stripe Apr 4, 2022
c9a9a54
Merge branch 'master' of github.com:stripe/stripe-android into elena/…
epan-stripe Apr 5, 2022
9fb81f7
Add context back to TransformSpecToElements
epan-stripe Apr 6, 2022
abfbea4
Add CardDetailsSectionController so credit card form values are passe…
epan-stripe Apr 6, 2022
9404f8d
Merge branch 'master' into elena/cardscanning
epan-stripe Apr 15, 2022
194c96b
Update CardScanActivity package
epan-stripe Apr 18, 2022
42daf14
Remove context from FormUI
epan-stripe Apr 19, 2022
a1772de
Add clarifying comment
epan-stripe Apr 19, 2022
8a21c3f
Remove unnecessary padding
epan-stripe Apr 19, 2022
88ede33
Create ScanCardButtonUI composable
epan-stripe Apr 19, 2022
6304213
Merge branch 'master' of github.com:stripe/stripe-android into elena/…
epan-stripe Apr 19, 2022
1d305cb
Move isStripeCardScan object to controller instead of Composable
epan-stripe Apr 20, 2022
cff7e81
Use material camera icon
epan-stripe Apr 20, 2022
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 @@ -25,6 +25,7 @@ This release patches on a crash on PaymentLauncher, updates the package name of
changes the public API for CardImageVerificationSheet and releases Identity SDK.

### Payments (`com.stripe:stripe-android`)
* [ADDED] [4804](https://github.com/stripe/stripe-android/pull/4804) Added card-scanning feature to PaymentSheet
* [FIXED] [4776](https://github.com/stripe/stripe-android/pull/4776) fix issue with PaymentLauncher configuration change
* [CHANGED] [4358](https://github.com/stripe/stripe-android/pull/4358) Updated the card element on
PaymentSheet to use Compose.
Expand Down
18 changes: 18 additions & 0 deletions payments-ui-core/api/payments-ui-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ public final class com/stripe/android/ui/core/address/AddressFieldElementReposit
public static fun newInstance (Landroid/content/res/Resources;)Lcom/stripe/android/ui/core/address/AddressFieldElementRepository;
}

public final class com/stripe/android/ui/core/databinding/ActivityCardScanBinding : androidx/viewbinding/ViewBinding {
public final field fragmentContainer Landroidx/fragment/app/FragmentContainerView;
public static fun bind (Landroid/view/View;)Lcom/stripe/android/ui/core/databinding/ActivityCardScanBinding;
public synthetic fun getRoot ()Landroid/view/View;
public fun getRoot ()Landroidx/constraintlayout/widget/ConstraintLayout;
public static fun inflate (Landroid/view/LayoutInflater;)Lcom/stripe/android/ui/core/databinding/ActivityCardScanBinding;
public static fun inflate (Landroid/view/LayoutInflater;Landroid/view/ViewGroup;Z)Lcom/stripe/android/ui/core/databinding/ActivityCardScanBinding;
}

public final class com/stripe/android/ui/core/elements/AffirmElementUIKt {
}

Expand All @@ -42,6 +51,15 @@ public final class com/stripe/android/ui/core/elements/BankRepository_Factory :
public final class com/stripe/android/ui/core/elements/BsbElementUIKt {
}

public final class com/stripe/android/ui/core/elements/CardDetailsSectionController : com/stripe/android/ui/core/elements/SectionFieldErrorController {
public static final field $stable I
public fun <init> (Landroid/content/Context;)V
public fun getError ()Lkotlinx/coroutines/flow/Flow;
}

public final class com/stripe/android/ui/core/elements/CardDetailsSectionElementUIKt {
}

public final class com/stripe/android/ui/core/elements/ComposableSingletons$AfterpayClearpayElementUIKt {
public static final field INSTANCE Lcom/stripe/android/ui/core/elements/ComposableSingletons$AfterpayClearpayElementUIKt;
public static field lambda-1 Lkotlin/jvm/functions/Function3;
Expand Down
3 changes: 3 additions & 0 deletions payments-ui-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ if (System.getenv("JITPACK")) {
dependencies {
implementation project(":stripe-core")
implementation project(":payments-core")
compileOnly project(":stripecardscan")

implementation 'androidx.constraintlayout:constraintlayout-compose:1.0.0'
implementation "androidx.core:core-ktx:$androidxCoreVersion"
Expand Down Expand Up @@ -63,6 +64,7 @@ dependencies {
testImplementation "androidx.test.ext:junit-ktx:$androidTestJunitVersion"
testImplementation "androidx.arch.core:core-testing:$androidxArchCoreVersion"
testImplementation "androidx.fragment:fragment-testing:$androidxFragmentVersion"
testImplementation project(':stripecardscan')

ktlint "com.pinterest:ktlint:$ktlintVersion"
}
Expand Down Expand Up @@ -102,6 +104,7 @@ android {

buildFeatures {
compose = true
viewBinding = true
}

testOptions {
Expand Down
13 changes: 13 additions & 0 deletions payments-ui-core/res/drawable/ic_photo_camera.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/black"
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
<path
android:fillColor="@android:color/black"
android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
</vector>
17 changes: 17 additions & 0 deletions payments-ui-core/res/layout/activity_card_scan.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
3 changes: 3 additions & 0 deletions payments-ui-core/res/values/totranslate.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@
-->
<!-- Card details section title for card form entry -->
<string name="card_information" tools:ignore="ExtraTranslation">Card information</string>

<!-- Scan card button -->
<string name="scan_card" tools:ignore="ExtraTranslation">Scan card</string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am looking up the translated string in localize and adding it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, got it in localize, and it will update the next time we run the script. Best to wait until this other PR is merged to run the localize script again. #4892

</resources>
7 changes: 7 additions & 0 deletions payments-ui-core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.stripe.android.ui.core">

<application>
<activity
android:name=".cardscan.CardScanActivity"
android:theme="@style/StripePaymentSheetDefaultTheme"
android:exported="false" />
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.stripe.android.ui.core
skyler-stripe marked this conversation as resolved.
Show resolved Hide resolved

internal interface IsStripeCardScanAvailable {
operator fun invoke(): Boolean
}

internal class DefaultIsStripeCardScanAvailable : IsStripeCardScanAvailable {
override fun invoke(): Boolean {
return try {
Class.forName("com.stripe.android.stripecardscan.cardscan.CardScanSheet")
true
} catch (_: Exception) {
false
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.stripe.android.ui.core

import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner
import com.stripe.android.BuildConfig
import com.stripe.android.stripecardscan.cardscan.CardScanSheet
import com.stripe.android.stripecardscan.cardscan.CardScanSheetResult

/**
* Proxy to access stripecardscan code safely
epan-stripe marked this conversation as resolved.
Show resolved Hide resolved
*
*/
internal interface StripeCardScanProxy {
fun present()

fun attachCardScanFragment(
lifecycleOwner: LifecycleOwner,
supportFragmentManager: FragmentManager,
@IdRes fragmentContainer: Int,
onFinished: (cardScanSheetResult: CardScanSheetResult) -> Unit
)

companion object {
fun create(
fragment: Fragment,
stripePublishableKey: String,
onFinished: (cardScanSheetResult: CardScanSheetResult) -> Unit,
provider: () -> StripeCardScanProxy = {
DefaultStripeCardScanProxy(CardScanSheet.create(fragment, stripePublishableKey, onFinished))
},
isStripeCardScanAvailable: IsStripeCardScanAvailable = DefaultIsStripeCardScanAvailable()
): StripeCardScanProxy {
return if (isStripeCardScanAvailable()) {
provider()
} else {
UnsupportedStripeCardScanProxy()
}
}

fun create(
activity: AppCompatActivity,
epan-stripe marked this conversation as resolved.
Show resolved Hide resolved
stripePublishableKey: String,
onFinished: (cardScanSheetResult: CardScanSheetResult) -> Unit,
provider: () -> StripeCardScanProxy = {
DefaultStripeCardScanProxy(CardScanSheet.create(activity, stripePublishableKey, onFinished))
},
isStripeCardScanAvailable: IsStripeCardScanAvailable = DefaultIsStripeCardScanAvailable()
): StripeCardScanProxy {
return if (isStripeCardScanAvailable()) {
provider()
} else {
UnsupportedStripeCardScanProxy()
}
}

fun removeCardScanFragment(
supportFragmentManager: FragmentManager,
isStripeCardScanAvailable: IsStripeCardScanAvailable = DefaultIsStripeCardScanAvailable()
) {
if (isStripeCardScanAvailable()) {
CardScanSheet.removeCardScanFragment(supportFragmentManager)
}
}
}
}

internal class DefaultStripeCardScanProxy(
private val cardScanSheet: CardScanSheet
) : StripeCardScanProxy {
override fun present() {
cardScanSheet.present()
}

override fun attachCardScanFragment(
lifecycleOwner: LifecycleOwner,
supportFragmentManager: FragmentManager,
fragmentContainer: Int,
onFinished: (cardScanSheetResult: CardScanSheetResult) -> Unit
) {
cardScanSheet.attachCardScanFragment(lifecycleOwner, supportFragmentManager, fragmentContainer, onFinished)
}
}

internal class UnsupportedStripeCardScanProxy : StripeCardScanProxy {
override fun present() {
if (BuildConfig.DEBUG) {
throw IllegalStateException(
"Missing stripecardscan dependency, please add it to your apps build.gradle"
epan-stripe marked this conversation as resolved.
Show resolved Hide resolved
)
}
}

override fun attachCardScanFragment(
lifecycleOwner: LifecycleOwner,
supportFragmentManager: FragmentManager,
fragmentContainer: Int,
onFinished: (cardScanSheetResult: CardScanSheetResult) -> Unit
) {
if (BuildConfig.DEBUG) {
throw IllegalStateException(
"Missing stripecardscan dependency, please add it to your apps build.gradle"
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.stripe.android.ui.core.cardscan

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.stripe.android.PaymentConfiguration
import com.stripe.android.stripecardscan.cardscan.CardScanSheetResult
import com.stripe.android.ui.core.R
import com.stripe.android.ui.core.StripeCardScanProxy
import com.stripe.android.ui.core.databinding.ActivityCardScanBinding

internal class CardScanActivity : AppCompatActivity() {
epan-stripe marked this conversation as resolved.
Show resolved Hide resolved
private val viewBinding by lazy {
ActivityCardScanBinding.inflate(layoutInflater)
}

private lateinit var stripeCardScanProxy: StripeCardScanProxy

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(viewBinding.root)

stripeCardScanProxy = StripeCardScanProxy.create(
this, PaymentConfiguration.getInstance(this).publishableKey, this::onScanFinished
)
}

override fun onStart() {
super.onStart()
stripeCardScanProxy.attachCardScanFragment(
this, supportFragmentManager, R.id.fragment_container, this::onScanFinished
)
}

private fun onScanFinished(result: CardScanSheetResult) {
val intent = Intent()
.putExtra(
CARD_SCAN_PARCELABLE_NAME,
result
)
setResult(RESULT_OK, intent)
finish()
}

override fun onStop() {
StripeCardScanProxy.removeCardScanFragment(supportFragmentManager)
super.onStop()
}

companion object {
const val CARD_SCAN_PARCELABLE_NAME = "CardScanActivityResult"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.stripe.android.ui.core.elements

import android.content.Context
import com.stripe.android.ui.core.DefaultIsStripeCardScanAvailable

class CardDetailsSectionController(context: Context) : SectionFieldErrorController {

internal val cardDetailsElement = CardDetailsElement(
IdentifierSpec.Generic("card_detail"), context
)

internal val isStripeCardScanAvailable = DefaultIsStripeCardScanAvailable()

override val error = cardDetailsElement.controller.error
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.stripe.android.ui.core.elements

import android.content.Context
import androidx.annotation.RestrictTo
import com.stripe.android.ui.core.forms.FormFieldEntry
import kotlinx.coroutines.flow.Flow

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
data class CardDetailsSectionElement(
val context: Context,
override val identifier: IdentifierSpec,
override val controller: CardDetailsSectionController = CardDetailsSectionController(context),
) : FormElement() {
override fun getFormFieldValueFlow(): Flow<List<Pair<IdentifierSpec, FormFieldEntry>>> =
controller.cardDetailsElement.getFormFieldValueFlow()

override fun getTextFieldIdentifiers(): Flow<List<IdentifierSpec>> =
controller.cardDetailsElement.getTextFieldIdentifiers()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.stripe.android.ui.core.elements

import androidx.annotation.RestrictTo
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import com.stripe.android.stripecardscan.cardscan.CardScanSheetResult
import com.stripe.android.stripecardscan.cardscan.exception.UnknownScanException
import com.stripe.android.ui.core.R
import com.stripe.android.ui.core.cardscan.CardScanActivity

@Composable
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
fun CardDetailsSectionElementUI(
enabled: Boolean,
controller: CardDetailsSectionController,
hiddenIdentifiers: List<IdentifierSpec>?
) {

Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
) {
H6Text(
text = stringResource(R.string.card_information),
modifier = Modifier
.semantics(mergeDescendants = true) { // Need to prevent form as focusable accessibility
epan-stripe marked this conversation as resolved.
Show resolved Hide resolved
heading()
}
)
if (controller.isStripeCardScanAvailable()) {
ScanCardButtonUI {
controller.cardDetailsElement.controller.numberElement.controller.onCardScanResult(
it.getParcelableExtra(CardScanActivity.CARD_SCAN_PARCELABLE_NAME)
?: CardScanSheetResult.Failed(
UnknownScanException("No data in the result intent")
)
)
}
}
}
SectionElementUI(
enabled,
SectionElement(
IdentifierSpec.Generic("credit_details"),
listOf(controller.cardDetailsElement),
SectionController(null, listOf(controller.cardDetailsElement.sectionFieldErrorController()))
),
hiddenIdentifiers ?: emptyList(),
IdentifierSpec.Generic("card_details")
)
}
Loading