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

Block disallowed brands in PAN field #9471

Merged
merged 12 commits into from
Oct 21, 2024
Merged

Conversation

porter-stripe
Copy link
Contributor

@porter-stripe porter-stripe commented Oct 17, 2024

Summary

  • Show an error when a disallowed brand is entered into the PAN field and block payment
  • Filters out disallowed brands in the update card drop down for CBC
    • In the future we may just hide the edit icon and show remove icon in the event there is only 1 possible brand after filtering. Will consider this as post beta polish most likely, however we should still filter the brands in the case maybe there are co-branded cards w/ more than just 2 networks.
  • Adds a new localized string that is uploaded to Lokalise
  • Future PRs will include:
    • E2E tests
    • Analytics
    • Google Pay

Motivation

  • CBF

Testing

  • Manual
  • New unit tests

Screenshots

Screenshot_1729193808

Changelog

N/A

Copy link
Contributor

github-actions bot commented Oct 17, 2024

Diffuse output:

OLD: paymentsheet-example-release-master.apk (signature: V1, V2)
NEW: paymentsheet-example-release-pr.apk (signature: V1, V2)

          │           compressed           │          uncompressed          
          ├───────────┬───────────┬────────┼───────────┬───────────┬────────
 APK      │ old       │ new       │ diff   │ old       │ new       │ diff   
──────────┼───────────┼───────────┼────────┼───────────┼───────────┼────────
      dex │   4.1 MiB │   4.1 MiB │ +444 B │   8.9 MiB │   8.9 MiB │ +360 B 
     arsc │   2.3 MiB │   2.3 MiB │    0 B │   2.3 MiB │   2.3 MiB │    0 B 
 manifest │   5.1 KiB │   5.1 KiB │    0 B │  25.6 KiB │  25.6 KiB │    0 B 
      res │ 933.8 KiB │ 933.8 KiB │    0 B │   1.5 MiB │   1.5 MiB │    0 B 
   native │   2.6 MiB │   2.6 MiB │    0 B │     6 MiB │     6 MiB │    0 B 
    asset │   2.9 MiB │   2.9 MiB │   +5 B │   2.9 MiB │   2.9 MiB │   +5 B 
    other │ 201.3 KiB │ 201.3 KiB │   +5 B │ 443.4 KiB │ 443.4 KiB │    0 B 
──────────┼───────────┼───────────┼────────┼───────────┼───────────┼────────
    total │    13 MiB │    13 MiB │ +454 B │  22.1 MiB │  22.1 MiB │ +365 B 

 DEX     │ old   │ new   │ diff           
─────────┼───────┼───────┼────────────────
   files │     1 │     1 │  0             
 strings │ 42993 │ 42992 │ -1 (+5 -6)     
   types │ 14510 │ 14510 │  0 (+2 -2)     
 classes │ 12096 │ 12096 │  0 (+1 -1)     
 methods │ 62461 │ 62463 │ +2 (+850 -848) 
  fields │ 41052 │ 41054 │ +2 (+303 -301) 

 ARSC    │ old  │ new  │ diff 
─────────┼──────┼──────┼──────
 configs │  242 │  242 │  0   
 entries │ 6274 │ 6274 │  0
APK
    compressed     │    uncompressed    │                                           
──────────┬────────┼───────────┬────────┤                                           
 size     │ diff   │ size      │ diff   │ path                                      
──────────┼────────┼───────────┼────────┼───────────────────────────────────────────
  4.1 MiB │ +444 B │   8.9 MiB │ +360 B │ ∆ classes.dex                             
    1 KiB │   +7 B │     925 B │   +7 B │ ∆ assets/dexopt/baseline.profm            
 50.5 KiB │   +4 B │ 119.1 KiB │    0 B │ ∆ META-INF/MANIFEST.MF                    
  8.1 KiB │   -2 B │     8 KiB │   -2 B │ ∆ assets/dexopt/baseline.prof             
 53.7 KiB │   +2 B │ 119.2 KiB │    0 B │ ∆ META-INF/CERT.SF                        
    271 B │   -1 B │     120 B │    0 B │ ∆ META-INF/version-control-info.textproto 
