Skip to main content

React Native Reference Guide

Importing DyScan

After getting the access token for Dyneti's NPM repo access, go to your RN project root directory and set it up with the following terminal commands.

If you are using ~/.zshrc:

echo "export DYSCAN_NPM_TOKEN=accessTokenHere" >> ~/.zshrc
source ~/.zshrc
echo "@dyneti:registry=https://registry.npmjs.org/" >> .npmrc
echo "//registry.npmjs.org/:_authToken=\${DYSCAN_NPM_TOKEN}" >> .npmrc

If you are using ~/.bash_profile:

echo "export DYSCAN_NPM_TOKEN=accessTokenHere" >> ~/.bash_profile
source ~/.bash_profile
echo "@dyneti:registry=https://registry.npmjs.org/" >> .npmrc
echo "//registry.npmjs.org/:_authToken=\${DYSCAN_NPM_TOKEN}" >> .npmrc

Verify if the terminal can see the value of DYSCAN_NPM_TOKEN

echo $DYSCAN_NPM_TOKEN

Install DyScan with the following terminal commands

npm install @dyneti/react-native-dyscan-fraud --save 
react-native link
react-native link @dyneti/react-native-dyscan-fraud

Linking for Android

In the android-directory-level build.gradle add the Dyneti Maven repository (credentials provided during integration):

allprojects {
repositories {
// Other repositories are here
maven {
credentials {
username = "nexusUsername"
password = "nexusPassword"
}
url "https://nexus.dyneti.com/repository/dyscan-fraud/"
authentication {
basic(BasicAuthentication)
}
}
}
}

Linking for iOS

Add the following line to the Podfile in the ios directory. Make sure you are using the latest (non-beta) version of Xcode.

warning

If you do not have a Podfile in your ios directory, you will need to generate one. Follow the instructions here to do so. Make sure to remove the use_frameworks! line in the generated Podfile. If the generated Podfile contains two targets for ProjectName-tvOSTests,you should remove the first target.

pod 'DyScan', :podspec => '../node_modules/@dyneti/react-native-dyscan-fraud/specs/DyScanFraud.podspec'
warning

