Skip to main content
Version: Next

Migrating to v3000

This guide describes how to upgrade to BlinkCard v3000.

For specific platforms (web, iOS, Android...), additional details may be available in their own API references.

note

BlinkCard v3000 brings new capabilities, other than those listed in this migration guide. The migration guide is focused on getting you to successfully migrate to the new version, and so it doesn't talk about the new features. Read the release notes for your SDK platform to find out more about what else is new.

Versioning change

Starting with v3000, BlinkCard will adopt the epoch versioning scheme.

{EPOCH * 1000 + MAJOR}.MINOR.PATCH

EPOCH: Increment when you make significant or groundbreaking changes.

MAJOR: Increment when you make minor incompatible API changes.

MINOR: Increment when you add functionality in a backwards-compatible manner.

PATCH: Increment when you make backwards-compatible bug fixes.

So, instead of going from v2.x.x to v3.x.x, BlinkCard will go from v2.x.x to v3000.x.x.

Subsequent versions will follow the same scheme.

Architecture changes

BlinkCard v3000, similarly to BlinkID v7 and above, will adopt a session-based architecture.

This means that you no longer need to configure and string together individual recognizers.

Instead, the whole concept of a recognizer is replaced by the concept of a session.

v2 (Recognizer-based):

import { createBlinkCardRecognizer } from "@microblink/blinkcard-in-browser-sdk";

const recognizer = await createBlinkCardRecognizer(wasmSDK);
await recognizer.updateSettings({
extractOwner: false,
returnFullDocumentImage: true
});
const result = await recognizer.getResult();

v3000 (Session-based):

import { createBlinkCard } from "@microblink/blinkcard";

// Complete solution with UI components
const blinkCard = await createBlinkCard({
licenseKey: "your-license-key",
scanningSettings: {
extractionSettings: { extractCardholderName: false },
croppedImageSettings: { returnCardImage: true }
}
});

License considerations

Old v2 licenses are compatible with v3000. You don't need to issue new licenses.

Installation and dependencies

v2:

npm install @microblink/blinkcard-in-browser-sdk

v3000:

npm install @microblink/blinkcard

The @microblink/blinkcard package (v3000.0.0) is the main user-facing package that provides a complete solution for card scanning in web applications. It combines core scanning functionality, camera management, and UI components.

For advanced usage scenarios where you need more control over individual components, you can also use the constituent packages directly:

  • @microblink/blinkcard-core: core scanning functionality and WASM management
  • @microblink/blinkcard-ux-manager: UI feedback and user experience management
  • @microblink/camera-manager: camera management (shared library)

Import statement changes

v2:

import { createBlinkCardRecognizer } from "@microblink/blinkcard-in-browser-sdk";

v3000:

// Main package (recommended for most use cases)
import { createBlinkCard } from "@microblink/blinkcard";

// Or for advanced usage with more control
import { loadBlinkCardCore } from "@microblink/blinkcard-core";

Changes in scanning settings

Changes in structure

The settings body used to be a flat object, with all items in the root level.

The settings structure is now hierarchical, with sub-structures that group related items:

type SessionSettings = {
resourcesPath: string;
inputImageSource: "photo" | "video";
scanningSettings: {
skipImagesWithBlur: boolean;
tiltDetectionLevel: DetectionLevel;
inputImageMargin: number;
extractionSettings: ExtractionSettings;
croppedImageSettings: CroppedImageSettings;
livenessSettings: LivenessSettings;
anonymizationSettings: AnonymizationSettings;
};
};

Renamed settings

v2v3000Notes
extractOwnerextractCardholderNameMoved to extractionSettings
allowBlurFilterskipImagesWithBlurLogic inverted: true now means skip blurred frames
paddingEdgeinputImageMarginSame meaning, default changed from 0.0 to 0.02
allowInvalidCardNumberextractInvalidCardNumberMoved to extractionSettings
handScaleThresholdhandToCardSizeRatioMoved to livenessSettings
handDocumentOverlapThresholdhandCardOverlapThresholdMoved to livenessSettings
photocopyAnalysisMatchLevelphotocopyCheckStrictnessLevelMoved to livenessSettings
screenAnalysisMatchLevelscreenCheckStrictnessLevelMoved to livenessSettings
returnFullDocumentImagereturnCardImageMoved to croppedImageSettings
ownerAnonymizationModecardholderNameAnonymizationModeMoved to anonymizationSettings
v2v3000
fullDocumentImageDpicroppedImageSettings.dotsPerInch
fullDocumentImageExtensionFactorscroppedImageSettings.extensionFactor

