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

Rewriting credit card network bin rules and adding the card networks: JCB and Diners Club #107

Merged
merged 4 commits into from
Dec 19, 2019

Conversation

jaimejiyepark
Copy link
Collaborator

No description provided.

Copy link
Collaborator

@kingst kingst left a comment

Choose a reason for hiding this comment

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

It looks like Stripe is using ranges and has a different set of ranges then we have. Should we just adopt Stripe's logic? We'll get some bonus networks, like JCB, as well.

https://github.com/stripe/stripe-ios/blob/master/Stripe/STPBINRange.m

@jaimejiyepark
Copy link
Collaborator Author

Adam and I decided to follow the Stripe-android code for the bin rules since the the bin set is the most similar to the IIN's listed on wiki
https://en.wikipedia.org/wiki/Payment_card_number#Issuer_identification_number_(IIN)

Copy link
Collaborator

@kingst kingst left a comment

Choose a reason for hiding this comment

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

Generally looks good, left a few minor comments. Can you get Adam to approve this?

@@ -1,6 +1,25 @@
import Foundation

public struct CreditCardUtils {
static let cvcLengthAmericanExpress = 4
Copy link
Collaborator

Choose a reason for hiding this comment

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

are the cvc lengths getting used anywhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

no but i thought maybe we'd use them later?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe, but let's remove them for now and add them back when we need them.

static let cvcLengthAmericanExpress = 4
static let cvcLength = 3

static let maxPanLength = 16
Copy link
Collaborator

Choose a reason for hiding this comment

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

according to the iOS code some of the pans for visa are 14, do they not track that in the Android side?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

ok, as long as we're consistent I'm fine with it

@@ -25,15 +41,12 @@ public struct CreditCardUtils {
}

public static func isValidBin(number: String) -> Bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

In the android code, I used the determineCardNetwork method to check for validity. This is more readable an extensible than checking for each possible card:
https://github.com/getbouncer/cardscan-android/blob/master/cardscan-base/src/main/java/com/getbouncer/cardscan/base/CreditCardUtils.kt#L125

@@ -25,15 +41,12 @@ public struct CreditCardUtils {
}

public static func isValidBin(number: String) -> Bool {
return isAmex(number: number) || isDiscover(number: number) || isVisa(number: number) || isMastercard(number: number) || isUnionPay(number: number)
return isAmex(number: number) || isDiscover(number: number) || isVisa(number: number) || isMastercard(number: number) || isUnionPay(number: number) || isJcb(number: number) || isDinersClub(number: number)
}

public static func isAmex(number: String) -> Bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we get rid of these methods? Instead of specific isNetwork methods, we should simplify the methods using these.

For example, if we are using these methods to set an icon

if (CreditCardUtils.isAmex()) {
   setIcon(amexIcon)
} else if (CreditCardUtils.isUnionPay()) {
  setIcon(unionPay)
} else if ...

we should instead create a method in CreditCardUtils that returns the desired icon.

switch (determineCardNetwork(number)) {
    case VISA -> visaIcon
    case AMEX -> amexIcon
    ...
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Centralizing into one determineCardNetwork method also keeps all the prefix logic in one place instead of spread out around multiple methods

see https://github.com/getbouncer/cardscan-android/blob/master/cardscan-base/src/main/java/com/getbouncer/cardscan/base/CreditCardUtils.kt#L159

Copy link
Contributor

Choose a reason for hiding this comment

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

this also lets us more easily deal with prioritizing discover over unionpay when BINs overlap.

//

import XCTest
@testable import CardScan
Copy link
Contributor

Choose a reason for hiding this comment

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

NICE! thanks for adding tests for this!

@jaimejiyepark
Copy link
Collaborator Author

thank you @awushensky for all the feedback! let me fixes these changes

@jaimejiyepark jaimejiyepark merged commit 39fa16f into master Dec 19, 2019
@jaimejiyepark jaimejiyepark changed the title [RFC] bin rules Rewriting credit card network bin rules and adding the card networks: JCB and Diners Club Jan 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants