revtel / react-native-nfc-manager

React Native NFC module for Android & iOS
MIT License
1.39k stars 319 forks source link

read creditcard #173

Closed deividnn closed 3 years ago

deividnn commented 5 years ago

its possible read credit card whith iso7816emv?

MaxWilliamJF commented 5 years ago

Any updates?

whitedogg13 commented 5 years ago

Yes, it should work with any iso7816 compliant NFC cards.

ghost commented 5 years ago

@MaxWilliamJF @deividnn Did you end up getting credit card reading working with this library?

toxipat commented 4 years ago

is there any way to get the credit card number?

toxipat commented 4 years ago

Yes, it should work with any iso7816 compliant NFC cards.

How?

Bad-Listener commented 4 years ago

Any updates on this one?

I am a little lost...

I succesfully scan the tag of the card, but I cannot understand how to get i.e. cardnumber

selcukitmis commented 3 years ago

@whitedogg13 how can I read credit card ? I tried the example project but it's didn't work. Can you give an example.

gabimoncha commented 3 years ago

I am also interested in this feature :)

whitedogg13 commented 3 years ago

@gabrielmoncea it's awesome, please feel free to submit a PR! Since most of this feature relates to APDU passing using IsoDep NfcTech, maybe we can consider start this from an example.

gabimoncha commented 3 years ago

@whitedogg13 I would love to help. Can I do this only through JavaScript?

whitedogg13 commented 3 years ago

@gabrielmoncea sure, I believe it's possible!

deanpretorius commented 3 years ago

@whitedogg13 I would also love to help with this feature! A tutorial seems to be in demand, and I would love to implement this feature in an app I am designing.

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

github-actions[bot] commented 3 years ago

This issue was closed because it has been stalled for 5 days with no activity.

ronaldo058 commented 2 years ago

Has there been any solution to this ?

MaxWilliamJF commented 2 years ago

@MaxWilliamJF @deividnn Did you end up getting credit card reading working with this library?

No =(

ws7one commented 2 years ago

This seems to be a commonly requested implementation of this library. Has there been any solution to this?

lmatamoros commented 1 year ago

Visa example

"node-emv": "^1.0.22" "react-native-nfc-manager": "^3.14.2"

import NfcManager, { NfcTech } from 'react-native-nfc-manager'
import emv from 'node-emv'

readVisaCreditCard = async () => {
    try {
        NfcManager.cancelTechnologyRequest()
    } catch (error) { }

    try {
        const commands = [
            "00A404000E325041592E5359532E444446303100",
            "00A4040007A00000000310100E",
            "80A800002383212800000000000000000000000000000002500000000000097820052600E8DA935200"
        ]

        await NfcManager.requestTechnology([NfcTech.IsoDep])

        const responses = []

        for (let i = 0; i < commands.length; i++) {
            const resp = await NfcManager.isoDepHandler.transceive(this.toByteArray(commands[i]))
            responses.push(resp)
        }

        if (responses && responses.length > 2) {
            const r = await this.getEmvInfo(this.toHexString(responses[2]))
            if (r) {
                const cardInfo = this.getCardInfoVisa(r)
                if (cardInfo) {
                    return {
                        card: cardInfo.card,
                        exp: cardInfo.exp
                    }
                } else {
                    return null
                }
            } else {
                return null
            }
        } else {
            return null
        }
    } catch (error) {
        return null
    } finally {
        NfcManager.cancelTechnologyRequest()
    }
}

getEmvInfo = (info) => {
    return new Promise((resolve) => {
        emv.describe(info, (data) => {
            if (data) {
                resolve(data)
            } else {
                resolve(null)
            }
        })
    })
}

toByteArray = (text) => {
    return text.match(/.{1,2}/g).map(b => {
        return parseInt(b, 16)
    })
}

toHexString = (byteArr) => {
    return byteArr.reduce((acc, byte) => {
        return (
            acc + ('00' + byte.toString(16).toUpperCase()).slice(-2)
        )
    }, '')
}

getCardInfoVisa = (responses) => {
    let res
    let end = false
    for (let i = 0; i < responses.length; i++) {
        const r = responses[i]
        if (r.tag === "77" && r.value && r.value.length > 0) {
            for (let j = 0; j < r.value.length; j++) {
                const e = r.value[j]
                if (e.tag === "57" && e.value) {
                    const parts = e.value.split("D")
                    if (parts.length > 1) {
                        res = {
                            card: parts[0],
                            exp: parts[1].substring(0, 4)
                        }
                        end = true
                    }
                }

                if (end) {
                    break
                }
            }

            if (end) {
                break
            }
        }
    }
    return res
}
Beejay-bot commented 1 year ago

Hey @lmatamoros thanks so much your solution worked for the visa card 🙌🏾. Do you have any idea on how to go about to read Mastercard ATM cards

lmatamoros commented 1 year ago

@Beejay-bot

Mastercard example

import NfcManager, { NfcTech } from 'react-native-nfc-manager'
import emv from 'node-emv'

readMasterCardCreditCard = async () => {
    try {
        NfcManager.cancelTechnologyRequest()
    } catch (error) { }

    try {
        const commands = [
            "00A4040007A00000000410100E",
            "80A8000002830000",
            "00B2011400",
            "00B2010C00",
            "00B2012400",
            "00B2022400"
        ]

        await NfcManager.requestTechnology([NfcTech.IsoDep])

        const responses = []

        for (let i = 0; i < commands.length; i++) {
            const resp = await NfcManager.isoDepHandler.transceive(this.toByteArray(commands[i]))
            responses.push(resp)
        }

        if (responses && responses.length > 3) {
            const r = await this.getEmvInfo(this.toHexString(responses[3]))
            if (r) {
                const cardInfo = this.getCardInfoMasterCard(r)
                if (cardInfo) {
                    return {
                        card: cardInfo.card,
                        exp: cardInfo.exp
                    }
                } else {
                    return null
                }
            } else {
                return null
            }
        } else {
            return null
        }
    } catch (error) {
        return null
    } finally {
        NfcManager.cancelTechnologyRequest()
    }
}

getEmvInfo = (info) => {
    return new Promise((resolve) => {
        emv.describe(info, (data) => {
            if (data) {
                resolve(data)
            } else {
                resolve(null)
            }
        })
    })
}

toByteArray = (text) => {
    return text.match(/.{1,2}/g).map(b => {
        return parseInt(b, 16)
    })
}

toHexString = (byteArr) => {
    return byteArr.reduce((acc, byte) => {
        return (
            acc + ('00' + byte.toString(16).toUpperCase()).slice(-2)
        )
    }, '')
}

getCardInfoMasterCard = (responses) => {
    let res
    let end = false
    for (let i = 0; i < responses.length; i++) {
        const r = responses[i]
        if (r.tag === "70" && r.value && r.value.length > 0) {
            for (let j = 0; j < r.value.length; j++) {
                const e = r.value[j]
                if (e.tag === "5A" && e.value) {
                    if (!res) {
                        res = {
                            card: e.value
                        }
                    } else {
                        res.card = e.value
                    }

                    if (res.card && res.exp) {
                        end = true
                    }
                }

                if (e.tag === "5F24" && e.value) {
                    if (!res) {
                        res = {
                            exp: e.value
                        }
                    } else {
                        res.exp = e.value
                    }

                    if (res.card && res.exp) {
                        end = true
                    }
                }

                if (end) {
                    break
                }
            }

            if (end) {
                break
            }
        }
    }
    return res
}
tamilmani12 commented 1 year ago

@lmatamoros please share some ideas thank you

Ali12275 commented 1 year ago

@lmatamoros can you help me to get debit card details for both visa and master i am getting response like this for debit card lenHex: 82 lenBin: 10000010 ---> len is more than 1 byte LOG length (decimals): 0 offset: 14 - this is for the substring of emv_data LOG [{"length": "82", "tag": "6A", "value": []}] r

Noitidart commented 1 year ago

This is very helpful, thanks for sharing. Just redirecting users from this issue to here - https://github.com/revtel/react-native-nfc-manager/issues/632

Is the techniques here similar to what Stripe does? Stripe makes it sound like Android and iOS can scan any (not just visa or mastercard) - https://stripe.com/en-au/terminal/tap-to-pay (screenshot below)

This module for Android seems like it can scan all cards in one shot too - https://github.com/pro100svitlo/Credit-Card-NFC-Reader

iOS seems to be allowing payment AID now - https://developer.apple.com/documentation/proximityreader/setting-up-the-entitlement-for-tap-to-pay-on-iphone?language=objc

image
tamilmani12 commented 1 year ago

@lmatamoros can you help me to get debit card details for both visa and master i am getting response like this for debit card lenHex: 82 lenBin: 10000010 ---> len is more than 1 byte LOG length (decimals): 0 offset: 14 - this is for the substring of emv_data LOG [{"length": "82", "tag": "6A", "value": []}] r

did you resolved this?

Laulhus commented 12 months ago

@lmatamoros can you help me to get debit card details for both visa and master i am getting response like this for debit card lenHex: 82 lenBin: 10000010 ---> len is more than 1 byte LOG length (decimals): 0 offset: 14 - this is for the substring of emv_data LOG [{"length": "82", "tag": "6A", "value": []}] r

I managed to read my VISA debit card following @lmatamoros implementation but updating the commands variable to the following:

const commands = [ '00A404000E325041592E5359532E444446303100', '00A4040007A000000003101000', '80A80000238321F620C00000000000000100000000000007240000000000097823112300194E172C00', '80A800002383212800000000000000000000000000000002500000000000097820052600E8DA935200', '80CA9F1700', '80CA9F3600', ];

reggiegutter commented 11 months ago

Hi, @lmatamoros and @Laulhus, where did guys find the commands necessary for each card type? I've been searching online and can't find anything. It would be super helpful if you could share a bit more.

Also, is it possible to verify the PIN using this library? I'm still trying to understand all that's involved with accepting contactless payment with an Android Phone. From what I understood until now, if I can verify the PIN then this is enough to build something like a SoftPOS to receive payments.

lmatamoros commented 11 months ago

Hi, @lmatamoros and @Laulhus, where did guys find the commands necessary for each card type? I've been searching online and can't find anything. It would be super helpful if you could share a bit more.

Also, is it possible to verify the PIN using this library? I'm still trying to understand all that's involved with accepting contactless payment with an Android Phone. From what I understood until now, if I can verify the PIN then this is enough to build something like a SoftPOS to receive payments.

You can't get the CVV or the cardholder's name using NFC.

reggiegutter commented 11 months ago

Yes, I'm aware of that. What I want is to validade the PIN, trough an APDU command. That would enable receiving payments with the Android phone.

Noitidart commented 11 months ago

Thanks for these questions, I wasn't aware you couldn't get card holder or CVV name from NFC.

Laulhus commented 11 months ago

Hi, @lmatamoros and @Laulhus, where did guys find the commands necessary for each card type? I've been searching online and can't find anything. It would be super helpful if you could share a bit more.

Also, is it possible to verify the PIN using this library? I'm still trying to understand all that's involved with accepting contactless payment with an Android Phone. From what I understood until now, if I can verify the PIN then this is enough to build something like a SoftPOS to receive payments.

Hi @reggiegutter ! In my case I used another app that reads credit cards with NFC and lets you check the logs where you can find these commands.

https://play.google.com/store/apps/details?id=com.github.devnied.emvnfccard

That's the app although there must be a way to get those commands online depending on the card presented, don't know much more about it

tgreco commented 9 months ago

Anyone interested in where the magic values are: https://github.com/devnied/EMV-NFC-Paycard-Enrollment/blob/master/library/src/main/java/com/github/devnied/emvnfccard/enums/EmvCardScheme.java#L32

joviksdev commented 7 months ago

toHexString

I am getting same issues too, any one with solution to this.

Siti-Shaufi commented 6 months ago

Hi @lmatamoros

Do you have any idea for amex cards? The emv result in empty. This is the commands that I used.

const commands = [
        "00A404000E325041592E5359532E444446303100", // Select PPSE
        "00A4040007A0000000250101", // Select Amex application
        "A000000025", // American Express
        "A0000000250000", // American Express
        "A00000002501", // American Express
        "A000000025010104", // American Express
        "A000000025010402", // American Express
        "A000000025010701", // American Express
        "A000000025010801", // American Express
      ];

Thanks

altaga commented 2 months ago

@Beejay-bot

Mastercard example

import NfcManager, { NfcTech } from 'react-native-nfc-manager'
import emv from 'node-emv'

readMasterCardCreditCard = async () => {
  try {
      NfcManager.cancelTechnologyRequest()
    } catch (error) { }

  try {
      const commands = [
          "00A4040007A00000000410100E",
          "80A8000002830000",
          "00B2011400",
          "00B2010C00",
          "00B2012400",
          "00B2022400"
      ]

      await NfcManager.requestTechnology([NfcTech.IsoDep])

      const responses = []

      for (let i = 0; i < commands.length; i++) {
          const resp = await NfcManager.isoDepHandler.transceive(this.toByteArray(commands[i]))
          responses.push(resp)
      }

      if (responses && responses.length > 3) {
          const r = await this.getEmvInfo(this.toHexString(responses[3]))
          if (r) {
              const cardInfo = this.getCardInfoMasterCard(r)
              if (cardInfo) {
                  return {
                      card: cardInfo.card,
                      exp: cardInfo.exp
                  }
              } else {
                  return null
              }
          } else {
              return null
          }
      } else {
          return null
      }
    } catch (error) {
      return null
    } finally {
      NfcManager.cancelTechnologyRequest()
  }
}

getEmvInfo = (info) => {
    return new Promise((resolve) => {
      emv.describe(info, (data) => {
          if (data) {
              resolve(data)
          } else {
              resolve(null)
          }
      })
    })
}

toByteArray = (text) => {
  return text.match(/.{1,2}/g).map(b => {
      return parseInt(b, 16)
  })
}

toHexString = (byteArr) => {
    return byteArr.reduce((acc, byte) => {
      return (
          acc + ('00' + byte.toString(16).toUpperCase()).slice(-2)
      )
    }, '')
}

getCardInfoMasterCard = (responses) => {
    let res
    let end = false
    for (let i = 0; i < responses.length; i++) {
      const r = responses[i]
      if (r.tag === "70" && r.value && r.value.length > 0) {
          for (let j = 0; j < r.value.length; j++) {
              const e = r.value[j]
              if (e.tag === "5A" && e.value) {
                  if (!res) {
                      res = {
                          card: e.value
                      }
                  } else {
                      res.card = e.value
                  }

                  if (res.card && res.exp) {
                      end = true
                  }
              }

              if (e.tag === "5F24" && e.value) {
                  if (!res) {
                      res = {
                          exp: e.value
                      }
                  } else {
                      res.exp = e.value
                  }

                  if (res.card && res.exp) {
                      end = true
                  }
              }

              if (end) {
                  break
              }
          }

          if (end) {
              break
          }
      }
    }
    return res
}

Please i really need Mastercard Reading, there is no way to get the Mastercard values? I can read Visa , but no Mastercard.