BlinkCard Module

You can add a card scanning solution to your application by adding VGSCollect/BlinkCard module. 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 BlinkCard SDK with VGS Collect iOS SDK.

Using BlinkCard in your app requires a valid license key. To get your license key you should contact MicroBlink.

You can start by watching our step-by-step tutorial, in which you’ll find out how to make BlinkCard SDK a part of your iOS app.

To see VGSCollect/BlinkCard in action, check our Demo app.

Pricing

VGSCollect/BlinkCard module is a paid integration. Please contact Microblink for more details.

Before you start

Using VGSCollect/BlinkCard API in your app you should obtain a valid license key. You can obtain it from Microblink dashboard.

Integration

The module can be deployed in iOS 13.0 or later.

Integrate with Swift Package Manager

To integrate VGSCollect/BlinkCard module via Swift Package Manager, in Xcode add the https://github.com/verygoodsecurity/vgs-collect-ios.git repo and choose the exact version.

Select both VGSCollectSDK and VGSBlinkCardCollector packages.

Follow the official Apple SPM guide instructions for more details.

Integrate with Cocoapods

Add BlinkCard module alongside with core VGSCollectSDK module into your App Podfile:

pod 'VGSCollectSDK'
pod 'VGSCollectSDK/BlinkCard'

Then in Terminal run:

pod install

UIKit integration

VGSBlinkCardController

An object you use to manage BlinkCard scan ViewController.

Declaration

class VGSBlinkCardController

Creating a VGSBlinkCardController

/// - Parameters:
///   - licenseKey: key required for BlinkCard SDK usage.
///   - delegate: `VGSBlinkCardControllerDelegate`. Default is `nil`.
///   - errorCallback: Error callback with Int error code(represents `MBCLicenseError` enum), triggers only when error occures.
public required init(licenseKey: String, delegate: VGSBlinkCardControllerDelegate? = nil, onError errorCallback: @escaping ((NSInteger) -> Void))

VGSBlinkCardController Attributes and Methods

/// `VGSBlinkCardControllerDelegate` - handle `BlinkCard` states.
public var delegate: VGSBlinkCardControllerDelegate?

/// Present `BlinkCard` scanner.
/// - Parameters:
///   - viewController: `UIViewController` that will present card scanner.
///   - animated: pass `true` to animate the presentation; otherwise, pass `false`.
///   - completion: the block to execute after the presentation finishes.
public func presentCardScanner(on viewController: UIViewController, animated: Bool, completion: (() -> Void)?)

/// Dismiss `BlinkCard` scanner.
/// - Parameters:
///   - animated: pass `true` to animate the dismiss of presented viewcontroller; otherwise, pass `false`.
///   - completion: the block to execute after the dismiss finishes.
public func dismissCardScanner(animated: Bool, completion: (() -> Void)?)

/// Set custom localization fileName.
public static func setCustomLocalization(fileName: String)

VGSBlinkCardControllerDelegate

Declaration

protocol VGSBlinkCardControllerDelegate

Managing Controller States

/// On user confirm scanned data by selecting Done button on `BlinkCard` screen.
@objc func userDidFinishScan()

/// On user press Cancel button on `BlinkCard` screen.
@objc func userDidCancelScan()

Providing VGSTextFields for setting Scanned Data

/// Asks `VGSTextField` where scanned data with `VGSConfiguration.FieldType` need to be set.
/// Called after user select Done button, just before userDidFinishScan() delegate.
@objc func textFieldForScannedData(type: VGSBlinkCardDataType) -> VGSTextField?

If scanned data is valid, it will be set in your VGSTextFields automatically after user confirmation.

VGSBlinkCardDataType

VGSBlinkCardDataType is an Enum of supported scan data types by BlinkCard module.

VGSBlinkCardDataType

Type, Value

.cardNumber

String, Digits string

.name

String, Cardholder name

.cvc

String, 3-4 digits

.expirationDate

String, "mm/yy" digits

.expirationDateLong

String, "mm/yyyy" digits

.expirationDateShortYearThenMonth

String, "yy/mm" digits

.expirationDateLongYearThenMonth

String, "yyyy/mm" digits

.expirationMonth

String, "mm" digits

.expirationYear

String, "yy" digits

.expirationYearLong

String, "yyyy" digits

Usage

Create UI Form with VGSTextfields, if not done yet. Inside your ViewController create and configure VGSBlinkCardController instance:

class ViewController: UIViewController {

    // VGSBlinkCardController instance
    var scanController: VGSBlinkCardController?

    // Scan card button
    var scanButton = UIButton()

    /// Initialize VGSCollect instance
    var vgsCollect = VGSCollect(id: "<VAULT_ID>", environment: .sandbox)

    /// VGS UI Elements
    var cardNumberField = VGSCardTextField()
    var cardHolderNameField = VGSTextField()
    var expCardDateField = VGSTextField()
    var cvcField = VGSTextField()