Removed settings

  • Setting JPEG encoding is no longer a separate option:
    • Web: removed returnEncodedFullDocumentImage
    • Android, iOS: removed encodeFullDocumentImage
  • Liveness status no longer in settings:
    • Web: removed documentLivenessCallback
    • Android: removed setLivenessStatusCallback()
    • iOS: removed livenessStatusCallback (the delegate method)

Added settings

SettingLocationDescription
enableCardHeldInHandChecklivenessSettingsEnables/disables the hand presence check

Nested settings details

In v3000, settings are organized into logical groups. Here's what each group contains:

ExtractionSettings

Controls which fields should be extracted from the card:

FieldTypeDefaultDescription
extractIbanbooleantrueExtract IBAN number
extractExpiryDatebooleantrueExtract card expiry date
extractCardholderNamebooleantrueExtract cardholder name
extractCvvbooleantrueExtract CVV security code
extractInvalidCardNumberbooleanfalseAccept card numbers that fail Luhn checksum validation

CroppedImageSettings

Controls image cropping and return options:

FieldTypeDefaultDescription
dotsPerInchnumber250DPI value for cropped images
extensionFactornumber0.0Extension factor for cropped card image
returnCardImagebooleanfalseWhether to return the cropped card image

LivenessSettings

Controls liveness detection parameters:

FieldTypeDefaultDescription
handToCardSizeRationumber0.15Minimum hand-to-card size ratio for valid hand detection
handCardOverlapThresholdnumber0.05Minimum overlap threshold between hand and card
enableCardHeldInHandCheckbooleantrueEnable/disable hand presence check
screenCheckStrictnessLevelStrictnessLevelLevel5Sensitivity for screen detection
photocopyCheckStrictnessLevelStrictnessLevelLevel5Sensitivity for photocopy detection

AnonymizationSettings

Controls data anonymization:

FieldTypeDefaultDescription
cardNumberAnonymizationSettingsobjectSee belowCard number anonymization configuration
cardNumberPrefixAnonymizationModeAnonymizationModeNoneCard number prefix anonymization
cvvAnonymizationModeAnonymizationModeNoneCVV anonymization
ibanAnonymizationModeAnonymizationModeNoneIBAN anonymization
cardholderNameAnonymizationModeAnonymizationModeNoneCardholder name anonymization

CardNumberAnonymizationSettings:

FieldTypeDefaultDescription
modeAnonymizationModeNoneAnonymization mode
prefixDigitsVisiblenumber0Number of prefix digits to keep visible
suffixDigitsVisiblenumber0Number of suffix digits to keep visible

AnonymizationMode values:

iOS, AndroidWebDescription
NonenoneNo anonymization
ImageOnlyimage-onlyAnonymize in images only
ResultFieldsOnlyresult-fields-onlyAnonymize in result fields only
FullResultfull-resultAnonymize in both images and result fields

StrictnessLevel changes

The MatchLevel enum has been renamed to StrictnessLevel:

// v2
enum MatchLevel {
Disabled = 0,
Level1 = 1,
Level2 = 2,
Level3 = 3,
Level4 = 4,
Level5 = 5,
Level6 = 6,
Level7 = 7,
Level8 = 8,
Level9 = 9,
Level10 = 10
}

// v3000
type StrictnessLevel =
| "disabled"
| "level-1"
| "level-2"
| "level-3"
| "level-4"
| "level-5"
| "level-6"
| "level-7"
| "level-8"
| "level-9"
| "level-10";

Key changes:

  • Changed from enum to type union of string literals
  • Values changed from PascalCase (Level1) to kebab-case ("level-1")
  • Disabled renamed to "disabled" (lowercase)

Changes in the result object

Structural changes

