Skip to main content

Tokenize an existing card

In specific scenarios you might want to create Own App Tokens linked to an existing card. In such cases, our platform offers two distinct ways to facilitate this process:

  • You can send the card details via API
  • Your customers can manually input their card details in our SDK
warning

In both scenarios it is possible to tokenize a card linked to a BIN which is not managed by Open Fabric. If you allow for this to happen, the payments processed on those tokens will not be reflected in Open Fabric's system.

Send card details via API

To start the process of tokenizing an existing card into an Own App Token, please make sure you have created a secure device wallet as explained here

Once the device is ready with a secure device wallet provisioned, it’s time to tokenize a card into the secure device wallet. You can provide card data to Open Fabric for tokenization, which will allow for push provisioning of the token into the secure device wallet

info

For security reasons, it is essential to make the API call from the backend.

Use the Push provision API, with the following parameters:

  • digital_wallet set to issuer
  • wallet_id with the secure device wallet indicator
  • encrypted_card_data with the encrypted card data JSON with Open Fabric’s shared public key, Base64-encoded
  • issuer_card_id with the issuer card ID, retrieved from your CMS
  • tenant_customer_ref with a reference to the customer from your system

The API will respond back to you with a provisioning_data.opc which then needs to be handed back to the SDK for the next step.

Sample request

Headers:
Idempotency-Key: 40709949-0712-487c-a2fe-1dd2e64af506
{
"tsp": "mdes",
"digital_wallet": "issuer",
"tenant_customer_ref": "of_customer_1",
"issuer_card_id": "507e8c90-3cfc-44ee-b701-0630067eb44fa5e9351a-0a6",
"issuer_authentication_data": "eyJ4NWMiOlsiTUlJQzNqQ0NBY2FnQXdJQkFnSUpBT1FDdnc2Tjh...",
"encrypted_card_data": "eyJ4NWMiOlsiTUlJQzNqQ0NBY2FnQXdJQkFnSUpBT1FDdnc2Tjh...",
"wallet_id": "507e8c90-3cfc-44ee-b701-0630067eb44fa5e9351a-0a6",
"billing_address": {
"address_line_1": "Singapore",
"post_code": "000001"
}
}
Unencrypted card data JSON
{
"card_number": "5...123",
"expiry_month": "12",
"expiry_year": "30"
}

Sample response

{
"wallet_id": "507e8c90-3cfc-44ee-b701-0630067eb44fa5e9351a-0a6",
"provisioning_data": {
"opc": "eyJ4NWMiOlsiTUlJQzNqQ0NBY2FnQXdJQkFnSUpBT1FDdnc2...",
}
}

Enroll the tokenized card into the secure device wallet

Now that we have tokenized the customer’s card and generated the device opaque data (provisioning_data.opc), it is time to enroll the tokenized account into the secure device wallet.

To complete the setup, the device opaque data (provisioning_data.opc) should be injected into the SDK. Use the enrollAccount() method to inject provisioning_data.opc received in the previous step.

If all goes well, the callback OpenfabricCallback#onSuccess() is called. We will initiate the process of asynchronously pulling the payment cryptograms generated for the tokenized account. When this is complete, the app is notified with the callback CardEventListener#onCardsUpdated().

If an error occurs anytime during the above process, the callback OpenfabricCallback#onError() is called, passing the reason for the error.

Enroll Account
wallet.enrollCard(context, provisioningDataOpc), object : OpenfabricCallback<DigitizeAccountResponse> {
override fun onSuccess(response: DigitizeAccountResponse) {
// update provisioning state with enrollment succeeded
}

override fun onError(error: OpenFabricError) {
displayError(RuntimeException(error.message))
}
})
CardListener.kt
class CardListener: CardEventListener {
override fun onCardsUpdated(context: Context) {
val intent = Intent(context, MainActivity::class.java)
intent.setAction(CardEventsReceiver.CARD_UPDATED)
LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
}
...
}
note

The registration of the listener is done by declaring the listener class in your manifest file under the key co.openfabric.nfc.CardEventListener, as shown below:

AndroidManifest.xml
<meta-data
android:name="co.openfabric.nfc.CardEventListener"
android:value="mypackage.CardListener" />

After this step is done, you can continue with card activation and setting preference as described here

Collecting card data from user

To start the process of tokenizing an existing card into an Own App Token, please make sure you have created a secure device wallet as explained here

Once the device is ready with a secure device wallet provisioned, it’s time to collect the user's card data for tokenization and push it into the secure wallet.

To initiate the secure session for collecting card data, use the requestCardTokenization() method. If all goes well, the callback OpenfabricCallback#onSuccess() is called with the session URL as an argument. We will initiate the process of asynchronously pulling the payment cryptograms generated for the tokenized card.

If an error occurs, the callback OpenfabricCallback#onError() is called, passing the reason for the error.

Enroll Card
wallet.requestCardTokenization(object : OpenfabricCallback<String> {
override fun onSuccess(sessionUrl: String) {
// Open WebView with the session URL to start card data collection
}

override fun onError(error: OpenFabricError) {
displayError(RuntimeException(error.message))
}
})

Now you should open the secure session URL in a WebView and present it to the user to start the card data collection and tokenization process. The process is handled securely between the user's device and Open Fabric backend. When this is complete, the app is notified with the callbacks CardEventListener#onCardsUpdated() and CardEventListener#onCardActivated(context, cardId).

CardListener.kt
class CardListener: CardEventListener {
override fun onCardsUpdated(context: Context) {
val intent = Intent(context, MainActivity::class.java)
intent.setAction(CardEventsReceiver.CARD_UPDATED)
LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
}

override fun onCardActivated(context: Context, cardId: String) {
val intent = Intent(context, MainActivity::class.java)
intent.setAction(CardEventsReceiver.CARD_ACTIVATED)
intent.putExtra(CardEventsReceiver.CARD_ID, cardId)
LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
}
...
}
note

The registration of the listener is done by declaring the listener class in your manifest file under the key co.openfabric.nfc.CardEventListener, as shown below:

AndroidManifest.xml
<meta-data
android:name="co.openfabric.nfc.CardEventListener"
android:value="mypackage.CardListener" />

After this step is done, you can continue with card activation and setting preference as described here

Card Scanning via NFC Tap

We provide a helper method that configures the WebView to enable customers to tap their physical card on the device’s NFC reader to automatically extract and pre-fill card information.

WebView Activity
class WebViewActivity : AppCompatActivity() {
private lateinit var webView: WebView
private lateinit var callback: CardCollectionCallback

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
HceHelper.setupCardCollectionCallback(
this,
webView,
callback
)
...
}
...
}

To enable tap-to-read functionality for collecting card details via NFC, you must first configure the WebView using HceHelper.setupCardCollectionCallback(activity, webview, callback).

When a user successfully taps a card, and the device is able to parse the card details, the JavaScript function onCardDataReceived(pan, expiry) will be called inside the WebView. The parameters pan and expiry contain the card number and expiry date respectively. Once this function is invoked, the device will automatically exit NFC reader mode.

If the WebView activity is exited before the NFC tap flow is completed, such as if the user navigates away or closes the activity, it is important to restore the device’s default NFC behavior. To do this, call HceHelper.enableHceService(activity) from the host activity’s onPause() method. This ensures that the device resumes its normal NFC operations if the WebView does not complete the card collection process

The CardCollectionCallback interface is used to receive status updates through the Card Collection flow. It includes several callback methods:

CardCollectionCallback.kt
// Callback interface for tracking events during the card collection flow via NFC.
interface CardCollectionCallback {

// Called when the card details form page has fully loaded and is ready for interaction.
//highlight-next
fun onFormReady()

// Called when __openfabric_js_bridge__.startCardScan() is invoked from the WebView and the device has entered NFC reader mode.
//highlight-next
fun onCardTapRequested()


// Called when a card has been successfully tapped and the card details are parsed correctly. The device will then exit NFC reader mode.
//highlight-next
fun onCardTapped()


// Called when an error occurs while attempting to parse the card details after tapping the card. The device will then exit NFC reader mode.
//highlight-next
fun onCardTapError()


// Called when the card is successfully added and the user reaches the success confirmation page.
//highlight-next
fun onCardAdded()

// Called when a generic error occurs that redirects the user to an error page.
//highlight-next
fun onError()
}

These callbacks allow the host application to respond appropriately at each stage of the tap-to-read process, ensuring a smooth and reliable integration.

After this step is done, you can continue with card activation and setting preference as described here