CardScan (Bouncer SDK) module
You can add a card scanning solution to your application by adding CardScan adapter. It provides a fast and easy way to scan payment cards and import them to VGS Collect. This tutorial is aimed to help you to adapt Bouncer SDK with VGS Collect Android SDK.
Pricing
VGS Collect CardScan module is a paid integration with Bouncer. VGS customers pay Bouncer for the functionality and receive a 20% discount off of Bouncer's normal pricing: $0.12 per card scan. For VGS customers expecting to scan >40,000 cards per month, customers can contact Bouncer directly for an attractive best-available custom plan supported by the VGS-Bouncer partnership.
Bouncer SDK Attributes
Bouncer SDK adapter supports few types of scan data:
Attribute | Description |
---|---|
CARD_NUMBER | Payment card number. |
CARD_EXP_DATE | Expiration date. |
CARD_CVC | Card verification code. |
CARD_HOLDER | Cardholder name. |
Additionally you can use attributes mentioned below:
Attribute | Description |
---|---|
API_KEY | Api key. It needs for initialization Bouncer SDK. |
ENABLE_EXPIRY_EXTRACTION | Boolean extra. If true, attempt to extract the card expiry date. |
ENABLE_NAME_EXTRACTION | Boolean extra. If true, attempt to extract the cardholder name. |
DISPLAY_CARD_PAN | Boolean extra. If true, display the card pan once the card has started to scan. |
DISPLAY_CARD_HOLDER_NAME | Boolean extra. If true, display the name of the card owner if extracted. |
DISPLAY_CARD_SCAN_LOGO | Boolean extra. If true, display the cardscan.io logo at the top of the screen. |
ENABLE_DEBUG | Boolean extra. If true, enable debug views in card scan. |
Before you start
You should obtain API Key for CardScan commercial usage, generating it on the Bouncer admin console.
Integration
To use the scanner in your project you just need to add the following line of dependency in your app gradle file.
dependencies {
implementation 'com.verygoodsecurity:vgscollect:<latest-version>'
implementation 'com.verygoodsecurity:adapter-bouncer-cardscan:<latest-version>'
}
--cacert [FILE]
.Configure Your App
First of all, don't forget to add Button to R.layout.activity_main
layout file:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical" android:padding="16dp"> <com.verygoodsecurity.vgscollect.widget.VGSTextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:hintEnabled="true" app:hint="Card number" app:boxCornerRadius="4dp" app:boxBackgroundModes="outline" app:boxStrokeColor="#2f426f"> <com.verygoodsecurity.vgscollect.widget.VGSCardNumberEditText android:id="@+id/cardNumberField" android:layout_width="match_parent" android:layout_height="wrap_content" app:fieldName="cardNumber" app:numberDivider="-" app:cardBrandIconGravity="end"/> </com.verygoodsecurity.vgscollect.widget.VGSTextInputLayout> <Button android:id="@+id/scanBtn" android:text="Scan" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
This is a sample VGS echo server.This is a HTTP port number to access.This is alias which you receive on redact step from your payload value. Please observe the code snippet of redact step.More about the aliases available formats you can read at nomenclature page.This is alias which you receive on redact step from your payload value. Please have a look on code snippet of redact step.More about the available formats of alias you can read here.This is a sample vault id.This is a vault id.This is your vault id.This is a vault environment.These are an access credentials for a sample test vault.This is a placeholder for your access credentials.This is a sample proxy vault url.This is your vault url.This is your proxy vault url.This is a sample vault host.This is your vault host.This is your current Organization ID.A pre-generated JS script placeholder for your current organization.Sign in to see your personalized example.A pre-generated JS script placeholder for your current organization.Please talk to support in order to enable it for this organization.This is your pre-generated JS script for your current organization.The unique name that identifies a specific iframe.Unique client ID used for VGS CLI authentication.Please contact VGS Support in order to enable it for your organization.Client secret used for VGS CLI authentication.Please contact VGS Support in order to enable it for your organization.Version of the CLI published on quay.io.Command on the VGS CLI.This is a full path to the certificate file.This option allows curl to proceed without providing a TLS certificate. If you'd like to include your certificate, use--cacert [FILE]
.
Then, attach it to VGSCollect
, otherwise VGSCollect doesn't know how to send data to the input field.
import com.verygoodsecurity.vgscollect.core.Environment
import com.verygoodsecurity.vgscollect.core.VGSCollect
import com.verygoodsecurity.vgscollect.widget.VGSCardNumberEditText
class MainActivity : AppCompatActivity() {
private lateinit var vgsForm:VGSCollect
private lateinit var cardNumberField: VGSCardNumberEditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
vgsForm = VGSCollect(this, "<VAULT_ID>", Environment.<SANDBOX>)
cardNumberField = findViewById<VGSCardNumberEditText>(R.id.cardNumberField)
vgsForm.bindView(cardNumberField)
val scanBtn = findViewById<Button>(R.id.scanBtn)
scanBtn?.setOnClickListener { }
}
override fun onDestroy() {
vgsForm.onDestroy()
super.onDestroy()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
}
}
--cacert [FILE]
.VGS Collect would automatically import received data into your input fields. For this you need to link fields with incoming data. Please, use the field name to notify VGSCollect which type of incoming data he should apply on it.
At the current moment available CARD_NUMBER
, CARD_CVC
, CARD_HOLDER
, CARD_EXP_DATE
types.
All of them supported by the last version of Bouncer SDK.
val scanSettings = hashMapOf<String?, Int>().apply {
val numberKey = cardNumberField?.getFieldName()
this[numberKey] = ScanActivity.CARD_NUMBER
}
--cacert [FILE]
.To start scanning, you need to create a ScanActivity intent and get the results via the onActivityResult
method.
import com.verygoodsecurity.vgscollect.core.Environment
import com.verygoodsecurity.vgscollect.core.VGSCollect
import com.verygoodsecurity.api.bouncer.ScanActivity
import com.verygoodsecurity.vgscollect.widget.VGSCardNumberEditText
class MainActivity : AppCompatActivity() {
companion object {
const val USER_SCAN_REQUEST_CODE = 0x7
}
private lateinit var vgsForm:VGSCollect
private lateinit var cardNumberField: VGSCardNumberEditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
vgsForm = VGSCollect(this, "<VAULT_ID>", Environment.<SANDBOX>)
cardNumberField = findViewById<VGSCardNumberEditText>(R.id.cardNumberField)
vgsForm.bindView(cardNumberField)
val scanBtn = findViewById<Button>(R.id.scanBtn)
scanBtn?.setOnClickListener {
scanData()
}
}
override fun onDestroy() {
vgsForm.onDestroy()
super.onDestroy()
}
private fun scanData() {
val scanSettings = hashMapOf<String?, Int>().apply {
val numberKey = cardNumberField?.getFieldName()
this[numberKey] = ScanActivity.CARD_NUMBER
}
val intent = Intent(this, ScanActivity::class.java)
intent.putExtra(ScanActivity.SCAN_CONFIGURATION, scanSettings)
intent.putExtra(ScanActivity.API_KEY, "<bouncer-api-key>")
startActivityForResult(intent, USER_SCAN_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
vgsForm.onActivityResult(requestCode, resultCode, data)
}
}
--cacert [FILE]
.