The result structure in v3000 is organized differently:

  1. Per-side results: Card data and images are now organized by side (firstSideResult, secondSideResult)
  2. Card accounts array: The cardAccounts field now supports multiple payment accounts on a single card
  3. Liveness results: Liveness checks are now per-side and include a new overall result

v2 structure:

{
cardNumber: "1234567890123456",
cvv: "123",
expiryDate: { /* ... */ },
owner: "John Doe",
issuer: CardIssuer.Visa,
processingStatus: ProcessingStatus.Success,

firstSideFullDocumentImage: { /* ... */ },
firstSideBlurred: false,

documentLivenessCheck: {
front: {
screenCheck: { result: CheckResult.Pass, matchLevel: MatchLevel.Level5 },
photocopyCheck: { result: CheckResult.Pass, matchLevel: MatchLevel.Level5 },
handPresenceCheck: CheckResult.Pass
},
back: { /* ... */ }
}
// ... other fields
}

v3000 structure:

{
issuingNetwork: "Visa", // String (was enum)
cardholderName: "John Doe",

// Card account fields now in array (cardNumber, cvv, expiryDate moved here)
cardAccounts: [
{
cardNumber: "1234567890123456",
cvv: "123",
expiryDate: { /* ... */ },
// ...
}
],
overallCardLivenessResult: "pass", // New field

firstSideResult: {
cardImage: { image: { /* ... */ } },
cardLivenessCheckResult: {
screenCheckResult: "pass", // Simplified (no matchLevel)
photocopyCheckResult: "pass",
cardHeldInHandCheckResult: "pass"
}
},
secondSideResult: { /* ... */ }
// ... other fields
}

Moved fields

Fields that haven't been renamed, but just moved, now live in the objects inside the cardAccounts array. These are:

  • cardNumber
  • cardNumberPrefix
  • cardNumberValid
  • cvv
  • expiryDate

Renamed (and moved) fields

  • owner -> cardholderName
  • issuer -> issuingNetwork
    • Changed from enum to string
  • firstSideFullDocumentImage -> firstSideResult.cardImage
    • Now nested in side result
  • secondSideFullDocumentImage -> secondSideResult.cardImage
    • Now nested in side result
  • firstSideBlurred -> inputImageAnalysisResult.blurDetectionStatus
    • Now in ProcessResult
  • secondSideBlurred -> inputImageAnalysisResult.blurDetectionStatus
    • Now in ProcessResult
  • documentLivenessCheck -> cardLivenessCheckResult
    • Split per-side
  • documentLivenessCheck.front.screenCheck.result -> firstSideResult.cardLivenessCheckResult.screenCheckResult
    • Simplified (no matchLevel)
  • documentLivenessCheck.front.photocopyCheck.result -> firstSideResult.cardLivenessCheckResult.photocopyCheckResult
    • Simplified (no matchLevel)
  • documentLivenessCheck.front.handPresenceCheck -> firstSideResult.cardLivenessCheckResult.cardHeldInHandCheckResult

Removed fields

  • Encoded image has been removed from the result:
    • Web:
      • firstSideFullDocumentImage.encodedImage
      • secondSideFullDocumentImage.encodedImage
    • iOS, Android:
      • encodedFirstSideFullDocumentImage
      • encodedSecondSideFullDocumentImage
  • scanningFirstSideDone
  • firstSideAnonymized
  • secondSideAnonymized
  • processingStatus
  • Match levels no longer exposed in results:
    • Web, Android:
      • documentLivenessCheck.front.screenCheck.matchLevel
      • documentLivenessCheck.front.photocopyCheck.matchLevel
    • iOS:
      • documentLivenessCheck.front.screenCheck.level
      • documentLivenessCheck.front.photocopyCheck.level

New fields

