> For the complete documentation index, see [llms.txt](https://docs.payments.thalescloud.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.payments.thalescloud.io/classic-push-provisioning/use-cases/push-provisioning-via-tsp.md).

# Push provisioning via TSP

Mastercard Token Connect (MDES Token Connect) is a service provided by Mastercard. Issuers use it to push cards to token requestors.

To participate, token requestors must comply with the Mastercard program and provide onboarding details to the TSPs. This lets the TSP determine how a card can be pushed to a given token requestor.

Typically, these services expose an API that allows issuers to:

* Query TSPs for the token requestors registered to the program and their available interface details (an application, a website, or both).
* Query TSPs for the appropriate URI (formatted with the card details) that the issuer application uses to push the card, after the end user selects a token requestor interface (such as a website).

The last step—pushing the card to the token requestor—remains the responsibility of the issuer application.

To use these APIs, issuers must open a project with the payment networks. Otherwise, the payment networks will not allow API access.

The Thales Push Provisioning solution embeds the MDES Token Connect APIs. This lets issuers access them directly from the issuer application through the SDK.

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Note <a href="#note" id="note"></a>
>
> Only token requestors registered in MDES Token Connect programs are accessible. Availability varies by region. For the list available in your region, check with your Visa and Mastercard contacts.

The following sections provide the details:

1. Use Thales SDK to request the list of token requestors eligible for a given card.
2. Select a token requestor from the returned list and use Thales SDK to request the formatted URI that is used to push the card.
3. Push the card to the selected token requestor.

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Note <a href="#note-1" id="note-1"></a>
>
> The issuer application always pushes the card to the selected token requestor interface.

### 1. Getting the eligible token requestors <a href="#id-1-getting-the-eligible-token-requestors" id="id-1-getting-the-eligible-token-requestors"></a>

The issuer application uses the Push Provisioning SDK to get a list of token requestors that are compatible with the issuer’s cards and the associated payment schemes.

This flow is shown in the following figure:

<figure><img src="/files/B64uL4PCwHNzguGT3Xt4" alt=""><figcaption><p>Get eligible token requestors for a card.</p></figcaption></figure>

* Steps 1 and 2: The issuer builds the encrypted card details according to the [format](/classic-push-provisioning/developer-guide/data-encryption-and-authentication.md) expected by the Push Provisioning SDK.
* Step 3: The issuer application calls the SDK through the `getEligibleTokenRequestors` ([Android](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/android/latest/com/thalesgroup/tpcsdk/provisioning/TSHProxy.html#getEligibleTokenRequestors\(java.lang.String,java.lang.String,java.lang.String,com.thalesgroup.tpcsdk.manager.listener.TPCSDKListener\))/[iOS](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/ios/latest/Classes/TPCSDK.html#/c:@M@TPCSDKSwift@objc\(cs\)TPCSDK\(cm\)getEligibleTokenRequestorWithCard:publicKeyIdentifier:completion:)) with the card details.
* Step 4: The Thales backend calls the TSP (VTS or MDES) to request the eligible token requestors.
* Step 5: The list is returned to the issuer mobile application.
* Step 6: The issuer mobile application gets the details for each token requestor and displays them to the end user so that a selection can be made.

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Note <a href="#note-2" id="note-2"></a>
>
> * Step 6 in the figure shows a possible interaction with the end user.
> * The overall UX is out of scope for this document.
> * The issuer is free to filter out the token requestors that are visible to the end user.
> * As there may be many dozens of token requestors available, the application has to manage the visibility of the items.

The following code snippet shows how to request the list of eligible token requestors:

{% tabs %}
{% tab title="Swift" %}

```swift
let scheme = "MASTERCARD"
let payload = "PKCS7 encrypted PAN"

let card = FundingCard(schemeString: scheme,
                        encryptedPayload: payload)

let publicKeyId = "id"

TPCSDK.getEligibleTokenRequestor(card: card,
                                  publicKeyIdentifier: publicKeyId) { (tokenRequestorList, error) in
    if let error = error {
        //Handle TPCError
    } else {
        let tokenRequestor = tokenRequestorList?.first
        let pushMethod = tokenRequestor?.pushMethods?.first
        let pushHandler = pushMethod?.pushHandler // for push provisioning
    }
}
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
NSString *scheme = @"MASTERCARD";
NSString * payload = @"PKCS7 encrypted PAN";

FundingCard * card = [[FundingCard alloc] initWithSchemeString:scheme
                                              encryptedPayload:payload
                                      primaryAccountIdentifier:nil];

NSString * publicKeyId = @"id";

[TPCSDK getEligibleTokenRequestorWithCard:card
                      publicKeyIdentifier:publicKeyId
                                completion:^(NSArray<TokenRequestor *> * _Nullable tokenRequestorList, NSError * _Nullable error) {
    if (error != nil) {
        //Handle TPCError
    } else {
        TokenRequestor *tokenRequestor = tokenRequestorList[0];
        PushMethod *pushMethod = [tokenRequestor pushMethods][0];
        NSString *pushHandler = pushMethod.pushHandler;
    }
}];
```

{% endtab %}

{% tab title="Android" %}

```java
Config config = new Config();
config.setActivity(activity);
config.setIssuerId(ISSUERID);
config.setOemPayType(OEMPayType.NONE); // This one is required to get correct PushProvisioning object
config.setUrl(envUrl);

TPCManager.getInstance().config(config, listener);
TPCManager.getInstance().getTSHProxy().getEligibleTokenRequestors(cardScheme, 
                                                                  encryptedPayload, 
                                                                  publicKeyId, 
                                                                  new TPCSDKListener<TokenRequestor[]>() {
    @Override
    public void onStart() {

    }

    @Override
    public void onSuccess(TPCResult<TokenRequestor[]> tpcResult) {
        TokenRequestor[] tokenRequestors = tpcResult.getResult();
        String pushHandler = tokenRequestors[0].getPushMethods()[0].getPushHandler(); // for push provisioning
    }

    @Override
    public void onError(TPCSDKException exception) {
        listener.onError(exception);
    }
});
```

{% endtab %}
{% endtabs %}

#### Get asset <a href="#get-asset" id="get-asset"></a>

Using the TPC SDK, the issuer application can obtain the token requestor’s logo image using the string returned by the `getEligibleTokenRequestor` API.

For the Visa scheme, the image of the token requestor's logo is returned as a URL that the mobile application has to fetch directly.

For the Mastercard scheme, the logo image is returned as a `logoId`. To fetch the logo, call the `getAsset` API.

<figure><img src="/files/5qSYrZj3aCb5kn3iE4cH" alt=""><figcaption><p>Retrieve a token requestor logo (Mastercard only).</p></figcaption></figure>

**Getting the logo of token requestor**

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Note <a href="#note-3" id="note-3"></a>
>
> This is only available for the Mastercard scheme.

After the application has obtained the list of token requestors, it can request to get the image of the token requestor's logo.

The following code snippet shows an example of how to get the token requestor’s logo image via the TPC SDK:

{% tabs %}
{% tab title="Swift" %}

```swift
func getTokenRequestorWithAssetId(id: String) {
    TPCSDK.getTokenRequestorAsset(assetId: id) {
      (tokenRequestorAsset, error) in
    }
  }
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c

- (void) getTokenRequestorWithAssetId: (NSString *) id {
  [TPCSDK getTokenRequestorAssetWithAssetId:id
                                 completion:^(NSArray<TokenRequestorAsset *> * _Nullable tokenRequestorAsset, NSError * _Nullable error) {
  }];
}
```

{% endtab %}

{% tab title="Android" %}

```java


try {
    TPCManager.getInstance().getTSHProxy().getAsset(assetId,
 	   new TPCSDKListener<MediaData[]>() {
        @Override
        public void onStart() {
            // Do nothing
        }

        @Override
        public void onSuccess(TPCResult<MediaData[]> result) {                
		    		MediaData[] mediaData = result.getResult();
            Log.d("TAG", "get Asset request success"); 
        }

        @Override
        public void onError(TPCSDKException exception) {
            Log.e("TAG", "get Asset request failed");
        }
      });
} catch (TPCSDKException exception) {
    Log.e("TAG", "TSHProxy Exception " +exception.getMessage());
}
```

{% endtab %}
{% endtabs %}

### 2. Selecting the token requestor <a href="#id-2-selecting-the-token-requestor" id="id-2-selecting-the-token-requestor"></a>

Each element that is returned by the `getEligibleTokenRequestors` ([Android](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/android/latest/com/thalesgroup/tpcsdk/provisioning/TSHProxy.html#getEligibleTokenRequestors\(java.lang.String,java.lang.String,java.lang.String,com.thalesgroup.tpcsdk.manager.listener.TPCSDKListener\))/[iOS](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/ios/latest/Classes/TPCSDK.html#/c:@M@TPCSDKSwift@objc\(cs\)TPCSDK\(cm\)getEligibleTokenRequestorWithCard:publicKeyIdentifier:completion:)) is a potential token requestor to which the card can be pushed.

A `TokenRequestor` object will expose the following properties:

* `id`: The Token Requestor ID (TRID) which is unique as per token requestor and is generated by the scheme.
* `name`: The name of the token requestor to be displayed.
* `logo`: The displayable icon that is associated with the token requestor.
  * For Mastercard, this can be accessed through the `logoId` and `getAsset` APIs.
* `pushMethods`: This object is an array of methods that can be used to contact the given token requestor. Each element of the array has two properties:
  * `platformType`: Indicates the platform the token requestor application is available on: `ANDROID`, `IOS`, or `WEB`.
  * `pushHandler`: Contains information about how to manage the push request to the token requestor. For each `platformType`, there is a `pushHandler` which is used to request the URI formatted with the card details from the TSP so that it can be used to call the token requestor.

Because a token requestor may be accessible through multiple interfaces, pay close attention to `pushMethods`:

* Application interface (when `platformType=ANDROID` or `platformType=IOS`)
* Website interface (when `platformType=WEB`)

For an application interface, the issuer application interacts with the token requestor application.

> <i class="fa-exclamation-circle">:exclamation-circle:</i>
>
> #### Warning <a href="#warning" id="warning"></a>
>
> If the token requestor application is not installed, the issuer application must handle the following cases:
>
> * In `ANDROID`, [ActivityNotFoundException](https://developer.android.com/reference/android/content/ActivityNotFoundException) has to be handled when calling the [startActivity](https://developer.android.com/reference/android/content/Context#startActivity\(android.content.Intent\)) method.
> * In `IOS`, the issuer application has to check if the URL is available using the [canOpenURL](https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl) API.
>
> Verifying whether the token requestor application is installed is outside the Thales SDK scope. The token requestor must provide a URI to the TSPs during onboarding.

For website interface, the issuer application has to interact with the website of the token requestor.

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Recommendation <a href="#recommendation" id="recommendation"></a>
>
> For a streamlined experience, support `platformType=WEB`. Handle the flow in a WebView within the issuer application, instead of redirecting to an external application.

### 3. Pushing the card <a href="#id-3-pushing-the-card" id="id-3-pushing-the-card"></a>

To push a card to a selected token requestor, you need the URI that triggers the token requestor with correctly formatted card details. Query this URI from the TSP.

This flow is depicted in the following figure:

<figure><img src="/files/y5hbGCoFFjZjZGv6oAPE" alt=""><figcaption><p>Request a push URI from the TSP.</p></figcaption></figure>

* Step 1: The end user selects a token requestor.
* Step 2: The issuer application gets the `pushHandler` property from the `TokenRequestor` object and calls the SDK through the `addCard` ([Android](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/android/latest/com/thalesgroup/tpcsdk/provisioning/PushProvisioning.html#addCard\(com.thalesgroup.tpcsdk.model.CardInfo,java.lang.String,boolean,com.thalesgroup.tpcsdk.model.CallbackObject,java.lang.String,com.thalesgroup.tpcsdk.manager.listener.TPCSDKListener\))/[iOS](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/ios/latest/Classes/TPCSDK.html#/c:@M@TPCSDKSwift@objc\(cs\)TPCSDK\(cm\)schemePushProvisionWithCard:publicKeyIdentifier:authorizationCode:termsAndConditionsAccepted:callbackUrl:callbackType:pushHandler:completion:)) API.
* Step 3: The SDK interacts with the backend to request a push provisioning.
* Step 4: The Thales backend verifies whether the request is authorized.
* Step 5: The Thales backend requests the payload and generates a push URL through the TSP.
* Step 6: The SDK returns the push URL to the issuer application.
* Step 7: The issuer application calls the push URL to launch the token requestor.

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Note <a href="#note-4" id="note-4"></a>
>
> The URI depends on `platformType`. `pushHandler` changes based on whether the interface is an application or a website.

For the other parameters shown in the figure:

* The `authorizationCode` is required to grant the permission to send the request. This has to be compliant with the [format and algorithm](/classic-push-provisioning/developer-guide/data-encryption-and-authentication/authorization-code-jwt-format.md).
* The callback URL allows the token requestor to call the issuer application at the end of the flow. This has to be configured using the deep link mechanism.

> <i class="fa-info-circle">:info-circle:</i>
>
> **Setting up a deep link URL**
>
> * [Android](https://developer.android.com/training/app-links/deep-linking)
> * [iOS](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app)

The following sample code demonstrates how to get the URI from the TSP through the SDK:

{% tabs %}
{% tab title="Swift" %}

```swift
let scheme = "MASTERCARD"
let payload = "3080xxx"

let card = FundingCard(schemeString: scheme,
                    encryptedPayload: payload)

let publicKeyId = "id"
let code = "code"
let callbackUrl = "tpcsdk://com.thalesgroup.tpc.demo/tokenRequestorsPage"
let base64EncodedCallbackUrl = callbackUrl.data(using: .utf8)!.base64EncodedString()
let callbackType = "IOS"

// This value can be retrieved from TPCSDK.getEligibleTokenRequestor
// For Click to Pay , the MasterCard tokenRequestor.id attribute value is 50123197928.
let pushHandler = "handler"

TPCSDK.schemePushProvision(card: card,
                            publicKeyIdentifier: publicKeyId,
                            authorizationCode: code,
                            termsAndConditionsAccepted: true,
                            callbackUrl: base64EncodedCallbackUrl,
                            callbackType: callbackType,
                            pushHandler: pushHandler) { (pushUrl, error) in
    if let error = error {
        // handle TPC Error
    } else if let pushUrl = pushUrl {
        // launch the token requestor app
        let url = URL(string: pushUrl)!
        if UIApplication.shared.canOpenURL(provisionURL) {
          UIApplication.shared.open(url, options: [:], completionHandler: nil)
        } else {
          // show error that Application is not installed
        }
    }
}
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c

NSString *scheme = @"MASTERCARD";
NSString * payload = @"PKCS7 encrypted PAN";

FundingCard * card = [[FundingCard alloc] initWithSchemeString:scheme
                                              encryptedPayload:payload
                                      primaryAccountIdentifier:nil];

NSString * publicKeyId = @"id";
NSString * code = @"code";
NSString * callbackUrl = @"tpcsdk://com.thalesgroup.tpc.demo/tokenRequestorsPage";
NSString * base64EncodedCallbackUrl = [[NSString alloc] initWithData:[[callbackUrl dataUsingEncoding:NSUTF8StringEncoding] base64EncodedDataWithOptions:NSDataBase64EncodingEndLineWithLineFeed] encoding:NSUTF8StringEncoding];
NSString * callbackType = @"IOS";

// This value can be retrieved from TPCSDK.getEligibleTokenRequestor
// For Click to Pay , the MasterCard tokenRequestor.id attribute value is 50123197928.
NSString * pushHandler = @"handler";

[TPCSDK schemePushProvisionWithCard:card
                publicKeyIdentifier:publicKeyId
                  authorizationCode:code
          termsAndConditionsAccepted:TRUE
                        callbackUrl:base64EncodedCallbackUrl
                        callbackType:callbackType
                        pushHandler:pushHandler
                          completion:^(NSString * _Nullable pushUrl, NSError * _Nullable error) {
    if (error != nil) {
        // handle TPCError
    } else {
        // launch the token requestor app
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:pushUrl] options:@{} completionHandler:nil];
    }
}];
```

{% endtab %}

{% tab title="Android" %}

```java


CardInfo cardInfo = new CardInfo();
cardInfo.setScheme("MASTERCARD");
cardInfo.setEncryptedPayload(encryptedPayload);
cardInfo.setAuthorizationCode(authorizationCode);

CallbackObject callback = new CallbackObject();
String callbackUrl = "tpcsdk://com.thalesgroup.tpc.demo/tokenRequestorsPage";
String callbackUrlInBase64 = Base64.encodeToString(callbackUrl.getBytes(), Base64.NO_WRAP | Base64.URL_SAFE);
callback.setUrl(callbackUrlInBase64);
callback.setType("ANDROID");

String publicKeyId = "id";
boolean tcsAccepted = true;

// This value can be retrieved from TPCSDK.getEligibleTokenRequestor
// For Click to Pay , the MasterCard tokenRequestor.id attribute value is 50123197928.
String pushHandler = "handler";

TPCManager.getInstance().getTSHProxy().addCard(cardInfo, 
                                               publicKeyId, 
                                               tcsAccepted, 
                                               callback, 
                                               pushHandler, 
                                               new TPCSDKListener<String>() {
    @Override
    public void onStart() {

    }

    @Override
    public void onSuccess(TPCResult<String> result) {
        String pushUrl = result.getResult();

        // Launch token requestor application
        try {
          getActivity().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(pushUrl)));
        } catch (ActivityNotFoundException e) {
          // No Activity available to handle action
        }
    }

    @Override
    public void onError(TPCSDKException exception) {
        // Check if there's any error in the push provisioning
    }
});
```

{% endtab %}
{% endtabs %}

The following figure depicts a generic flow where the issuer application pushes the card to the token requestor application.

<figure><img src="/files/TlQFl2ZOBmiSOOjV36dd" alt=""><figcaption><p>Generic push provisioning flow with a token requestor.</p></figcaption></figure>

The first part of the flow involves only the issuer application.

In step 3, the issuer application uses the list returned by the `getEligibleTokenRequestors` API ([Android](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/android/latest/com/thalesgroup/tpcsdk/provisioning/TSHProxy.html#getEligibleTokenRequestors\(java.lang.String,java.lang.String,java.lang.String,com.thalesgroup.tpcsdk.manager.listener.TPCSDKListener\))/[iOS](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/ios/latest/Classes/TPCSDK.html#/c:@M@TPCSDKSwift@objc\(cs\)TPCSDK\(cm\)getEligibleTokenRequestorWithCard:publicKeyIdentifier:completion:)) to build the interface displayed to the end user.

When the end user confirms in step 4 that they want to push the card (or immediately after the selection in step 3), the issuer application calls the SDK using the `addCard` ([Android](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/android/latest/com/thalesgroup/tpcsdk/provisioning/PushProvisioning.html#addCard\(com.thalesgroup.tpcsdk.model.CardInfo,java.lang.String,boolean,com.thalesgroup.tpcsdk.model.CallbackObject,java.lang.String,com.thalesgroup.tpcsdk.manager.listener.TPCSDKListener\))/[iOS](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/ios/latest/Classes/TPCSDK.html#/c:@M@TPCSDKSwift@objc\(cs\)TPCSDK\(cm\)schemePushProvisionWithCard:publicKeyIdentifier:authorizationCode:termsAndConditionsAccepted:callbackUrl:callbackType:pushHandler:completion:)) so the SDK can query the TSP for the URI used to push the card.

<figure><img src="/files/wYKjHTu15uC6UXBSvqWP" alt=""><figcaption><p>Push the card by launching the token requestor.</p></figcaption></figure>

Once the URI is returned from step 4, the issuer application uses the URI to push the card to the token requestor.

The token requestor takes control in step 5, and there will be several pop-ups to drive the end user through the tokenization flow.

At this point, the token requestor application is in full control. It interacts with the TSP to request card digitization, as shown in steps 6 and 7.

Once digitization completes, the end user can proceed as shown in step 7. Control can return to the issuer application if the token requestor uses the callback URL provided by `addCard` ([Android](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/android/latest/com/thalesgroup/tpcsdk/provisioning/PushProvisioning.html#addCard\(com.thalesgroup.tpcsdk.model.CardInfo,java.lang.String,boolean,com.thalesgroup.tpcsdk.model.CallbackObject,java.lang.String,com.thalesgroup.tpcsdk.manager.listener.TPCSDKListener\))/[iOS](https://thalesgroup.github.io/d1sdk-docs/tpc-sdk/ios/latest/Classes/TPCSDK.html#/c:@M@TPCSDKSwift@objc\(cs\)TPCSDK\(cm\)schemePushProvisionWithCard:publicKeyIdentifier:authorizationCode:termsAndConditionsAccepted:callbackUrl:callbackType:pushHandler:completion:)) API.

<br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.payments.thalescloud.io/classic-push-provisioning/use-cases/push-provisioning-via-tsp.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