If your linking does not work for some reason (most common if you've added React Native to a native project), you may have to add a pod for RNDyScan which points to the RNDyScan.podspec included in the npm package

In the ios directory, execute in terminal

pod install

When asked for a password for user "dyscan-fraud", paste the GitHub access token that we provided during integration.

danger

If you have not previously asked for camera permissions in the app, you will need to add the “NSCameraUsageDescription” (Privacy - Camera Usage Description) to your Info.plist file. To do this in Xcode, navigate to Info.plist. When you hover over any of the fields in the file, a small plus icon should show up next to the field. Click on the plus sign and type in “NSCameraUsageDescription” into the new field. You should set the value to be the string a user sees when they are prompted for the camera permission (e.g. To scan credit cards).

danger

If you are getting an error like "DyScanFraud/DyScanFraud.h not found," you will need to remove DyScanFraud as a library dependency. In the Xcode file tree, ctrl+click on RNDyScan.xcodeproj under Libraries to delete it. Xcode should prompt you to delete or remove the reference. Choose to remove the reference.

danger

If the app is compiling but you are getting an error when you try to initialize DyScan that says "undefined is not an object (evaluating 'RNDyScanModule.scanCard')," then you will need to add the DyScan iOS node module directory as a header search path. To do this, click on your project name next to a blue icon in the navigation bar on the top left of Xcode. In the middle of the screen, select "Build Settings" and search for "Header Search Paths" in the search bar. Add
$(SRCROOT)/../node_modules/@dyneti/react-native-dyscan-fraud-eu/ios

or

$(SRCROOT)/../node_modules/@dyneti/react-native-dyscan-fraud/ios to the search paths respectively.

danger

If you are getting an error like "dyld: Library not loaded: @rpath/libswift*.dylib," then you will need to force Xcode to embed Swift libraries. Do this by clicking on your project name next to a blue icon in the navigation bar on the top left of Xcode. Click on "Build Settings" and search for "Always Embed Swift Standard Libraries." Set the value of this field from "No" to "Yes" and the app should now run.

Interfacing DyScan

Initializing DyScan

In your App.js add the following line to configure DyScan.

import React from 'react';
import {DyScan} from '@dyneti/react-native-dyscan-fraud';

const App: () => React$Node = () => {

DyScan.init({
apiKey: 'YOUR_API_KEY',
});

// some code here
};

export default App;

DyScanModule

The DyScanModule abstracts the DyScanViewController on iOS and the DyScanActivity on Android. It will open a separate screen where the user will scan their card and return a JavaScript Promise.

import React, { Component } from 'react';
import { View, TouchableOpacity, Text, Platform } from 'react-native';
import { DyScanModule } from '@dyneti/react-native-dyscan-fraud';

export default class DyScanExample extends Component {

scanCard() {
DyScanModule
.scanCard({
showDynetiLogo: true
})
.then(card => {
// the scanned card
// Access the fields cardNumber, expiryMonth, expiryYear, timeStamp, isFraud or declineReasons
})
.catch(() => {
// the user cancelled
})
}

render() {
return (
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
<TouchableOpacity onPress={this.scanCard.bind(this)}>
<Text>Scan card!</Text>
</TouchableOpacity>
</View>
);
}
}
warning

If you have been migrating from native Android to using React Native (or otherwise created a custom Activity to contain your react screens), you must be sure that you are passing calls to onActivityResult on to the ReactInstanceManager; otherwise neither callback will be called. For more details on how to do this, see the React Native documentation.

DyScanView

This component allows the scanning view to be placed on a screen with other components. You must be sure that the view gets unmounted when it is no longer needed.

import React, { Component } from 'react';
import { View } from 'react-native';
import { DyScanView } from '@dyneti/react-native-dyscan-fraud';

export default class DyScanExample extends Component {

onCardScanned = (card) => {
// the scanned card (can be null)
// Access the fields cardNumber, expiryMonth, expiryYear, timeStamp, isFraud or declineReasons
}

render() {
return (
<View>
<DyScanView
onCardScanned={this.onCardScanned}
/>
</View>
);
}
}
warning

When you are using the View, we cannot determine for ourselves whether our View is still needed at any given point in time. You should ensure that the View gets unmounted when it is no longer needed since otherwise our code will continue to run in the background, wasting your users' resources. For example, with react-native-navigation, if in onCardScanned you immediately navigate to a results screen, the screen containing our view will be persisted on the stack and so will not be unmounted. In order to ensure it is unmounted, you should make a call to navigation.goBack() prior to making the call to navigation.navigate().

Customization

Both the module and the view support customization. For the module, you pass the parameters into the scanCard function along with the API key; for the view, you supply them as props on the view.

Supported by Module and View:

ParameterDescriptionType
showCornersWhether to show the scan area outline.boolean
cornerThicknessHow thick to make the lines outlining the scan area, indicating to the user where to place their credit card.number
cornerInactiveColorThe color to use in drawing the outline of the scan region when nothing of interest is detected.color*
cornerCompletedColorThe color to use in drawing the outline of the scan region when we have successfully scanned a card.color*
bgColorThe color to use to obscure everything outside the scan region in order to draw the user’s attention to the scan region.color*
bgOpacityThe opacity to use when obscuring everything outside the scan region, as an integer ranging from 0.0 (transparent) to 1.0 (opaque).number
lightTorchWhenDarkWhether the phone will turn on the flashlight if multiple frames have appeared to be too dark. If set to false, torch toggle button will appear.boolean
vibrateOnCompletionWhether the device will vibrate once it has successfully extracted the credit card data from the images provided by the camera.boolean
showDynetiLogoWhether to show the Dyneti logo above the scan regionboolean
showCardOverlayWhether to show the overlay displaying a sample card number and expiration date hinting at the user to place their card in the scan region.boolean
enableSidewaysScanningWhether to allow cards to scan in sideways orientation. If set to true, vertical cards will be able to be scanned when positioned in the horizontal scan window. Note that enableSidewaysScanning and showRotateButton should not simultaneously be set to true when using the module, and that isVertical should not be used when enableSidewaysScanning is set to true when using DyScan as a view.boolean
awaitScanStorageWhether to strictly wait for the scan data to be successfully uploaded to the backend before returning a scan resultboolean

DyScanModule

PropDescriptionType
showHelperTextWhether to show the helper text on screen.boolean
helperTextStringWhat to text to display to the user to guide them in scanning their card.string
helperTextColorThe color to use to display the helper text.color*
helperTextSizeThe font size of the helper text.number
helperTextFontFamilyThe font family name of the helper text. The font needs to be placed in assets first.string
showRotateButtonWhether to show the button which allows the user to rotate the scan region by 90 degrees, facilitating the scanning of vertical cards.boolean
iosHelperTextPositionThe preset position of the helper text. Available values: top, center, bottom. Default: bottomstring

DyScanView

PropDescriptionType
onCardScannedA callback for receiving results from the scanning process. card will be undefined on failure.(card: CreditCard) => void

Color Representation

Colors are inputted as hex-encoded strings representing the RGB values with a '#' at the front, the so-called 'HTML Color Codes.' For example, #ff0000 is red. The representation must be exactly 7 characters long; otherwise we will ignore it when trying to convert the strings to the native representations.

Card Object

The card scan result object contains the following fields:

FieldDescriptionValues
scanIdthe scan UUIDstring
payloadIda unique identifier for the payload. To be used with the Integrity Check API.string
cardNumberthe card number readstring
expiryMonththe expiration month of the cardif read, the expiration month, otherwise 0
expiryYearthe expiration year of the cardIf read, the expiration year, otherwise 0
isFraudindicates if the card is legitimate
  • true if card is fraudulent
  • false if card is legitimate
timestampindicates when the card was scannedan ISO8601 timestamp indicating when the scan occurred
declineReasonsdescribes the reasons why a card was flagged as fraudulent

  • empty when isFraudisfalse
  • populated when isFraudistrue

Potential reasons for decline include the following:

  • formatMismatch: a boolean that is true when the card assets do not match the card type as detected by the BIN (e.g., the card number or logo are not where we expect them to be).
  • numberMismatch: a boolean that is true when the BIN and last four digits of the scanned card do not match with what we expect. Note this reason is only available if you provide us with the expected BIN and last four.
  • generatedImage: a boolean that is true when the image is likely generated (e.g., the image is being scanned through a screen, or does not have corners or wear and tear).
  • rateLimited: a boolean that is true when an attacker has been attempting multiple scans in rapid succession using the same device.
  • tamperedFeatures: a boolean that is true when at least one of the other features has been tampered with

TypeScript

We also provide TypeScript bindings in our package. If you use TypeScript no additional steps will be required to start using the types we provide.