FieldDescription
overallCardLivenessResultAggregated liveness check across all sides. Possible values: "not-available", "pass", "fail"
cardHeldInHandCheckResultResult of the hand presence check (per-side). Possible values: "not-available", "pass", "fail"
cardAccountsSupports multiple payment accounts on a card
cardAccounts[].fundingTypeOptional: Card funding type (e.g., "DEBIT", "CREDIT", "CHARGE CARD")
cardAccounts[].cardCategoryOptional: Card category (e.g., "PERSONAL", "BUSINESS", "PREPAID")
cardAccounts[].issuerNameOptional: Name of the issuing financial institution
cardAccounts[].issuerCountryCodeOptional: ISO 3166-1 alpha-3 country code (e.g., "USA", "GBR", "HRV")
cardAccounts[].issuerCountryOptional: Name of the issuer's country

CardAccountResult structure

The cardAccounts field is now an array that can contain multiple payment accounts. Each CardAccountResult contains:

{
cardNumber: string;
cardNumberValid: boolean;
cardNumberPrefix: string | undefined;
cvv: string | undefined;
expiryDate: DateResult;
fundingType: string | undefined; // New in v3000
cardCategory: string | undefined; // New in v3000
issuerName: string | undefined; // New in v3000
issuerCountryCode: string | undefined; // New in v3000
issuerCountry: string | undefined; // New in v3000
}

Processing status changes

Processing status and other frame-level information is now available in the ProcessResult object returned during scanning. This provides real-time feedback about the scanning process on a per-frame basis.

Example of what you'll see when logging the ProcessResult:

{
inputImageAnalysisResult: {
processingStatus: "success", // or "detection-failed", "image-preprocessing-failed", etc.
scanningSide: "first", // or "second"
detectionStatus: "success", // or "failed", "camera-too-far", "camera-too-close", etc.
cardLocation: {
upperLeft: 123,
upperRight: 456,
lowerRight: 789,
lowerLeft: 012
},
blurDetectionStatus: "not-detected", // or "detected", "not-available"
cardRotation: "zero" // or "clockwise-90", "counter-clockwise-90", "upside-down", "not-available"
},
resultCompleteness: {
scanningStatus: "scanning-side-in-progress", // or "side-scanned", "card-scanned"
cardNumberExtractionStatus: "extracted", // or "not-available", "not-requested", "not-present", "not-extracted"
cardNumberPrefixExtractionStatus: "extracted",
expiryDateExtractionStatus: "not-present",
cardholderNameExtractionStatus: "extracted",
cvvExtractionStatus: "not-requested",
ibanExtractionStatus: "not-present",
cardImageExtractionStatus: "extracted"
}
}

Key differences from v2:

  • processingStatus moved from the final result to per-frame ProcessResult
  • New resultCompleteness provides detailed extraction status for each field
  • scanningStatus indicates overall progress (scanning-side-in-progress, side-scanned, card-scanned)
  • Blur detection status is now in inputImageAnalysisResult.blurDetectionStatus

Resource management

BlinkCard v3000 requires recognition resources (models and configuration files) to perform card scanning. The SDK supports different approaches for managing these resources depending on the platform.

Web

Resources are loaded from a specified path (typically hosted on your server or CDN):

const blinkCard = await createBlinkCard({
licenseKey: "your-license-key",
resourcesLocation: "https://example.com", // URL for WASM and model files; we append "/resources" to this value
// ... other settings
});

Best practices:

  • Host resources on the same domain to avoid CORS issues
  • Use a CDN for better performance and caching
  • Ensure resources are served with appropriate cache headers

iOS

BlinkCard SDK supports both downloaded and bundled resources:

let settings = BlinkCardSdkSettings(
licenseKey: "your-license-key",
downloadResources: true, // true = download, false = use bundled
resourceLocalFolder: "BlinkCard" // Optional custom storage location
)

Downloaded resources:

  • Smaller app bundle size
  • Resources downloaded on first use
  • Requires network connection on first launch

Bundled resources:

  • Larger app bundle size
  • No network required
  • Immediate availability

Android

Similar to iOS, Android supports both downloaded and bundled resources:

val settings = BlinkCardSdkSettings(
licenseKey = "your-license-key",
downloadResources = true, // true = download, false = use bundled
resourceLocalFolder = "BlinkCard" // Optional custom storage location
)

V2 maintenance

With the v3000 release, v2 goes into maintenance mode.

This means that v2 will stop receiving feature updates, but in case of security issues, it will be patched.

For product improvements, better scanning performance, etc., please use v3000.