──────────┼────────┼───────────┼────────┼───────────────────────────────────────────
  4.2 MiB │ +454 B │   9.1 MiB │ +365 B │ (total)
DEX
STRINGS:

   old   │ new   │ diff       
  ───────┼───────┼────────────
   42993 │ 42992 │ -1 (+5 -6) 
  
  + LLLLLLLZZ
  + Lx/w;
  + VLLLLLLZLLLLLLLLLLLZ
  + [Lo/O;
  + ~~R8{"backend":"dex","compilation-mode":"release","has-checksums":false,"min-api":21,"pg-map-id":"e1500e6","r8-mode":"full","version":"8.5.35"}
  
  - LLLLLLZZ
  - Lw7/c;
  - VLLLLLLZLLLLLLLLLLZ
  - VLLLLLZZ
  - [Lo/P;
  - ~~R8{"backend":"dex","compilation-mode":"release","has-checksums":false,"min-api":21,"pg-map-id":"1ac042f","r8-mode":"full","version":"8.5.35"}
  

TYPES:

   old   │ new   │ diff      
  ───────┼───────┼───────────
   14510 │ 14510 │ 0 (+2 -2) 
  
  + Lx/w;
  + [Lo/O;
  
  - Lw7/c;
  - [Lo/P;
  

METHODS:

   old   │ new   │ diff           
  ───────┼───────┼────────────────
   62461 │ 62463 │ +2 (+850 -848) 
  
  + A2.D <init>(a0)
  + A2.D J(int, int, T) → Typeface
  + A2.i a(r0)
  + A2.i create(b, c) → r0
  + A2.i create(Class) → r0
  + A2.i create(Class, c) → r0
  + A2.j <init>(k0)
  + A2.l getDefaultViewModelProviderFactory() → t0
  + A2.x create(b, c) → r0
  + A2.x create(Class) → r0
  + A2.x create(Class, c) → r0
  + B2.a <init>(k0)
  + B6.A <init>(a, k0, P, k, i, i0, v, d, F, String, i)
  + B7.g <init>(k0, b, c, a, r)
  + C.D g(v0, int, Bundle) → boolean
  + C.d <init>(boolean, a)
  + C.d p(HashSet, x, c)
  + C5.V s(KeyEvent) → int
  + C6.J <init>(k0)
  + C6.K <init>(k0)
  + C6.d <init>(k0, d)
  + C6.i <init>(c, b, m, d, k0)
  + F.e u(r0, k0) → o
  + F3.k e() → int
  + F3.k k()
  + G.i F(k, L1, v0) → ArrayList
  + G7.Q create(b, c) → r0
  + G7.Q create(Class) → r0
  + G7.Q create(Class, c) → r0
  + G7.e0 <init>(Application, k0, Uri)
  + H3.j e() → int
  + H5.D create(b, c) → r0
  + H5.D create(Class) → r0
  + H5.D create(Class, c) → r0
  + H5.E <init>(k0)
  + H5.s0 create(b, c) → r0
  + H5.s0 create(Class) → r0
  + H5.s0 create(Class, c) → r0
  + J6.A create(b, c) → r0
  + J6.A create(Class) → r0
  + J6.A create(Class, c) → r0
  + J6.G <init>(m, o, v, P, U, m, e, k0, f, i)
  + J6.Z <init>(m, o, W, P, m, e, k0)
  + L3.a e() → int
  + N0.g a(t0, b, c) → r0
  + N0.g b(t0, Class, c) → r0
  + Q5.G <init>(String, k0, B, t, f, d, a, l, v, t, P, u)
  + S0.g e(Activity, i0)
  + U5.a <init>(m, c, K2, k0, Application, i, a)
  + U7.E <init>(Application, k0)
  + V6.f create(b, c) → r0
  + V6.f create(Class) → r0
  + V6.f create(Class, c) → r0
  + Y8.s0 <init>(d, p, i, i, String, U, a)
  + Z3.b <init>(v0, View)
  + a8.F create(b, c) → r0
  + a8.F create(Class) → r0
  + a8.F create(Class, c) → r0
  + a8.H <init>(E, Application, a, k0)
  + androidx.activity.m getDefaultViewModelProviderFactory() → t0
  + androidx.appcompat.widget.ActionMenuView setOnMenuItemClickListener(o)
  + androidx.appcompat.widget.AppCompatTextView getEmojiTextViewHelper() → x
  + androidx.appcompat.widget.AppCompatTextView getSuperCaller() → Z
  + androidx.appcompat.widget.SwitchCompat getEmojiTextViewHelper() → x
  + androidx.fragment.app.H getDefaultViewModelProviderFactory() → t0
  + androidx.fragment.app.y0 getDefaultViewModelProviderFactory() → t0
  + androidx.lifecycle.Z <init>(b0)
  + androidx.lifecycle.a0 <init>(b0)
  + androidx.lifecycle.b0 <clinit>()
  + androidx.lifecycle.b0 <init>()
  + androidx.lifecycle.b0 a()
  + androidx.lifecycle.b0 getLifecycle() → v
  + androidx.lifecycle.c0 <init>(e, d)
  + androidx.lifecycle.c0 j(Object, Object) → Object
  + androidx.lifecycle.c0 s(d, Object) → d
  + androidx.lifecycle.c0 u(Object) → Object
  + androidx.lifecycle.d0 <init>(a, e, d)
  + androidx.lifecycle.e0 <init>(t, w, C, t, k, d, e)
  + androidx.lifecycle.e0 d(G, t)
  + androidx.lifecycle.f0 <init>(v, u, C, e, d)
  + androidx.lifecycle.f0 j(Object, Object) → Object
  + androidx.lifecycle.f0 s(d, Object) → d
  + androidx.lifecycle.f0 u(Object) → Object
  + androidx.lifecycle.g0 <init>(v, u, e, d)
  + androidx.lifecycle.i0 <clinit>()
  + androidx.lifecycle.i0 <init>()
  + androidx.lifecycle.i0 onActivityCreated(Activity, Bundle)
  + androidx.lifecycle.i0 onActivityDestroyed(Activity)
  + androidx.lifecycle.i0 onActivityPaused(Activity)
  + androidx.lifecycle.i0 onActivityPostCreated(Activity, Bundle)
  + androidx.lifecycle.i0 onActivityPostResumed(Activity)
  + androidx.lifecycle.i0 onActivityPostStarted(Activity)
  + androidx.lifecycle.i0 onActivityPreDestroyed(Activity)
  + androidx.lifecycle.i0 onActivityPrePaused(Activity)
  + androidx.lifecycle.i0 onActivityPreStopped(Activity)
  + androidx.lifecycle.i0 onActivityResumed(Activity)
  + androidx.lifecycle.i0 
...✂

@@ -521,7 +521,7 @@ internal class CardNumberControllerTest {
}

@Parcelize
private class FakeCardBrandFilter(
class FakeCardBrandFilter(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should probably bump this out to it's own file, since it's public now.

Copy link

emerge-tools bot commented Oct 21, 2024

2 builds increased size, 1 build decreased size

Name Version Download Change Install Change Approval
Stripe Identity Example
com.stripe.android.identity.example.theme1
20.52.1-theme1 (20) 3.8 MB ⬇️ 1.9 kB (-0.05%) 8.9 MB ⬇️ 1.0 kB (-0.01%) N/A
Financial Connections Example
com.stripe.android.financialconnections.example
20.52.1 (205201) 4.2 MB ⬆️ 4.2 kB (0.1%) 9.4 MB ⬆️ 3.4 kB (0.04%) N/A
PaymentSheet Example
com.stripe.android.paymentsheet.example
20.52.1 (11) 8.7 MB ⬆️ 118.7 kB (1.39%) 16.4 MB ⬆️ 244.0 kB (1.51%) N/A

Stripe Identity Example 20.52.1-theme1 (20)
com.stripe.android.identity.example.theme1

⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬇️ 1.0 kB (-0.01%)
Total download size change: ⬇️ 1.9 kB (-0.05%)

Largest size changes

Item Install Size Change Download Size Change
🗑 androidx.compose.ui.text.android.PaintExtensionsKt ⬇️ -23.2 kB ⬇️ -11.2 kB
androidx.compose.ui.input.key.KeyEvent_androidKt ⬆️ 20.7 kB ⬆️ 10.0 kB
🗑 kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt ⬇️ -19.0 kB ⬇️ -9.1 kB
kotlin.math.MathKt ⬇️ -18.0 kB ⬇️ -8.7 kB
androidx.camera.core.impl.utils.MainThreadAsyncHandler ⬇️ -16.9 kB ⬇️ -8.2 kB
View Treemap

Image of diff

Financial Connections Example 20.52.1 (205201)
com.stripe.android.financialconnections.example

⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 3.4 kB (0.04%)
Total download size change: ⬆️ 4.2 kB (0.1%)

Largest size changes

Item Install Size Change Download Size Change
🗑 _COROUTINE ⬇️ -60.4 kB ⬇️ -28.5 kB
📝 com.stripe.android.financialconnections.features.linkaccountpicke... ⬆️ 53.2 kB ⬆️ 25.2 kB
🗑 com.stripe.android.model.parsers.Stripe3ds2AuthResultJsonParser$A... ⬇️ -52.9 kB ⬇️ -25.0 kB
🗑 com.stripe.android.model.parsers.SourceCardDataJsonParser ⬇️ -43.8 kB ⬇️ -20.7 kB
kotlin.collections.SetsKt ⬇️ -38.6 kB ⬇️ -18.2 kB
View Treemap

Image of diff

PaymentSheet Example 20.52.1 (11)
com.stripe.android.paymentsheet.example

⚖️ Compare build
⏱️ Analyze build performance

Total install size change: ⬆️ 244.0 kB (1.51%)
Total download size change: ⬆️ 118.7 kB (1.39%)

Largest size changes

Item Install Size Change Download Size Change
📝 com.stripe.android.paymentsheet.ui.PaymentSheetScreenKt ⬆️ 41.6 kB ⬆️ 19.0 kB
🗑 com.stripe.android.stripecardscan.framework.ResourceFetcher ⬇️ -40.9 kB ⬇️ -18.7 kB
androidx.camera.core.impl.utils.executor.MainThreadExecutor ⬇️ -39.6 kB ⬇️ -18.1 kB
com.stripe.android.stripecardscan.payment.ml.CardDetectModelManag... ⬆️ 38.0 kB ⬆️ 17.4 kB
com.google.android.gms.dynamite.zzb ⬇️ -36.3 kB ⬇️ -16.6 kB
View Treemap

Image of diff


🛸 Powered by Emerge Tools

Comment trigger: Size diff threshold of 100.00kB exceeded

@@ -477,7 +477,11 @@ internal class CardNumberControllerTest {
cardBrandFilter: CardBrandFilter = DefaultCardBrandFilter
): DefaultCardNumberController {
return DefaultCardNumberController(
cardTextFieldConfig = CardNumberConfig(),
cardTextFieldConfig = CardNumberConfig(

Copy link
Collaborator

Choose a reason for hiding this comment

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

🙈

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the linter fails if I don't add that actually

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok nvm I guess it doesn't. Fixed!

Copy link
Collaborator

@jaynewstrom-stripe jaynewstrom-stripe left a comment

Choose a reason for hiding this comment

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

One last nit, if you don't mind fixing.

@porter-stripe porter-stripe merged commit b1a9d00 into master Oct 21, 2024
16 checks passed
@porter-stripe porter-stripe deleted the porter/cbf-pan-field branch October 21, 2024 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants