GUIDE : Get Card’s PAN/CVV


Requirement

Android version must be 6.0 (API level 23) or above.

How it works :

As PAN and CVV are very sensitive data LinkCy solution uses the MeaWallet secure tool to deliver these datas. MeaWallet is a third party tool. Do not contact them directly for support

By using our endpoint Get Pan credentials /api/partner/cards/[cardId]/pan/credentials

We will provide you a token and a secret to able you to use the MeaWallet SDK which will return you the desire PAN/CVV.

For the next step note that what we named token correspond to the cardId field of the MeaWallet SDK, we renamed it to avoid confusion with our cardId field.
Mobile AppLinkcy ApiMeaWallet SDKGet MeaWallet credentials : GET `/api/partner/cards/{cardId}/pan/credentials`{token: string, secret: string}Get Card PAN/CVV : MeaCardData.getCardData(cardId = token, secret = secret){pan: string, cvv: string}Mobile AppLinkcy ApiMeaWallet SDK

Unfortunately, the full integration is not completed in sandbox, and the SDK will return an error with Sandbox data.

How to install the MeaWallet SDK :

iOS :

1) Get your MeaWallet SDK

iOS SDK will be send to you by LinkCy (mcd-prod-x.y.z.zip)

Once downloaded, you can ignore the iphoneos/ andiphonesimulator/ folders, these are physical device OR simulator only SDKs. Instead just use the MeaCardData.xcframework/ which is at the root of the .zip downloaded file, it works fine for both physical and emulator devices.

2) Link it to your xCode project :

  • Open xcode and slide the MeaCardData.xcframework where it please you in your .xcworkspace and target your project. Be careful, this will link the framework to your xcode project but only as a relative path, so you also have to put the MeaCardData.xcframework in your project to share it with your team.
  • If not automatically added, add MeaCardData.xcframework to Frameworks, Libraries and Embedded Content section of General settings in iOS project target.
  • Set it to Embed & Sign :

    ScreenShotEmbedAndSign

3) Add mea_config file :

send to you with the SDK

Add mea_config to iOS App Resources folder and App Target. File must be included in the final app bundle. Framework automatically loads configuration from app bundle during runtime. Framework raises an exception if configuration file is missing, broken or otherwise fails to load.

Android :

1) Put the MeaWallet SDK in dependencies :

MCD SDK should be added to the project as a standard Android dependency. SDK is hosted in a private Maven repository, so you need to configure build.gradle by setting the assigned URL and credentials.build.gradle :
Copy
Copied
repositories {
	maven {
		url 'https://nexus.ext.meawallet.com/repository/mcd-android-group/'

		credentials {
			username '<user>'
			password '<password>'
		}
	}
}

dependencies {
	debugImplementation 'com.meawallet:mcd-prod:1.2.0-debug'
	releaseImplementation 'com.meawallet:mcd-prod:1.2.0'
}

Update the version above according to the available SDK version

2) Add the mea_config file :

send to you by email

Add mea_config to Android App resources res/raw folder. Library automatically loads configuration from app bundle during runtime, and throws an exception if configuration file is missing, broken or otherwise fails to load.

3) App Manifest

It is not necessary to specify any permissions for SDK in AndroidManifest.xml file. A special marker tools:overrideLibrary can be used with uses-sdk declaration to override importing a library with minimum SDK version above application's minimum SDK version. Without such a marker manifest merger fails with an error. The marker allow users to select which libraries can be imported ignoring the minimum SDK version.

MCD SDK is using the following permissions that are merged with the app manifest file:

Copy
Copied
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>

How to use it :

iOS :

In Swift

Copy
Copied
import  MeaCardData

...

let cardId:  String  =  "<value"
let secret:  String  =  "<value>"

MeaCardData.getCardData(cardId, secret: secret)  {  (cardData, error)  in

    if  (error !=  nil)  {
        print(String(format:  "Card data request failed: %@", error!.localizedDescription))
    }
    else  {
        let pan = cardData!.pan
        let cvv = cardData!.cvv

        print(String(format:  "Card data fetched successfully, pan: %@, cvv: %@", pan, cvv))
    }
}

Or in Objective-C

Copy
Copied
#import <MeaCardData/MeaCardData.h>

...

NSString *cardId = @"<value>";
NSString *secret = @"<value>";

[MeaCardData getCardData:cardId secret:secret completionHandler:^(McdCardData *_Nullable cardData, NSError *_Nullable error) {
    if (error) {
        NSLog(@"Card data request failed: %@", [error localizedDescription]);
    }
    else {
        NSString *pan = cardData.pan;
        NSString *cvv = cardData.cvv;
        NSLog(@"Card data fetched successfully, pan: %@, cvv: %@", pan, cvv);
    }
}];

Android :

Initialize

To begin issuer app should initialize MeaCardData instance.

Copy
Copied
if (!MeaCardData.isInitialized()) {
    MeaCardData.initialize(this);
}

Then you can use the getCardData method like this

Copy
Copied
MeaCardData.getCardData(cardId, secret, new McdGetCardDataListener() {
    @Override
    public void onSuccess(@NonNull McdCardData mcdCardData) {
        String cardPan = mcdCardData.getPan();
        String cardCvv = mcdCardData.getCvv();
        // Use retrieved data.
    }

    @Override
    public void onFailure(@NonNull McdError mcdError) {
        int errorCode = mcdError.getCode();
        String errorMessage = mcdError.getMessage();
        // Handle error.
    }
});

There is another example in kotlin using the sdk with callbacks (optional) :

Copy
Copied
class MeaWalletModule() {

  init {
    if (!MeaCardData.isInitialized()) {
      MeaCardData.initialize(this);
    }
  }

  fun getCardData(cardId: String, secret: String, responseCallback: Callback, errorCallback: Callback) {

    MeaCardData.getCardData(cardId, secret, object:McdGetCardDataListener {
      override fun onSuccess(cardData: McdCardData) {
        responseCallback.invoke(cardData.pan, cardData.cvv)
      }
      override fun onFailure(error: McdError) {
        errorCallback.invoke(error.name)
      }
    })
  }
}