> 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/es/guia-para-desarrolladores/configuracion-del-sdk/android.md).

# Android

Push Provisioning SDK se utiliza para tokenizar tarjetas para Google Pay y Samsung Pay. Este SDK gestiona la comunicación con los SDK de Google Pay y Samsung Pay. También simplifica el flujo de tokenización para las aplicaciones emisoras.

Esta sección está dirigida a desarrolladores de aplicaciones emisoras Android que quieran integrar Push Provisioning SDK en su aplicación.

### Servicios disponibles <a href="#available-services" id="available-services"></a>

Thales Push Provisioning SDK proporciona los siguientes servicios:

* Le permite integrar una aplicación emisora con las API de Push Provisioning SDK, como `isCardDigitized` y `addCard` (Google Pay y Samsung Pay).
* Reduce la necesidad de comprender los SDK de Google Pay y Samsung Pay.
* Reutiliza los servicios de Push Provisioning SDK en proyectos existentes.
* Inscribe el FPAN en Google Pay o Samsung Pay.
* Accede a las API del servidor TSH.

### Requisitos previos <a href="#prerequisites" id="prerequisites"></a>

* Versión de Java: 11
* Versión de Android Studio: Chipmunk o posterior.
* Un dispositivo con Google Play Services (para Google Pay).

> <i class="fa-info-circle">:info-circle:</i>
>
> Para obtener la funcionalidad completa de Google Pay, se recomienda ejecutarlo en dispositivos móviles.

### Integración con la aplicación emisora <a href="#integrating-with-issuer-app" id="integrating-with-issuer-app"></a>

* Crea una carpeta llamada `libs` dentro del directorio del módulo (normalmente 'app'), como se muestra en la siguiente figura:

<figure><img src="https://2719026056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC22AqJs7fn1cZC7pAaOE%2Fuploads%2FaVZ5xunluNKEoqgRwQ63%2FDev-Guide_SDK-conf_01.png?alt=media&amp;token=d21c8dad-b05a-421f-9153-1227e3e0c7a1" alt=""><figcaption></figcaption></figure>

* Copia el archivo AAR de Push Provisioning SDK en la carpeta `libs` .
* Desde Push Provisioning SDK v1.12.2, copia el archivo JAR de Samsung Pay SDK en la carpeta `libs` .
* Desde Push Provisioning SDK v2.0.0, copia el archivo AAR de Google Pay SDK en la carpeta `libs` .
* Abre el `build.gradle` o `build.gradle.kts` de la aplicación y añade las siguientes dependencias:

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

```groovy
android {
  defaultConfig {
    ndk {
      abiFilters 'arm64-v8a', 'x86_64', 'armeabi-v7a', 'x86'
    }
  }
  buildTypes {
        debug {
            // para Samsung Pay
            manifestPlaceholders = [DEBUG_MODE: 'Y', SPAY_API_LEVEL: 2.22]
        }
        release {
            // para Samsung Pay
            manifestPlaceholders = [DEBUG_MODE: 'N' , SPAY_API_LEVEL: 2.22]
        }
    }
}

dependencies {
    debugImplementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' // depuración contiene registrador
    releaseImplementation 'com.squareup.okhttp3:okhttp:4.9.1'
    implementation "com.google.android.gms:play-services-base:18.5.0"
    implementation "com.google.android.gms:play-services-basement:18.5.0"
    implementation files('libs/tpcsdk.aar') // Usa el nombre de archivo más reciente de Push Provisioning SDK 
    implementation files('libs/samsungpay_2.22.00.jar') // desde SDK v1.12.2
    implementation files('libs/play-services-tapandpay-18.7.0.aar') // desde SDK v2.0.0
    implementation 'net.java.dev.jna:jna:5.17.0@aar'
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
android {
  defaultConfig {
    ndk {
      abiFilters += listOf("arm64-v8a", "x86_64", "armeabi-v7a", "x86")
    }
  }
}

dependencies {
    debugImplementation ("com.squareup.okhttp3:logging-interceptor:4.9.1") // depuración contiene registrador
    releaseImplementation ("com.squareup.okhttp3:okhttp:4.9.1")
    implementation ("com.google.android.gms:play-services-base:18.2.0")
    implementation files('libs/samsungpay_2.22.00.jar') // desde SDK v1.12.2
    implementation files('libs/play-services-tapandpay-18.7.0.aar') // desde SDK v2.0.0
    implementation (files("libs/tpcsdk.aar")) // Usa el nombre de archivo más reciente de Push Provisioning SDK 
    implementation ("net.java.dev.jna:jna:5.17.0@aar")
}
```

{% endtab %}
{% endtabs %}

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Nota <a href="#note" id="note"></a>
>
> * Desde Push Provisioning SDK V1.7.0, la biblioteca JNA se utiliza como dependencia. Se recomienda usar JNA V5.5.0 porque no se garantiza que otras versiones funcionen con Push Provisioning SDK.
> * Desde Push Provisioning SDK V1.12.0, es obligatorio usar JNA V5.17.0 para admitir tamaños de página de 16 KB.

* Para importar una dependencia file-tree en la compilación de Gradle, abre el `build.gradle` o `build.gradle.kts` de la aplicación y añade la siguiente dependencia:

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

```groovy
dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])

}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
}
```

{% endtab %}
{% endtabs %}

* Consulta la aplicación de ejemplo y la documentación de Java para aprender a usar las API de Push Provisioning SDK.

> <i class="fa-exclamation-circle">:exclamation-circle:</i>
>
> #### Compatibilidad con tamaños de página de 16 KB <a href="#supporting-16-kb-page-sizesbr" id="supporting-16-kb-page-sizesbr"></a>
>
> A partir del 1 de noviembre de 2025, todas las aplicaciones desarrolladas recientemente y las actualizaciones de aplicaciones existentes enviadas a Google Play, y destinadas a dispositivos Android 15+, deben admitir tamaños de página de 16 KB. Esta compatibilidad está disponible para Push Provisioning SDK V1.12.0 y posteriores.
>
> Al compilar un APK que admita tamaños de página de 16 KB:
>
> * Actualiza a Push Provisioning SDK V1.12.0 o posterior.
> * Actualiza la dependencia de JNA a 5.17.0 o posterior. Para JNA 5.17.0, la versión requerida de Android Gradle Plugin (AGP) es 8.0.2 o posterior. Si utilizas una versión de AGP anterior a 8.0.2, es posible que encuentres problemas de compilación.
> * Cuando la versión de AGP es 8.5.1 o posterior, la aplicación se alinea automáticamente con tamaños de página de 16 KB. Si es anterior a 8.5.1, configura las [opciones de empaquetado heredadas](https://developer.android.com/guide/practices/page-sizes#agp_version_85_or_lower) en el `build.gradle` archivo.

### Configuración <a href="#configuration" id="configuration"></a>

Usa el siguiente fragmento para configurar Push Provisioning SDK en tu aplicación móvil:

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Nota <a href="#note-1" id="note-1"></a>
>
> Desde Push Provisioning SDK V1.9.0, tu aplicación puede establecer un `Context` de aplicación en lugar de un `Activity` al configurar Push Provisioning SDK para Google Pay y Samsung Pay. Un `Activity` solo es requerido por la nueva API, `addCard(Activity activity, CardInfo cardInfo, TPCSDKListener<T> listener)`, para el push provisioning de Google Pay.

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

```java
protected static final int HTTP_TIMEOUT = 60;

protected CountDownLatch mCountDownLatch;

protected void awaitCountDownLatch() {
    try {
        mCountDownLatch.await(HTTP_TIMEOUT, TimeUnit.SECONDS);
    } catch (Exception e) { // Ignorado.
    }
}

protected void resetCountDownLatch() {
    mCountDownLatch = new CountDownLatch(1);
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); 
    // Configurar SDK para el push provisioning de esquema
    // Desde Push Provisioning SDK V2.0.0, solo establece OEMPayType cuando realices el aprovisionamiento de OEM Wallet. De lo contrario, deja el tipo OEM sin establecer.
    Config schemeConfig = new Config();
    schemeConfig.setIssuerId("ISSUERID");
    schemeConfig.setUrl("URL"); // URL correspondiente
    // Desde Push Provisioning SDK V1.9.0, la aplicación puede establecer `Context`
    // en lugar de `Activity` durante la configuración de Push Provisioning SDK
    // para el aprovisionamiento de esquema
    schemeConfig.setContext(getApplicationContext());
    configSdkForScheme(schemeConfig);
    
    // Configurar SDK para push provisioning OEM
    Config oemConfig = new Config();
    oemConfig.setIssuerId("ISSUERID");
    oemConfig.setUrl("URL"); // URL correspondiente
    
    // La lista puede actualizarse en consecuencia. Por ejemplo, es posible que solo necesites tener un tipo de OEMPayType.
    List<OEMPayType> oemPayTypes = Arrays.asList(
        //Desde Push Provisioning SDK V2.0.0, OEMPayType.NONE ya no es compatible
        OEMPayType.GOOGLE_PAY,
        OEMPayType.SAMSUNG_PAY,
        OEMPayType.HUAWEI_PAY);

    for (OEMPayType oemPayType:oemPayTypes) {
        if (oemPayType == OEMPayType.SAMSUNG_PAY) {
            oemConfig.setContext(getApplicationContext());
            oemConfig.setServiceId("SERVICEID");
            oemConfig.setVisaClientAppId("VisaClientAppID");
        } else if (oemPayType == OEMPayType.HUAWEI_PAY) {
            String callbackUrl = "tpcsdk://com.thalesgroup.tpc.demo/tokenRequestorsPage";
            oemConfig.setCallbackUrl(callbackUrl);
            oemConfig.setActivity(getActivity());
        } else if (oemPayType == OEMPayType.GOOGLE_PAY) {
            //Desde Push Provisioning SDK V1.9.0, la aplicación puede establecer `Context` en lugar de `Activity` durante la configuración de Push Provisioning SDK para Google Pay
            oemConfig.setContext(getApplicationContext());
        }
        configSdk(oemPayType, oemConfig);
    }
}

public void configSdkForScheme(Config configs) throws InterruptedException {
    // Desde Push Provisioning SDK V2.0.0, para el push provisioning de esquema, no establezcas OEMPayType
    resetCountDownLatch();
    TPCManager.getInstance().config(configs, new TPCSDKListener<Boolean>() {
        @Override
        public void onStart() {
        }

        @Override
        public void onSuccess(TPCResult<Boolean> result) {
            Log.d("CONFIG_SDK", "Configuración de esquema exitosa...");
            mCountDownLatch.countDown();
        }

        @Override
        public void onError(TPCSDKException exception) {
            Log.e("CONFIG_SDK", "La configuración de esquema falló con el error: " + exception.getMessage());
            mCountDownLatch.countDown();
        }
    });
    awaitCountDownLatch();
}

public void configSdk(OEMPayType oemPayType, Config configs) throws InterruptedException {
    configs.setOemPayType(oemPayType);
    resetCountDownLatch();
    TPCManager.getInstance().config(configs, new TPCSDKListener<Boolean>() {
        @Override
        public void onStart() {
        }

        @Override
        public void onSuccess(TPCResult<Boolean> result) {
            Log.d("CONFIG_SDK", "Configuración exitosa..." + oemPayType.getOemType());
            mCountDownLatch.countDown();
        }

        @Override
        public void onError(TPCSDKException exception) {
            Log.e("CONFIG_SDK", "La configuración falló con el error: " + exception.getMessage());
            mCountDownLatch.countDown();
        }
    });
    awaitCountDownLatch();
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
class MainViewModel : ViewModel() {
    fun configureMultipleOEM(activity: Activity){
        viewModelScope.launch {
            // Configurar SDK para el push provisioning de esquema
            // Desde Push Provisioning SDK V2.0.0, solo establece OEMPayType cuando realices el aprovisionamiento de OEM Wallet. De lo contrario, deja el tipo OEM sin establecer.
            val schemeConfig = Config()
            schemeConfig.issuerId = "ISSUERID"
            schemeConfig.url = "URL" // URL correspondiente
            // Desde Push Provisioning SDK V1.9.0, la aplicación puede establecer `Context`
            // en lugar de `Activity` durante la configuración de Push Provisioning SDK
            // para el aprovisionamiento de esquema
            schemeConfig.context = applicationContext

            configSdkForScheme(schemeConfig).collect {
                println(it)
            }

            // Configurar SDK para push provisioning OEM
            val oemConfig = Config()
            oemConfig.issuerId = "ISSUERID"
            oemConfig.url = "URL" // URL correspondiente

            // La lista puede actualizarse en consecuencia. Por ejemplo, es posible que solo necesites tener un tipo de OEMPayType.
            val oemPayTypes: List<OEMPayType> = listOf(
                //Desde Push Provisioning SDK V2.0.0, OEMPayType.NONE ya no es compatible
                OEMPayType.GOOGLE_PAY,
                OEMPayType.SAMSUNG_PAY,
                OEMPayType.HUAWEI_PAY
            )
            for (oemPayType in oemPayTypes) {
                when (oemPayType) {
                    OEMPayType.SAMSUNG_PAY -> {
                        oemConfig.serviceId = "SERVICEID"
                        oemConfig.context = applicationContext
                        oemConfig.visaClientAppId = "VisaClientAppID";
                    }
                    OEMPayType.HUAWEI_PAY -> {
                        val callbackUrl = "tpcsdk://com.thalesgroup.tpc.demo/tokenRequestorsPage"
                        oemConfig.callbackUrl = callbackUrl
                        oemConfig.activity = activity
                    }
                    OEMPayType.GOOGLE_PAY -> {
                        //Desde Push Provisioning SDK V1.9.0, la aplicación puede establecer `Context` en lugar de `Activity` durante la configuración de Push Provisioning SDK para Google Pay
                        oemConfig.context = applicationContext
                    }
                }
                configSdk(oemPayType, oemConfig).collect{
                    println(it)
                }
            }
        }
    }

    private fun configSdkForScheme(configs: Config): Flow<TPCResult<Boolean>> = callbackFlow {
        // Desde Push Provisioning SDK V2.0.0, para el push provisioning de esquema, no establezcas OEMPayType
        val callBack = object : TPCSDKListener<Boolean?> {
            override fun onStart() {}

            override fun onSuccess(result: TPCResult<Boolean?>) {
                Log.d("CONFIG_SDK", "Configuración de esquema exitosa...")
                channel.close()
            }

            override fun onError(exception: TPCSDKException) {
                Log.e("CONFIG_SDK", "La configuración de esquema falló con el error: " + exception.message)
                channel.close()
            }
        }
        TPCManager.getInstance().config(configs, callBack)
    }

    private fun configSdk(oemPayType: OEMPayType, configs: Config): Flow<TPCResult<Boolean>> =  callbackFlow {
        configs.oemPayType = oemPayType;
        val callBack = object : TPCSDKListener<Boolean?> {
            override fun onStart() {}
            override fun onSuccess(result: TPCResult<Boolean?>) {
                Log.d("CONFIG_SDK", "Configuración exitosa..." + oemPayType.oemType)
                channel.close()
            }

            override fun onError(exception: TPCSDKException) {
                Log.e("CONFIG_SDK", "La configuración falló con el error: " + exception.message)
                channel.close()

            }
        }
        TPCManager.getInstance().config(configs, callBack)
        
    }
}
```

{% endtab %}
{% endtabs %}

#### Configuración de Samsung Pay <a href="#samsung-pay-configurations" id="samsung-pay-configurations"></a>

A partir de Android R (SDK de destino 30), debes declarar `<queries>` en el archivo de manifiesto de Android.

```xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools" 
  package="xxx.xxx.xxx.xxx">
  
  <application>
    <!-- para Samsung Pay -->
    <meta-data
      android:name="debug_mode"
      android:value="${DEBUG_MODE}" />
    <!-- para Samsung Pay -->
    <meta-data
      android:name="spay_sdk_api_level"
      android:value="${SPAY_API_LEVEL}" />
  </application>
  
  <queries>
    <package android:name="com.samsung.android.spay" />
    <package android:name="com.samsung.android.samsungpay.gear" />
  </queries>
```

### Ofuscación <a href="#obfuscation" id="obfuscation"></a>

Si tu aplicación tiene problemas de ProGuard con Samsung Pay, usa las siguientes reglas:

<pre><code># Samsung Pay
-keep class com.samsung.android.sdk.** { *; }
<strong>-keep interface com.samsung.android.sdk.** { *; }
</strong></code></pre>

A continuación se muestran las reglas de ofuscación recomendadas por Google:

{% code overflow="wrap" %}

```
# Google Pay
# Conservar las clases e interfaces del cliente del SDK TapAndPay
-keep class com.google.android.gms.tapandpay.** { *; }

# Evitar la eliminación o el cambio de nombre de las clases SafeParcelable y sus campos CREATOR
-keep class * implements com.google.android.gms.common.internal.safeparcelable.SafeParcelable {
    public static final android.os.Parcelable$Creator *;
}

# Conservar los campos creador Parcelable estándar
-keepclassmembers class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator CREATOR;
}

```

{% endcode %}


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.payments.thalescloud.io/classic-push-provisioning/es/guia-para-desarrolladores/configuracion-del-sdk/android.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