    override func viewDidLoad() {
       super.viewDidLoad()

       /// Init scan controller with license key.
       scanController = VGSBlinkCardController(licenseKey: <licenseKey>, delegate: self, onError: { errorCode in
          print("BlinkCard license error, code: \(errorCode)")
        })

       /// Add action to handle scan button touch
       scanButton.addTarget(self, action: #selector(scanData(_:)), for: .touchUpInside)

       /// Setup Fields Layout and Configuration
       ...
    }

     // Present scan ViewController
     @objc func scanData(_ sender: UIButton) {
         scanButton.presentCardScanner(on: self, animated: true, completion: nil)
     }
}

Implement VGSBlinkCardControllerDelegate methods. To setup scanned data into specific VGSTextFields implement textFieldForScannedData:. If scanned data is valid it will be set in your VGSTextFields automatically. Check VGSBlinkCardDataType to get available scanned data types.

extension CardsDataCollectingViewController: VGSBlinkCardControllerDelegate {
  func textFieldForScannedData(type: VGSBlinkCardDataType) -> VGSTextField? {
      // match VGSTextField with scanned data
      switch type {
      case .expirationDateLong:
          return expCardDate
      case .cardNumber:
          return cardNumber
      case .cvc:
        return cvcCardNum
      case .name:
        return cardHolderName
      default:
          return nil
      }
  }
  
  func userDidFinishScan() {
      scanController?.dismissCardScanner(animated: true, completion: {
          // add actions on scan controller dismiss completion
      })
  }
  
  func userDidCancelScan() {
      scanController?.dismissCardScanner(animated: true, completion: {
          // add actions on scan controller dismiss completion
      })
  }
}

SwiftUI integration

VGS Collect iOS SDK provide support for integration with apps that are buid with SwiftUI toolkit by providing SwiftUI wrappers. VGS Collect SwiftUI wrappers are designed to make integration easier and more straight forward by taking care of all needed state and editing events.

VGSBlinkCardControllerRepresentable

Declaration

struct VGSBlinkCardControllerRepresentable: UIViewControllerRepresentable

Creating a VGSBlinkCardControllerRepresentable

/// Initialization
/// - Parameters:
///   - licenseKey: key required for BlinkCard  SDK usage.
///   - dataCoordinators: `[VGSBlinkCardDataType: VGSCardScanCoordinator]` represents connection between scanned data and VGSTextFields.
///   - errorCallback: Error callback with Int error code(represents `MBCLicenseError` enum), triggered only when error occured.
public init(licenseKey: String, dataCoordinators: [VGSBlinkCardDataType: VGSCardScanCoordinator], errorCallback: @escaping ((NSInteger) -> Void))

Instance Methods

VGSBlinkCardControllerRepresentable is a SwiftUI wrapper around BlinkCard card scanner controller and have similar attributes and functionality represented in SwiftUI way.

VGSBlinkCardControllerRepresentable card recognition modifier

You can find available attributes and their description in BlinkCard documentation.

  /// Should extract the card owner information.
  public var extractOwner: Bool = true
  /// Should extract the payment card’s month of expiry.
  public var extractExpiryDate: Bool = true
  /// Should extract CVV.
  public var extractCvv: Bool = true
  /// Should extract the payment card’s IBAN.
  public var extractIban: Bool = true
  /// Whether invalid card number is accepted.
  public var allowInvalidCardNumber: Bool = false

VGSBlinkCardControllerRepresentable Event modifier

/// On Scaner finish card recognition.
public var onCardScanned: (() -> Void)?
/// On card scanning canceled  by user.
public var onCardScanCanceled: (() -> Void)?

Code examples

Create UI Form with VGSTextfieldRepresentable, if not done yet. Inside your View create and configure VGSBlinkCardControllerRepresentable instance:

struct CardDataCollectionSwiftUI: View {
    /// Track BlinkCard visibility status
    @State private var showingBlinkCardScanner = false
    /// Match scanned data with apropriate text fields.
    @State private var scanedDataCoordinators: [VGSBlinkCardDataType: VGSCardScanCoordinator] = [
            .cardNumber: VGSCardScanCoordinator(),
            .name: VGSCardScanCoordinator(),
            .cvc: VGSCardScanCoordinator(),
            .expirationDate: VGSCardScanCoordinator()
        ]
         
    // MARK: - Build View
    var body: some View {
        /// setup VGSConfiguration for fields 
        /// ...
      return VStack(spacing: 8) {
        VGSTextFieldRepresentable(configuration: holderNameConfiguration)
          .placeholder("Cardholder Name")
          .cardScanCoordinator(scanedDataCoordinators[.name]!)
        VGSCardTextFieldRepresentable(configuration: cardNumConfiguration)
          .placeholder("4111 1111 1111 1111")
          .cardScanCoordinator(scanedDataCoordinators[.cardNumber]!)
        HStack(spacing: 20) {
          VGSExpDateTextFieldRepresentable(configuration: expDateConfiguration)
            .placeholder("MM/YY")
            .cardScanCoordinator(scanedDataCoordinators[.expirationDate]!)
          VGSCVCTextFieldRepresentable(configuration: cvcConfiguration)
            .placeholder("CVC")
            .cardScanCoordinator(scanedDataCoordinators[.cvc]!)
            .setSecureTextEntry(true)
        }
        HStack(spacing: 20) {
          Button(action: {
            showingBlinkCardScanner = true
          }) {
              Text("SCAN")
                  .padding()
                  .cornerRadius(8)
                  .overlay(
                      RoundedRectangle(cornerRadius: 10)
                          .stroke(Color.blue, lineWidth: 2)
                  )
          }
          .fullScreenCover(isPresented: $showingBlinkCardScanner) {
            VGSBlinkCardControllerRepresentable(licenseKey: AppCollectorConfiguration.shared.blinkCardLicenseKey!, dataCoordinators: scanedDataCoordinators) { (errorCode) in
              print(errorCode)
            }.allowInvalidCardNumber(true)
            .onCardScanned({
              showingBlinkCardScanner = false
            })
            .onCardScanCanceled({
              showingBlinkCardScanner = false
            })
          }
        }
      }
    }
}

Last updated